KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > activation > DataHandler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)DataHandler.java 1.39 05/11/16
24  *
25  * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package javax.activation;
29
30 import java.io.InputStream JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.io.PipedInputStream JavaDoc;
34 import java.io.PipedOutputStream JavaDoc;
35 import java.net.URL JavaDoc;
36 import java.awt.datatransfer.Transferable JavaDoc;
37 import java.awt.datatransfer.DataFlavor JavaDoc;
38 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
39
40 /**
41  * The DataHandler class provides a consistent interface to data
42  * available in many different sources and formats.
43  * It manages simple stream to string conversions and related operations
44  * using DataContentHandlers.
45  * It provides access to commands that can operate on the data.
46  * The commands are found using a CommandMap. <p>
47  *
48  * <b>DataHandler and the Transferable Interface</b><p>
49  * DataHandler implements the Transferable interface so that data can
50  * be used in AWT data transfer operations, such as cut and paste and
51  * drag and drop. The implementation of the Transferable interface
52  * relies on the availability of an installed DataContentHandler
53  * object corresponding to the MIME type of the data represented in
54  * the specific instance of the DataHandler.<p>
55  *
56  * <b>DataHandler and CommandMaps</b><p>
57  * The DataHandler keeps track of the current CommandMap that it uses to
58  * service requests for commands (<code>getCommand</code>,
59  * <code>getAllCommands</code>, <code>getPreferredCommands</code>).
60  * Each instance of a DataHandler may have a CommandMap associated with
61  * it using the <code>setCommandMap</code> method. If a CommandMap was
62  * not set, DataHandler calls the <code>getDefaultCommandMap</code>
63  * method in CommandMap and uses the value it returns. See
64  * <i>CommandMap</i> for more information. <p>
65  *
66  * <b>DataHandler and URLs</b><p>
67  * The current DataHandler implementation creates a private
68  * instance of URLDataSource when it is constructed with a URL.
69  *
70  * @see javax.activation.CommandMap
71  * @see javax.activation.DataContentHandler
72  * @see javax.activation.DataSource
73  * @see javax.activation.URLDataSource
74  */

