Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxws/src/share/jaf_classes/javax/activation/DataHandler.java
38877 views
1
/*
2
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.activation;
27
28
import java.io.InputStream;
29
import java.io.IOException;
30
import java.io.OutputStream;
31
import java.io.PipedInputStream;
32
import java.io.PipedOutputStream;
33
import java.io.OutputStreamWriter;
34
import java.net.URL;
35
import java.awt.datatransfer.Transferable;
36
import java.awt.datatransfer.DataFlavor;
37
import java.awt.datatransfer.UnsupportedFlavorException;
38
39
/**
40
* The DataHandler class provides a consistent interface to data
41
* available in many different sources and formats.
42
* It manages simple stream to string conversions and related operations
43
* using DataContentHandlers.
44
* It provides access to commands that can operate on the data.
45
* The commands are found using a CommandMap. <p>
46
*
47
* <b>DataHandler and the Transferable Interface</b><p>
48
* DataHandler implements the Transferable interface so that data can
49
* be used in AWT data transfer operations, such as cut and paste and
50
* drag and drop. The implementation of the Transferable interface
51
* relies on the availability of an installed DataContentHandler
52
* object corresponding to the MIME type of the data represented in
53
* the specific instance of the DataHandler.<p>
54
*
55
* <b>DataHandler and CommandMaps</b><p>
56
* The DataHandler keeps track of the current CommandMap that it uses to
57
* service requests for commands (<code>getCommand</code>,
58
* <code>getAllCommands</code>, <code>getPreferredCommands</code>).
59
* Each instance of a DataHandler may have a CommandMap associated with
60
* it using the <code>setCommandMap</code> method. If a CommandMap was
61
* not set, DataHandler calls the <code>getDefaultCommandMap</code>
62
* method in CommandMap and uses the value it returns. See
63
* <i>CommandMap</i> for more information. <p>
64
*
65
* <b>DataHandler and URLs</b><p>
66
* The current DataHandler implementation creates a private
67
* instance of URLDataSource when it is constructed with a URL.
68
*
69
* @see javax.activation.CommandMap
70
* @see javax.activation.DataContentHandler
71
* @see javax.activation.DataSource
72
* @see javax.activation.URLDataSource
73
*
74
* @since 1.6
75
*/
76
77
public class DataHandler implements Transferable {
78
79
// Use the datasource to indicate whether we were started via the
80
// DataSource constructor or the object constructor.
81
private DataSource dataSource = null;
82
private DataSource objDataSource = null;
83
84
// The Object and mimetype from the constructor (if passed in).
85
// object remains null if it was instantiated with a
86
// DataSource.
87
private Object object = null;
88
private String objectMimeType = null;
89
90
// Keep track of the CommandMap
91
private CommandMap currentCommandMap = null;
92
93
// our transfer flavors
94
private static final DataFlavor emptyFlavors[] = new DataFlavor[0];
95
private DataFlavor transferFlavors[] = emptyFlavors;
96
97
// our DataContentHandler
98
private DataContentHandler dataContentHandler = null;
99
private DataContentHandler factoryDCH = null;
100
101
// our DataContentHandlerFactory
102
private static DataContentHandlerFactory factory = null;
103
private DataContentHandlerFactory oldFactory = null;
104
// the short representation of the ContentType (sans params)
105
private String shortType = null;
106
107
/**
108
* Create a <code>DataHandler</code> instance referencing the
109
* specified DataSource. The data exists in a byte stream form.
110
* The DataSource will provide an InputStream to access the data.
111
*
112
* @param ds the DataSource
113
*/
114
public DataHandler(DataSource ds) {
115
// save a reference to the incoming DS
116
dataSource = ds;
117
oldFactory = factory; // keep track of the factory
118
}
119
120
/**
121
* Create a <code>DataHandler</code> instance representing an object
122
* of this MIME type. This constructor is
123
* used when the application already has an in-memory representation
124
* of the data in the form of a Java Object.
125
*
126
* @param obj the Java Object
127
* @param mimeType the MIME type of the object
128
*/
129
public DataHandler(Object obj, String mimeType) {
130
object = obj;
131
objectMimeType = mimeType;
132
oldFactory = factory; // keep track of the factory
133
}
134
135
/**
136
* Create a <code>DataHandler</code> instance referencing a URL.
137
* The DataHandler internally creates a <code>URLDataSource</code>
138
* instance to represent the URL.
139
*
140
* @param url a URL object
141
*/
142
public DataHandler(URL url) {
143
dataSource = new URLDataSource(url);
144
oldFactory = factory; // keep track of the factory
145
}
146
147
/**
148
* Return the CommandMap for this instance of DataHandler.
149
*/
150
private synchronized CommandMap getCommandMap() {
151
if (currentCommandMap != null)
152
return currentCommandMap;
153
else
154
return CommandMap.getDefaultCommandMap();
155
}
156
157
/**
158
* Return the DataSource associated with this instance
159
* of DataHandler.
160
* <p>
161
* For DataHandlers that have been instantiated with a DataSource,
162
* this method returns the DataSource that was used to create the
163
* DataHandler object. In other cases the DataHandler
164
* constructs a DataSource from the data used to construct
165
* the DataHandler. DataSources created for DataHandlers <b>not</b>
166
* instantiated with a DataSource are cached for performance
167
* reasons.
168
*
169
* @return a valid DataSource object for this DataHandler
170
*/
171
public DataSource getDataSource() {
172
if (dataSource == null) {
173
// create one on the fly
174
if (objDataSource == null)
175
objDataSource = new DataHandlerDataSource(this);
176
return objDataSource;
177
}
178
return dataSource;
179
}
180
181
/**
182
* Return the name of the data object. If this DataHandler
183
* was created with a DataSource, this method calls through
184
* to the <code>DataSource.getName</code> method, otherwise it
185
* returns <i>null</i>.
186
*
187
* @return the name of the object
188
*/
189
public String getName() {
190
if (dataSource != null)
191
return dataSource.getName();
192
else
193
return null;
194
}
195
196
/**
197
* Return the MIME type of this object as retrieved from
198
* the source object. Note that this is the <i>full</i>
199
* type with parameters.
200
*
201
* @return the MIME type
202
*/
203
public String getContentType() {
204
if (dataSource != null) // data source case
205
return dataSource.getContentType();
206
else
207
return objectMimeType; // obj/type case
208
}
209
210
/**
211
* Get the InputStream for this object. <p>
212
*
213
* For DataHandlers instantiated with a DataSource, the DataHandler
214
* calls the <code>DataSource.getInputStream</code> method and
215
* returns the result to the caller.
216
* <p>
217
* For DataHandlers instantiated with an Object, the DataHandler
218
* first attempts to find a DataContentHandler for the Object. If
219
* the DataHandler can not find a DataContentHandler for this MIME
220
* type, it throws an UnsupportedDataTypeException. If it is
221
* successful, it creates a pipe and a thread. The thread uses the
222
* DataContentHandler's <code>writeTo</code> method to write the
223
* stream data into one end of the pipe. The other end of the pipe
224
* is returned to the caller. Because a thread is created to copy
225
* the data, IOExceptions that may occur during the copy can not be
226
* propagated back to the caller. The result is an empty stream.<p>
227
*
228
* @return the InputStream representing this data
229
* @exception IOException if an I/O error occurs
230
*
231
* @see javax.activation.DataContentHandler#writeTo
232
* @see javax.activation.UnsupportedDataTypeException
233
*/
234
public InputStream getInputStream() throws IOException {
235
InputStream ins = null;
236
237
if (dataSource != null) {
238
ins = dataSource.getInputStream();
239
} else {
240
DataContentHandler dch = getDataContentHandler();
241
// we won't even try if we can't get a dch
242
if (dch == null)
243
throw new UnsupportedDataTypeException(
244
"no DCH for MIME type " + getBaseType());
245
246
if (dch instanceof ObjectDataContentHandler) {
247
if (((ObjectDataContentHandler)dch).getDCH() == null)
248
throw new UnsupportedDataTypeException(
249
"no object DCH for MIME type " + getBaseType());
250
}
251
// there is none but the default^^^^^^^^^^^^^^^^
252
final DataContentHandler fdch = dch;
253
254
// from bill s.
255
// ce n'est pas une pipe!
256
//
257
// NOTE: This block of code needs to throw exceptions, but
258
// can't because it is in another thread!!! ARG!
259
//
260
final PipedOutputStream pos = new PipedOutputStream();
261
PipedInputStream pin = new PipedInputStream(pos);
262
new Thread(
263
new Runnable() {
264
public void run() {
265
try {
266
fdch.writeTo(object, objectMimeType, pos);
267
} catch (IOException e) {
268
269
} finally {
270
try {
271
pos.close();
272
} catch (IOException ie) { }
273
}
274
}
275
},
276
"DataHandler.getInputStream").start();
277
ins = pin;
278
}
279
280
return ins;
281
}
282
283
/**
284
* Write the data to an <code>OutputStream</code>.<p>
285
*
286
* If the DataHandler was created with a DataSource, writeTo
287
* retrieves the InputStream and copies the bytes from the
288
* InputStream to the OutputStream passed in.
289
* <p>
290
* If the DataHandler was created with an object, writeTo
291
* retrieves the DataContentHandler for the object's type.
292
* If the DataContentHandler was found, it calls the
293
* <code>writeTo</code> method on the <code>DataContentHandler</code>.
294
*
295
* @param os the OutputStream to write to
296
* @exception IOException if an I/O error occurs
297
*/
298
public void writeTo(OutputStream os) throws IOException {
299
// for the DataSource case
300
if (dataSource != null) {
301
InputStream is = null;
302
byte data[] = new byte[8*1024];
303
int bytes_read;
304
305
is = dataSource.getInputStream();
306
307
try {
308
while ((bytes_read = is.read(data)) > 0) {
309
os.write(data, 0, bytes_read);
310
}
311
} finally {
312
is.close();
313
is = null;
314
}
315
} else { // for the Object case
316
DataContentHandler dch = getDataContentHandler();
317
dch.writeTo(object, objectMimeType, os);
318
}
319
}
320
321
/**
322
* Get an OutputStream for this DataHandler to allow overwriting
323
* the underlying data.
324
* If the DataHandler was created with a DataSource, the
325
* DataSource's <code>getOutputStream</code> method is called.
326
* Otherwise, <code>null</code> is returned.
327
*
328
* @return the OutputStream
329
*
330
* @see javax.activation.DataSource#getOutputStream
331
* @see javax.activation.URLDataSource
332
*/
333
public OutputStream getOutputStream() throws IOException {
334
if (dataSource != null)
335
return dataSource.getOutputStream();
336
else
337
return null;
338
}
339
340
/**
341
* Return the DataFlavors in which this data is available. <p>
342
*
343
* Returns an array of DataFlavor objects indicating the flavors
344
* the data can be provided in. The array is usually ordered
345
* according to preference for providing the data, from most
346
* richly descriptive to least richly descriptive.<p>
347
*
348
* The DataHandler attempts to find a DataContentHandler that
349
* corresponds to the MIME type of the data. If one is located,
350
* the DataHandler calls the DataContentHandler's
351
* <code>getTransferDataFlavors</code> method. <p>
352
*
353
* If a DataContentHandler can <i>not</i> be located, and if the
354
* DataHandler was created with a DataSource (or URL), one
355
* DataFlavor is returned that represents this object's MIME type
356
* and the <code>java.io.InputStream</code> class. If the
357
* DataHandler was created with an object and a MIME type,
358
* getTransferDataFlavors returns one DataFlavor that represents
359
* this object's MIME type and the object's class.
360
*
361
* @return an array of data flavors in which this data can be transferred
362
* @see javax.activation.DataContentHandler#getTransferDataFlavors
363
*/
364
public synchronized DataFlavor[] getTransferDataFlavors() {
365
if (factory != oldFactory) // if the factory has changed, clear cache
366
transferFlavors = emptyFlavors;
367
368
// if it's not set, set it...
369
if (transferFlavors == emptyFlavors)
370
transferFlavors = getDataContentHandler().getTransferDataFlavors();
371
372
if (transferFlavors == emptyFlavors)
373
return transferFlavors;
374
else
375
return transferFlavors.clone();
376
377
}
378
379
/**
380
* Returns whether the specified data flavor is supported
381
* for this object.<p>
382
*
383
* This method iterates through the DataFlavors returned from
384
* <code>getTransferDataFlavors</code>, comparing each with
385
* the specified flavor.
386
*
387
* @param flavor the requested flavor for the data
388
* @return true if the data flavor is supported
389
* @see javax.activation.DataHandler#getTransferDataFlavors
390
*/
391
public boolean isDataFlavorSupported(DataFlavor flavor) {
392
DataFlavor[] lFlavors = getTransferDataFlavors();
393
394
for (int i = 0; i < lFlavors.length; i++) {
395
if (lFlavors[i].equals(flavor))
396
return true;
397
}
398
return false;
399
}
400
401
/**
402
* Returns an object that represents the data to be
403
* transferred. The class of the object returned is defined by the
404
* representation class of the data flavor.<p>
405
*
406
* <b>For DataHandler's created with DataSources or URLs:</b><p>
407
*
408
* The DataHandler attempts to locate a DataContentHandler
409
* for this MIME type. If one is found, the passed in DataFlavor
410
* and the type of the data are passed to its <code>getTransferData</code>
411
* method. If the DataHandler fails to locate a DataContentHandler
412
* and the flavor specifies this object's MIME type and the
413
* <code>java.io.InputStream</code> class, this object's InputStream
414
* is returned.
415
* Otherwise it throws an UnsupportedFlavorException. <p>
416
*
417
* <b>For DataHandler's created with Objects:</b><p>
418
*
419
* The DataHandler attempts to locate a DataContentHandler
420
* for this MIME type. If one is found, the passed in DataFlavor
421
* and the type of the data are passed to its getTransferData
422
* method. If the DataHandler fails to locate a DataContentHandler
423
* and the flavor specifies this object's MIME type and its class,
424
* this DataHandler's referenced object is returned.
425
* Otherwise it throws an UnsupportedFlavorException.
426
*
427
* @param flavor the requested flavor for the data
428
* @return the object
429
* @exception UnsupportedFlavorException if the data could not be
430
* converted to the requested flavor
431
* @exception IOException if an I/O error occurs
432
* @see javax.activation.ActivationDataFlavor
433
*/
434
public Object getTransferData(DataFlavor flavor)
435
throws UnsupportedFlavorException, IOException {
436
return getDataContentHandler().getTransferData(flavor, dataSource);
437
}
438
439
/**
440
* Set the CommandMap for use by this DataHandler.
441
* Setting it to <code>null</code> causes the CommandMap to revert
442
* to the CommandMap returned by the
443
* <code>CommandMap.getDefaultCommandMap</code> method.
444
* Changing the CommandMap, or setting it to <code>null</code>,
445
* clears out any data cached from the previous CommandMap.
446
*
447
* @param commandMap the CommandMap to use in this DataHandler
448
*
449
* @see javax.activation.CommandMap#setDefaultCommandMap
450
*/
451
public synchronized void setCommandMap(CommandMap commandMap) {
452
if (commandMap != currentCommandMap || commandMap == null) {
453
// clear cached values...
454
transferFlavors = emptyFlavors;
455
dataContentHandler = null;
456
457
currentCommandMap = commandMap;
458
}
459
}
460
461
/**
462
* Return the <i>preferred</i> commands for this type of data.
463
* This method calls the <code>getPreferredCommands</code> method
464
* in the CommandMap associated with this instance of DataHandler.
465
* This method returns an array that represents a subset of
466
* available commands. In cases where multiple commands for the
467
* MIME type represented by this DataHandler are present, the
468
* installed CommandMap chooses the appropriate commands.
469
*
470
* @return the CommandInfo objects representing the preferred commands
471
*
472
* @see javax.activation.CommandMap#getPreferredCommands
473
*/
474
public CommandInfo[] getPreferredCommands() {
475
if (dataSource != null)
476
return getCommandMap().getPreferredCommands(getBaseType(),
477
dataSource);
478
else
479
return getCommandMap().getPreferredCommands(getBaseType());
480
}
481
482
/**
483
* Return all the commands for this type of data.
484
* This method returns an array containing all commands
485
* for the type of data represented by this DataHandler. The
486
* MIME type for the underlying data represented by this DataHandler
487
* is used to call through to the <code>getAllCommands</code> method
488
* of the CommandMap associated with this DataHandler.
489
*
490
* @return the CommandInfo objects representing all the commands
491
*
492
* @see javax.activation.CommandMap#getAllCommands
493
*/
494
public CommandInfo[] getAllCommands() {
495
if (dataSource != null)
496
return getCommandMap().getAllCommands(getBaseType(), dataSource);
497
else
498
return getCommandMap().getAllCommands(getBaseType());
499
}
500
501
/**
502
* Get the command <i>cmdName</i>. Use the search semantics as
503
* defined by the CommandMap installed in this DataHandler. The
504
* MIME type for the underlying data represented by this DataHandler
505
* is used to call through to the <code>getCommand</code> method
506
* of the CommandMap associated with this DataHandler.
507
*
508
* @param cmdName the command name
509
* @return the CommandInfo corresponding to the command
510
*
511
* @see javax.activation.CommandMap#getCommand
512
*/
513
public CommandInfo getCommand(String cmdName) {
514
if (dataSource != null)
515
return getCommandMap().getCommand(getBaseType(), cmdName,
516
dataSource);
517
else
518
return getCommandMap().getCommand(getBaseType(), cmdName);
519
}
520
521
/**
522
* Return the data in its preferred Object form. <p>
523
*
524
* If the DataHandler was instantiated with an object, return
525
* the object. <p>
526
*
527
* If the DataHandler was instantiated with a DataSource,
528
* this method uses a DataContentHandler to return the content
529
* object for the data represented by this DataHandler. If no
530
* <code>DataContentHandler</code> can be found for the
531
* the type of this data, the DataHandler returns an
532
* InputStream for the data.
533
*
534
* @return the content.
535
* @exception IOException if an IOException occurs during
536
* this operation.
537
*/
538
public Object getContent() throws IOException {
539
if (object != null)
540
return object;
541
else
542
return getDataContentHandler().getContent(getDataSource());
543
}
544
545
/**
546
* A convenience method that takes a CommandInfo object
547
* and instantiates the corresponding command, usually
548
* a JavaBean component.
549
* <p>
550
* This method calls the CommandInfo's <code>getCommandObject</code>
551
* method with the <code>ClassLoader</code> used to load
552
* the <code>javax.activation.DataHandler</code> class itself.
553
*
554
* @param cmdinfo the CommandInfo corresponding to a command
555
* @return the instantiated command object
556
*/
557
public Object getBean(CommandInfo cmdinfo) {
558
Object bean = null;
559
560
try {
561
// make the bean
562
ClassLoader cld = null;
563
// First try the "application's" class loader.
564
cld = SecuritySupport.getContextClassLoader();
565
if (cld == null)
566
cld = this.getClass().getClassLoader();
567
bean = cmdinfo.getCommandObject(this, cld);
568
} catch (IOException e) {
569
} catch (ClassNotFoundException e) { }
570
571
return bean;
572
}
573
574
/**
575
* Get the DataContentHandler for this DataHandler: <p>
576
*
577
* If a DataContentHandlerFactory is set, use it.
578
* Otherwise look for an object to serve DCH in the
579
* following order: <p>
580
*
581
* 1) if a factory is set, use it <p>
582
* 2) if a CommandMap is set, use it <p>
583
* 3) use the default CommandMap <p>
584
*
585
* In any case, wrap the real DataContentHandler with one of our own
586
* to handle any missing cases, fill in defaults, and to ensure that
587
* we always have a non-null DataContentHandler.
588
*
589
* @return the requested DataContentHandler
590
*/
591
private synchronized DataContentHandler getDataContentHandler() {
592
593
// make sure the factory didn't change
594
if (factory != oldFactory) {
595
oldFactory = factory;
596
factoryDCH = null;
597
dataContentHandler = null;
598
transferFlavors = emptyFlavors;
599
}
600
601
if (dataContentHandler != null)
602
return dataContentHandler;
603
604
String simpleMT = getBaseType();
605
606
if (factoryDCH == null && factory != null)
607
factoryDCH = factory.createDataContentHandler(simpleMT);
608
609
if (factoryDCH != null)
610
dataContentHandler = factoryDCH;
611
612
if (dataContentHandler == null) {
613
if (dataSource != null)
614
dataContentHandler = getCommandMap().
615
createDataContentHandler(simpleMT, dataSource);
616
else
617
dataContentHandler = getCommandMap().
618
createDataContentHandler(simpleMT);
619
}
620
621
// getDataContentHandler always uses these 'wrapper' handlers
622
// to make sure it returns SOMETHING meaningful...
623
if (dataSource != null)
624
dataContentHandler = new DataSourceDataContentHandler(
625
dataContentHandler,
626
dataSource);
627
else
628
dataContentHandler = new ObjectDataContentHandler(
629
dataContentHandler,
630
object,
631
objectMimeType);
632
return dataContentHandler;
633
}
634
635
/**
636
* Use the MimeType class to extract the MIME type/subtype,
637
* ignoring the parameters. The type is cached.
638
*/
639
private synchronized String getBaseType() {
640
if (shortType == null) {
641
String ct = getContentType();
642
try {
643
MimeType mt = new MimeType(ct);
644
shortType = mt.getBaseType();
645
} catch (MimeTypeParseException e) {
646
shortType = ct;
647
}
648
}
649
return shortType;
650
}
651
652
/**
653
* Sets the DataContentHandlerFactory. The DataContentHandlerFactory
654
* is called first to find DataContentHandlers.
655
* The DataContentHandlerFactory can only be set once.
656
* <p>
657
* If the DataContentHandlerFactory has already been set,
658
* this method throws an Error.
659
*
660
* @param newFactory the DataContentHandlerFactory
661
* @exception Error if the factory has already been defined.
662
*
663
* @see javax.activation.DataContentHandlerFactory
664
*/
665
public static synchronized void setDataContentHandlerFactory(
666
DataContentHandlerFactory newFactory) {
667
if (factory != null)
668
throw new Error("DataContentHandlerFactory already defined");
669
670
SecurityManager security = System.getSecurityManager();
671
if (security != null) {
672
try {
673
// if it's ok with the SecurityManager, it's ok with me...
674
security.checkSetFactory();
675
} catch (SecurityException ex) {
676
// otherwise, we also allow it if this code and the
677
// factory come from the same class loader (e.g.,
678
// the JAF classes were loaded with the applet classes).
679
if (DataHandler.class.getClassLoader() !=
680
newFactory.getClass().getClassLoader())
681
throw ex;
682
}
683
}
684
factory = newFactory;
685
}
686
}
687
688
/**
689
* The DataHanderDataSource class implements the
690
* DataSource interface when the DataHandler is constructed
691
* with an Object and a mimeType string.
692
*/
693
class DataHandlerDataSource implements DataSource {
694
DataHandler dataHandler = null;
695
696
/**
697
* The constructor.
698
*/
699
public DataHandlerDataSource(DataHandler dh) {
700
this.dataHandler = dh;
701
}
702
703
/**
704
* Returns an <code>InputStream</code> representing this object.
705
* @return the <code>InputStream</code>
706
*/
707
public InputStream getInputStream() throws IOException {
708
return dataHandler.getInputStream();
709
}
710
711
/**
712
* Returns the <code>OutputStream</code> for this object.
713
* @return the <code>OutputStream</code>
714
*/
715
public OutputStream getOutputStream() throws IOException {
716
return dataHandler.getOutputStream();
717
}
718
719
/**
720
* Returns the MIME type of the data represented by this object.
721
* @return the MIME type
722
*/
723
public String getContentType() {
724
return dataHandler.getContentType();
725
}
726
727
/**
728
* Returns the name of this object.
729
* @return the name of this object
730
*/
731
public String getName() {
732
return dataHandler.getName(); // what else would it be?
733
}
734
}
735
736
/*
737
* DataSourceDataContentHandler
738
*
739
* This is a <i>private</i> DataContentHandler that wraps the real
740
* DataContentHandler in the case where the DataHandler was instantiated
741
* with a DataSource.
742
*/
743
class DataSourceDataContentHandler implements DataContentHandler {
744
private DataSource ds = null;
745
private DataFlavor transferFlavors[] = null;
746
private DataContentHandler dch = null;
747
748
/**
749
* The constructor.
750
*/
751
public DataSourceDataContentHandler(DataContentHandler dch, DataSource ds) {
752
this.ds = ds;
753
this.dch = dch;
754
}
755
756
/**
757
* Return the DataFlavors for this <code>DataContentHandler</code>.
758
* @return the DataFlavors
759
*/
760
public DataFlavor[] getTransferDataFlavors() {
761
762
if (transferFlavors == null) {
763
if (dch != null) { // is there a dch?
764
transferFlavors = dch.getTransferDataFlavors();
765
} else {
766
transferFlavors = new DataFlavor[1];
767
transferFlavors[0] =
768
new ActivationDataFlavor(ds.getContentType(),
769
ds.getContentType());
770
}
771
}
772
return transferFlavors;
773
}
774
775
/**
776
* Return the Transfer Data of type DataFlavor from InputStream.
777
* @param df the DataFlavor
778
* @param ds the DataSource
779
* @return the constructed Object
780
*/
781
public Object getTransferData(DataFlavor df, DataSource ds) throws
782
UnsupportedFlavorException, IOException {
783
784
if (dch != null)
785
return dch.getTransferData(df, ds);
786
else if (df.equals(getTransferDataFlavors()[0])) // only have one now
787
return ds.getInputStream();
788
else
789
throw new UnsupportedFlavorException(df);
790
}
791
792
public Object getContent(DataSource ds) throws IOException {
793
794
if (dch != null)
795
return dch.getContent(ds);
796
else
797
return ds.getInputStream();
798
}
799
800
/**
801
* Write the object to the output stream.
802
*/
803
public void writeTo(Object obj, String mimeType, OutputStream os)
804
throws IOException {
805
if (dch != null)
806
dch.writeTo(obj, mimeType, os);
807
else
808
throw new UnsupportedDataTypeException(
809
"no DCH for content type " + ds.getContentType());
810
}
811
}
812
813
/*
814
* ObjectDataContentHandler
815
*
816
* This is a <i>private</i> DataContentHandler that wraps the real
817
* DataContentHandler in the case where the DataHandler was instantiated
818
* with an object.
819
*/
820
class ObjectDataContentHandler implements DataContentHandler {
821
private DataFlavor transferFlavors[] = null;
822
private Object obj;
823
private String mimeType;
824
private DataContentHandler dch = null;
825
826
/**
827
* The constructor.
828
*/
829
public ObjectDataContentHandler(DataContentHandler dch,
830
Object obj, String mimeType) {
831
this.obj = obj;
832
this.mimeType = mimeType;
833
this.dch = dch;
834
}
835
836
/**
837
* Return the DataContentHandler for this object.
838
* Used only by the DataHandler class.
839
*/
840
public DataContentHandler getDCH() {
841
return dch;
842
}
843
844
/**
845
* Return the DataFlavors for this <code>DataContentHandler</code>.
846
* @return the DataFlavors
847
*/
848
public synchronized DataFlavor[] getTransferDataFlavors() {
849
if (transferFlavors == null) {
850
if (dch != null) {
851
transferFlavors = dch.getTransferDataFlavors();
852
} else {
853
transferFlavors = new DataFlavor[1];
854
transferFlavors[0] = new ActivationDataFlavor(obj.getClass(),
855
mimeType, mimeType);
856
}
857
}
858
return transferFlavors;
859
}
860
861
/**
862
* Return the Transfer Data of type DataFlavor from InputStream.
863
* @param df the DataFlavor
864
* @param ds the DataSource
865
* @return the constructed Object
866
*/
867
public Object getTransferData(DataFlavor df, DataSource ds)
868
throws UnsupportedFlavorException, IOException {
869
870
if (dch != null)
871
return dch.getTransferData(df, ds);
872
else if (df.equals(getTransferDataFlavors()[0])) // only have one now
873
return obj;
874
else
875
throw new UnsupportedFlavorException(df);
876
877
}
878
879
public Object getContent(DataSource ds) {
880
return obj;
881
}
882
883
/**
884
* Write the object to the output stream.
885
*/
886
public void writeTo(Object obj, String mimeType, OutputStream os)
887
throws IOException {
888
if (dch != null)
889
dch.writeTo(obj, mimeType, os);
890
else if (obj instanceof byte[])
891
os.write((byte[])obj);
892
else if (obj instanceof String) {
893
OutputStreamWriter osw = new OutputStreamWriter(os);
894
osw.write((String)obj);
895
osw.flush();
896
} else throw new UnsupportedDataTypeException(
897
"no object DCH for MIME type " + this.mimeType);
898
}
899
}
900
901