75
76 public class DataHandler implements Transferable JavaDoc {
77
78     // Use the datasource to indicate whether we were started via the
79
// DataSource constructor or the object constructor.
80
private DataSource JavaDoc dataSource = null;
81     private DataSource JavaDoc objDataSource = null;
82
83     // The Object and mimetype from the constructor (if passed in).
84
// object remains null if it was instantiated with a
85
// DataSource.
86
private Object JavaDoc object = null;
87     private String JavaDoc objectMimeType = null;
88
89     // Keep track of the CommandMap
90
private CommandMap JavaDoc currentCommandMap = null;
91
92     // our transfer flavors
93
private static final DataFlavor JavaDoc emptyFlavors[] = new DataFlavor JavaDoc[0];
94     private DataFlavor JavaDoc transferFlavors[] = emptyFlavors;
95
96     // our DataContentHandler
97
private DataContentHandler JavaDoc dataContentHandler = null;
98     private DataContentHandler JavaDoc factoryDCH = null;
99
100     // our DataContentHandlerFactory
101
private static DataContentHandlerFactory JavaDoc factory = null;
102     private DataContentHandlerFactory JavaDoc oldFactory = null;
103     // the short representation of the ContentType (sans params)
104
private String JavaDoc shortType = null;
105
106     /**
107      * Create a <code>DataHandler</code> instance referencing the
108      * specified DataSource. The data exists in a byte stream form.
109      * The DataSource will provide an InputStream to access the data.
110      *
111      * @param ds the DataSource
112      */

113     public DataHandler(DataSource JavaDoc ds) {
114     // save a reference to the incoming DS
115
dataSource = ds;
116     oldFactory = factory; // keep track of the factory
117
}
118
119     /**
120      * Create a <code>DataHandler</code> instance representing an object
121      * of this MIME type. This constructor is
122      * used when the application already has an in-memory representation
123      * of the data in the form of a Java Object.
124      *
125      * @param obj the Java Object
126      * @param mimeType the MIME type of the object
127      */

128     public DataHandler(Object JavaDoc obj, String JavaDoc mimeType) {
129     object = obj;
130     objectMimeType = mimeType;
131     oldFactory = factory; // keep track of the factory
132
}
133
134     /**
135      * Create a <code>DataHandler</code> instance referencing a URL.
136      * The DataHandler internally creates a <code>URLDataSource</code>
137      * instance to represent the URL.
138      *
139      * @param url a URL object
140      */

141     public DataHandler(URL JavaDoc url) {
142     dataSource = new URLDataSource JavaDoc(url);
143     oldFactory = factory; // keep track of the factory
144
}
145
146     /**
147      * Return the CommandMap for this instance of DataHandler.
148      */

149     private synchronized CommandMap JavaDoc getCommandMap() {
150     if (currentCommandMap != null)
151         return currentCommandMap;
152     else
153         return CommandMap.getDefaultCommandMap();
154     }
155
156     /**
157      * Return the DataSource associated with this instance
158      * of DataHandler.
159      * <p>
160      * For DataHandlers that have been instantiated with a DataSource,
161      * this method returns the DataSource that was used to create the
162      * DataHandler object. In other cases the DataHandler
163      * constructs a DataSource from the data used to construct
164      * the DataHandler. DataSources created for DataHandlers <b>not</b>
165      * instantiated with a DataSource are cached for performance
166      * reasons.
167      *
168      * @return a valid DataSource object for this DataHandler
169      */

170     public DataSource JavaDoc getDataSource() {
171     if (dataSource == null) {
172         // create one on the fly
173
if (objDataSource == null)
174         objDataSource = new DataHandlerDataSource JavaDoc(this);
175         return objDataSource;
176     }
177     return dataSource;
178     }
179
180     /**
181      * Return the name of the data object. If this DataHandler
182      * was created with a DataSource, this method calls through
183      * to the <code>DataSource.getName</code> method, otherwise it
184      * returns <i>null</i>.
185      *
186      * @return the name of the object
187      */

188     public String JavaDoc getName() {
189     if (dataSource != null)
190         return dataSource.getName();
191     else
192         return null;
193     }
194
195     /**
196      * Return the MIME type of this object as retrieved from
197      * the source object. Note that this is the <i>full</i>
198      * type with parameters.
199      *
200      * @return the MIME type
201      */

202     public String JavaDoc getContentType() {
203     if (dataSource != null) // data source case
204
return dataSource.getContentType();
205     else
206         return objectMimeType; // obj/type case
207
}
208
209     /**
210      * Get the InputStream for this object. <p>
211      *
212      * For DataHandlers instantiated with a DataSource, the DataHandler
213      * calls the <code>DataSource.getInputStream</code> method and
214      * returns the result to the caller.
215      * <p>
216      * For DataHandlers instantiated with an Object, the DataHandler
217      * first attempts to find a DataContentHandler for the Object. If
218      * the DataHandler can not find a DataContentHandler for this MIME
219      * type, it throws an UnsupportedDataTypeException. If it is
220      * successful, it creates a pipe and a thread. The thread uses the
221      * DataContentHandler's <code>writeTo</code> method to write the
222      * stream data into one end of the pipe. The other end of the pipe
223      * is returned to the caller. Because a thread is created to copy
224      * the data, IOExceptions that may occur during the copy can not be
225      * propagated back to the caller. The result is an empty stream.<p>
226      *
227      * @return the InputStream representing this data
228      * @exception IOException if an I/O error occurs
229      *
230      * @see javax.activation.DataContentHandler#writeTo
231      * @see javax.activation.UnsupportedDataTypeException
232      */

233     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
234     InputStream JavaDoc ins = null;
235
236     if (dataSource != null) {
237         ins = dataSource.getInputStream();
238     } else {
239         DataContentHandler JavaDoc dch = getDataContentHandler();
240         // we won't even try if we can't get a dch
241
if (dch == null)
242         throw new UnsupportedDataTypeException JavaDoc(
243                 "no DCH for MIME type " + getBaseType());
244
245         if (dch instanceof ObjectDataContentHandler JavaDoc) {
246         if (((ObjectDataContentHandler JavaDoc)dch).getDCH() == null)
247             throw new UnsupportedDataTypeException JavaDoc(
248                 "no object DCH for MIME type " + getBaseType());
249         }
250         // there is none but the default^^^^^^^^^^^^^^^^
251
final DataContentHandler JavaDoc fdch = dch;
252
253         // from bill s.
254
// ce n'est pas une pipe!
255
//
256
// NOTE: This block of code needs to throw exceptions, but
257
// can't because it is in another thread!!! ARG!
258
//
259
final PipedOutputStream JavaDoc pos = new PipedOutputStream JavaDoc();
260         PipedInputStream JavaDoc pin = new PipedInputStream JavaDoc(pos);
261         new Thread JavaDoc(
262                new Runnable JavaDoc() {
263         public void run() {
264             try {
265             fdch.writeTo(object, objectMimeType, pos);
266             } catch (IOException JavaDoc e) {
267
268             } finally {
269             try {
270                 pos.close();
271             } catch (IOException JavaDoc ie) { }
272             }
273         }
274         },
275               "DataHandler.getInputStream").start();
276         ins = pin;
277     }
278
279     return ins;
280     }
281
282     /**
283      * Write the data to an <code>OutputStream</code>.<p>
284      *
285      * If the DataHandler was created with a DataSource, writeTo
286      * retrieves the InputStream and copies the bytes from the
287      * InputStream to the OutputStream passed in.
288      * <p>
289      * If the DataHandler was created with an object, writeTo
290      * retrieves the DataContentHandler for the object's type.
291      * If the DataContentHandler was found, it calls the
292      * <code>writeTo</code> method on the <code>DataContentHandler</code>.
293      *
294      * @param os the OutputStream to write to
295      * @exception IOException if an I/O error occurs
296      */

297     public void writeTo(OutputStream JavaDoc os) throws IOException JavaDoc {
298     // for the DataSource case
299
if (dataSource != null) {
300         InputStream JavaDoc is = null;
301         byte data[] = new byte[8*1024];
302         int bytes_read;
303
304         is = dataSource.getInputStream();
305
306         try {
307         while ((bytes_read = is.read(data)) > 0) {
308             os.write(data, 0, bytes_read);
309         }
310         } finally {
311         is.close();
312         is = null;
313         }
314     } else { // for the Object case
315
DataContentHandler JavaDoc dch = getDataContentHandler();
316         dch.writeTo(object, objectMimeType, os);
317     }
318     }
319
320     /**
321      * Get an OutputStream for this DataHandler to allow overwriting
322      * the underlying data.
323      * If the DataHandler was created with a DataSource, the
324      * DataSource's <code>getOutputStream</code> method is called.
325      * Otherwise, <code>null</code> is returned.
326      *
327      * @return the OutputStream
328      *
329      * @see javax.activation.DataSource#getOutputStream
330      * @see javax.activation.URLDataSource
331      */

332     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
333     if (dataSource != null)
334         return dataSource.getOutputStream();
335     else
336         return null;
337     }
338
339     /**
340      * Return the DataFlavors in which this data is available. <p>
341      *
342      * Returns an array of DataFlavor objects indicating the flavors
343      * the data can be provided in. The array is usually ordered
344      * according to preference for providing the data, from most
345      * richly descriptive to least richly descriptive.<p>
346      *
347      * The DataHandler attempts to find a DataContentHandler that
348      * corresponds to the MIME type of the data. If one is located,
349      * the DataHandler calls the DataContentHandler's
350      * <code>getTransferDataFlavors</code> method. <p>
351      *
352      * If a DataContentHandler can <i>not</i> be located, and if the
353      * DataHandler was created with a DataSource (or URL), one
354      * DataFlavor is returned that represents this object's MIME type
355      * and the <code>java.io.InputStream</code> class. If the
356      * DataHandler was created with an object and a MIME type,
357      * getTransferDataFlavors returns one DataFlavor that represents
358      * this object's MIME type and the object's class.
359      *
360      * @return an array of data flavors in which this data can be transferred
361      * @see javax.activation.DataContentHandler#getTransferDataFlavors
362      */

363     public synchronized DataFlavor JavaDoc[] getTransferDataFlavors() {
364     if (factory != oldFactory) // if the factory has changed, clear cache
365
transferFlavors = emptyFlavors;
366
367     // if it's not set, set it...
368
if (transferFlavors == emptyFlavors)
369         transferFlavors = getDataContentHandler().getTransferDataFlavors();
370     return transferFlavors;
371     }
372
373     /**
374      * Returns whether the specified data flavor is supported
375      * for this object.<p>
376      *
377      * This method iterates through the DataFlavors returned from
378      * <code>getTransferDataFlavors</code>, comparing each with
379      * the specified flavor.
380      *
381      * @param flavor the requested flavor for the data
382      * @return true if the data flavor is supported
383      * @see javax.activation.DataHandler#getTransferDataFlavors
384      */

385     public boolean isDataFlavorSupported(DataFlavor JavaDoc flavor) {
386     DataFlavor JavaDoc[] lFlavors = getTransferDataFlavors();
387
388     for (int i = 0; i < lFlavors.length; i++) {
389         if (lFlavors[i].equals(flavor))
390         return true;
391     }
392     return false;
393     }
394
395     /**
396      * Returns an object that represents the data to be
397      * transferred. The class of the object returned is defined by the
398      * representation class of the data flavor.<p>
399      *
400      * <b>For DataHandler's created with DataSources or URLs:</b><p>
401      *
402      * The DataHandler attempts to locate a DataContentHandler
403      * for this MIME type. If one is found, the passed in DataFlavor
404      * and the type of the data are passed to its <code>getTransferData</code>
405      * method. If the DataHandler fails to locate a DataContentHandler
406      * and the flavor specifies this object's MIME type and the
407      * <code>java.io.InputStream</code> class, this object's InputStream
408      * is returned.
409      * Otherwise it throws an UnsupportedFlavorException. <p>
410      *
411      * <b>For DataHandler's created with Objects:</b><p>
412      *
413      * The DataHandler attempts to locate a DataContentHandler
414      * for this MIME type. If one is found, the passed in DataFlavor
415      * and the type of the data are passed to its getTransferData
416      * method. If the DataHandler fails to locate a DataContentHandler
417      * and the flavor specifies this object's MIME type and its class,
418      * this DataHandler's referenced object is returned.
419      * Otherwise it throws an UnsupportedFlavorException.
420      *
421      * @param flavor the requested flavor for the data
422      * @return the object
423      * @exception UnsupportedFlavorException if the data could not be
424      * converted to the requested flavor
425      * @exception IOException if an I/O error occurs
426      * @see javax.activation.ActivationDataFlavor
427      */

428     public Object JavaDoc getTransferData(DataFlavor JavaDoc flavor)
429                 throws UnsupportedFlavorException JavaDoc, IOException JavaDoc {
430     return getDataContentHandler().getTransferData(flavor, dataSource);
431     }
432
433     /**
434      * Set the CommandMap for use by this DataHandler.
435      * Setting it to <code>null</code> causes the CommandMap to revert
436      * to the CommandMap returned by the
437      * <code>CommandMap.getDefaultCommandMap</code> method.
438      * Changing the CommandMap, or setting it to <code>null</code>,
439      * clears out any data cached from the previous CommandMap.
440      *
441      * @param commandMap the CommandMap to use in this DataHandler
442      *
443      * @see javax.activation.CommandMap#setDefaultCommandMap
444      */

445     public synchronized void setCommandMap(CommandMap JavaDoc commandMap) {
446     if (commandMap != currentCommandMap || commandMap == null) {
447         // clear cached values...
448
transferFlavors = emptyFlavors;
449         dataContentHandler = null;
450
451         currentCommandMap = commandMap;
452     }
453     }
454
455     /**
456      * Return the <i>preferred</i> commands for this type of data.
457      * This method calls the <code>getPreferredCommands</code> method
458      * in the CommandMap associated with this instance of DataHandler.
459      * This method returns an array that represents a subset of
460      * available commands. In cases where multiple commands for the
461      * MIME type represented by this DataHandler are present, the
462      * installed CommandMap chooses the appropriate commands.
463      *
464      * @return the CommandInfo objects representing the preferred commands
465      *
466      * @see javax.activation.CommandMap#getPreferredCommands
467      */

468     public CommandInfo JavaDoc[] getPreferredCommands() {
469     if (dataSource != null)
470         return getCommandMap().getPreferredCommands(getBaseType(),
471                             dataSource);
472     else
473         return getCommandMap().getPreferredCommands(getBaseType());
474     }
475
476     /**
477      * Return all the commands for this type of data.
478      * This method returns an array containing all commands
479      * for the type of data represented by this DataHandler. The
480      * MIME type for the underlying data represented by this DataHandler
481      * is used to call through to the <code>getAllCommands</code> method
482      * of the CommandMap associated with this DataHandler.
483      *
484      * @return the CommandInfo objects representing all the commands
485      *
486      * @see javax.activation.CommandMap#getAllCommands
487      */

488     public CommandInfo JavaDoc[] getAllCommands() {
489     if (dataSource != null)
490         return getCommandMap().getAllCommands(getBaseType(), dataSource);
491     else
492         return getCommandMap().getAllCommands(getBaseType());
493     }
494
495     /**
496      * Get the command <i>cmdName</i>. Use the search semantics as
497      * defined by the CommandMap installed in this DataHandler. The
498      * MIME type for the underlying data represented by this DataHandler
499      * is used to call through to the <code>getCommand</code> method
500      * of the CommandMap associated with this DataHandler.
501      *
502      * @param cmdName the command name
503      * @return the CommandInfo corresponding to the command
504      *
505      * @see javax.activation.CommandMap#getCommand
506      */

507     public CommandInfo JavaDoc getCommand(String JavaDoc cmdName) {
508     if (dataSource != null)
509         return getCommandMap().getCommand(getBaseType(), cmdName,
510                                 dataSource);
511     else
512         return getCommandMap().getCommand(getBaseType(), cmdName);
513     }
514
515     /**
516      * Return the data in its preferred Object form. <p>
517      *
518      * If the DataHandler was instantiated with an object, return
519      * the object. <p>
520      *
521      * If the DataHandler was instantiated with a DataSource,
522      * this method uses a DataContentHandler to return the content
523      * object for the data represented by this DataHandler. If no
524      * <code>DataContentHandler</code> can be found for the
525      * the type of this data, the DataHandler returns an
526      * InputStream for the data.
527      *
528      * @return the content.
529      * @exception IOException if an IOException occurs during
530      * this operation.
531      */

532     public Object JavaDoc getContent() throws IOException JavaDoc {
533     if (object != null)
534         return object;
535     else
536         return getDataContentHandler().getContent(getDataSource());
537     }
538
539     /**
540      * A convenience method that takes a CommandInfo object
541      * and instantiates the corresponding command, usually
542      * a JavaBean component.
543      * <p>
544      * This method calls the CommandInfo's <code>getCommandObject</code>
545      * method with the <code>ClassLoader</code> used to load
546      * the <code>javax.activation.DataHandler</code> class itself.
547      *
548      * @param cmdinfo the CommandInfo corresponding to a command
549      * @return the instantiated command object
550      */

551     public Object JavaDoc getBean(CommandInfo JavaDoc cmdinfo) {
552     Object JavaDoc bean = null;
553
554     try {
555         // make the bean
556
ClassLoader JavaDoc cld = null;
557         // First try the "application's" class loader.
558
cld = SecuritySupport.getContextClassLoader();
559         if (cld == null)
560         cld = this.getClass().getClassLoader();
561         bean = cmdinfo.getCommandObject(this, cld);
562     } catch (IOException JavaDoc e) {
563     } catch (ClassNotFoundException JavaDoc e) { }
564
565     return bean;
566     }
567
568     /**
569      * Get the DataContentHandler for this DataHandler: <p>
570      *
571      * If a DataContentHandlerFactory is set, use it.
572      * Otherwise look for an object to serve DCH in the
573      * following order: <p>
574      *
575      * 1) if a factory is set, use it <p>
576      * 2) if a CommandMap is set, use it <p>
577      * 3) use the default CommandMap <p>
578      *
579      * In any case, wrap the real DataContentHandler with one of our own
580      * to handle any missing cases, fill in defaults, and to ensure that
581      * we always have a non-null DataContentHandler.
582      *
583      * @return the requested DataContentHandler
584      */

585     private synchronized DataContentHandler JavaDoc getDataContentHandler() {
586
587     // make sure the factory didn't change
588
if (factory != oldFactory) {
589         oldFactory = factory;
590         factoryDCH = null;
591         dataContentHandler = null;
592         transferFlavors = emptyFlavors;
593     }
594
595     if (dataContentHandler != null)
596         return dataContentHandler;
597
598     String JavaDoc simpleMT = getBaseType();
599
600     if (factoryDCH == null && factory != null)
601         factoryDCH = factory.createDataContentHandler(simpleMT);
602
603     if (factoryDCH != null)
604         dataContentHandler = factoryDCH;
605
606     if (dataContentHandler == null) {
607         if (dataSource != null)
608         dataContentHandler = getCommandMap().
609                 createDataContentHandler(simpleMT, dataSource);
610         else
611         dataContentHandler = getCommandMap().
612                 createDataContentHandler(simpleMT);
613     }
614
615     // getDataContentHandler always uses these 'wrapper' handlers
616
// to make sure it returns SOMETHING meaningful...
617
if (dataSource != null)
618         dataContentHandler = new DataSourceDataContentHandler JavaDoc(
619                               dataContentHandler,
620                               dataSource);
621     else
622         dataContentHandler = new ObjectDataContentHandler JavaDoc(
623                               dataContentHandler,
624                               object,
625                               objectMimeType);
626     return dataContentHandler;
627     }
628
629     /**
630      * Use the MimeType class to extract the MIME type/subtype,
631      * ignoring the parameters. The type is cached.
632      */

633     private synchronized String JavaDoc getBaseType() {
634     if (shortType == null) {
635         String JavaDoc ct = getContentType();
636         try {
637         MimeType JavaDoc mt = new MimeType JavaDoc(ct);
638         shortType = mt.getBaseType();
639         } catch (MimeTypeParseException JavaDoc e) {
640         shortType = ct;
641         }
642     }
643     return shortType;
644     }
645
646     /**
647      * Sets the DataContentHandlerFactory. The DataContentHandlerFactory
648      * is called first to find DataContentHandlers.
649      * The DataContentHandlerFactory can only be set once.
650      * <p>
651      * If the DataContentHandlerFactory has already been set,
652      * this method throws an Error.
653      *
654      * @param newFactory the DataContentHandlerFactory
655      * @exception Error if the factory has already been defined.
656      *
657      * @see javax.activation.DataContentHandlerFactory
658      */

659     public static synchronized void setDataContentHandlerFactory(
660                      DataContentHandlerFactory JavaDoc newFactory) {
661     if (factory != null)
662         throw new Error JavaDoc("DataContentHandlerFactory already defined");
663
664     SecurityManager JavaDoc security = System.getSecurityManager();
665     if (security != null) {
666         try {
667         // if it's ok with the SecurityManager, it's ok with me...
668
security.checkSetFactory();
669         } catch (SecurityException JavaDoc ex) {
670         // otherwise, we also allow it if this code and the
671
// factory come from the same class loader (e.g.,
672
// the JAF classes were loaded with the applet classes).
673
if (DataHandler JavaDoc.class.getClassLoader() !=
674             newFactory.getClass().getClassLoader())
675             throw ex;
676         }
677     }
678     factory = newFactory;
679     }
680 }
681
682 /**
683  * The DataHanderDataSource class implements the
684  * DataSource interface when the DataHandler is constructed
685  * with an Object and a mimeType string.
686  */

687 class DataHandlerDataSource implements DataSource JavaDoc {
688     DataHandler JavaDoc dataHandler = null;
689
690     /**
691      * The constructor.
692      */

693     public DataHandlerDataSource(DataHandler JavaDoc dh) {
694     this.dataHandler = dh;
695     }
696
697     /**
698      * Returns an <code>InputStream</code> representing this object.
699      * @return the <code>InputStream</code>
700      */

701     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
702     return dataHandler.getInputStream();
703     }
704
705     /**
706      * Returns the <code>OutputStream</code> for this object.
707      * @return the <code>OutputStream</code>
708      */

709     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
710     return dataHandler.getOutputStream();
711     }
712
713     /**
714      * Returns the MIME type of the data represented by this object.
715      * @return the MIME type
716      */

717     public String JavaDoc getContentType() {
718     return dataHandler.getContentType();
719     }
720
721     /**
722      * Returns the name of this object.
723      * @return the name of this object
724      */

725     public String JavaDoc getName() {
726     return dataHandler.getName(); // what else would it be?
727
}
728 }
729
730 /*
731  * DataSourceDataContentHandler
732  *
733  * This is a <i>private</i> DataContentHandler that wraps the real
734  * DataContentHandler in the case where the DataHandler was instantiated
735  * with a DataSource.
736  */

737 class DataSourceDataContentHandler implements DataContentHandler JavaDoc {
738     private DataSource JavaDoc ds = null;
739     private DataFlavor JavaDoc transferFlavors[] = null;
740     private DataContentHandler JavaDoc dch = null;
741
742     /**
743      * The constructor.
744      */

745     public DataSourceDataContentHandler(DataContentHandler JavaDoc dch, DataSource JavaDoc ds) {
746     this.ds = ds;
747     this.dch = dch;
748     }
749
750     /**
751      * Return the DataFlavors for this <code>DataContentHandler</code>.
752      * @return the DataFlavors
753      */

754     public DataFlavor JavaDoc[] getTransferDataFlavors() {
755
756     if (transferFlavors == null) {
757         if (dch != null) { // is there a dch?
758
transferFlavors = dch.getTransferDataFlavors();
759         } else {
760         transferFlavors = new DataFlavor JavaDoc[1];
761         transferFlavors[0] =
762             new ActivationDataFlavor JavaDoc(ds.getContentType(),
763                          ds.getContentType());
764         }
765     }
766     return transferFlavors;
767     }
768
769     /**
770      * Return the Transfer Data of type DataFlavor from InputStream.
771      * @param df the DataFlavor
772      * @param ds the DataSource
773      * @return the constructed Object
774      */

775     public Object JavaDoc getTransferData(DataFlavor JavaDoc df, DataSource JavaDoc ds) throws
776                 UnsupportedFlavorException JavaDoc, IOException JavaDoc {
777
778     if (dch != null)
779         return dch.getTransferData(df, ds);
780     else if (df.equals(getTransferDataFlavors()[0])) // only have one now
781
return ds.getInputStream();
782     else
783         throw new UnsupportedFlavorException JavaDoc(df);
784     }
785
786     public Object JavaDoc getContent(DataSource JavaDoc ds) throws IOException JavaDoc {
787
788     if (dch != null)
789         return dch.getContent(ds);
790     else
791         return ds.getInputStream();
792     }
793
794     /**
795      * Write the object to the output stream.
796      */

797     public void writeTo(Object JavaDoc obj, String JavaDoc mimeType, OutputStream JavaDoc os)
798                         throws IOException JavaDoc {
799     if (dch != null)
800         dch.writeTo(obj, mimeType, os);
801     else
802         throw new UnsupportedDataTypeException JavaDoc(
803             "no DCH for content type " + ds.getContentType());
804     }
805 }
806
807 /*
808  * ObjectDataContentHandler
809  *
810  * This is a <i>private</i> DataContentHandler that wraps the real
811  * DataContentHandler in the case where the DataHandler was instantiated
812  * with an object.
813  */

814 class ObjectDataContentHandler implements DataContentHandler JavaDoc {
815     private DataFlavor JavaDoc transferFlavors[] = null;
816     private Object JavaDoc obj;
817     private String JavaDoc mimeType;
818     private DataContentHandler JavaDoc dch = null;
819
820     /**
821      * The constructor.
822      */

823     public ObjectDataContentHandler(DataContentHandler JavaDoc dch,
824                     Object JavaDoc obj, String JavaDoc mimeType) {
825     this.obj = obj;
826     this.mimeType = mimeType;
827     this.dch = dch;
828     }
829
830     /**
831      * Return the DataContentHandler for this object.
832      * Used only by the DataHandler class.
833      */

834     public DataContentHandler JavaDoc getDCH() {
835     return dch;
836     }
837
838     /**
839      * Return the DataFlavors for this <code>DataContentHandler</code>.
840      * @return the DataFlavors
841      */

842     public DataFlavor JavaDoc[] getTransferDataFlavors() {
843     if (transferFlavors == null) {
844         if (dch != null) {
845         transferFlavors = dch.getTransferDataFlavors();
846         } else {
847         transferFlavors = new DataFlavor JavaDoc[1];
848         transferFlavors[0] = new ActivationDataFlavor JavaDoc(obj.getClass(),
849                          mimeType, mimeType);
850         }
851     }
852     return transferFlavors;
853     }
854
855     /**
856      * Return the Transfer Data of type DataFlavor from InputStream.
857      * @param df the DataFlavor
858      * @param ds the DataSource
859      * @return the constructed Object
860      */

861     public Object JavaDoc getTransferData(DataFlavor JavaDoc df, DataSource JavaDoc ds)
862                 throws UnsupportedFlavorException JavaDoc, IOException JavaDoc {
863
864     if (dch != null)
865         return dch.getTransferData(df, ds);
866     else if (df.equals(transferFlavors[0])) // only have one now
867
return obj;
868     else
869         throw new UnsupportedFlavorException JavaDoc(df);
870
871     }
872
873     public Object JavaDoc getContent(DataSource JavaDoc ds) {
874     return obj;
875     }
876
877     /**
878      * Write the object to the output stream.
879      */

880     public void writeTo(Object JavaDoc obj, String JavaDoc mimeType, OutputStream JavaDoc os)
881                         throws IOException JavaDoc {
882     if (dch != null)
883         dch.writeTo(obj, mimeType, os);
884     else
885         throw new UnsupportedDataTypeException JavaDoc(
886                 "no object DCH for MIME type " + this.mimeType);
887     }
888 }
889
Popular Tags