/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* glassfish/bootstrap/legal/CDDLv1.0.txt or
* https://glassfish.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
* add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your
* own identifying information: Portions Copyright [yyyy]
* [name of copyright owner]
*/
/*
* @(#)DataHandler.java 1.39 05/11/16
*
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
*/
package javax.activation;
import java.io.
InputStream;
import java.io.
IOException;
import java.io.
OutputStream;
import java.io.
PipedInputStream;
import java.io.
PipedOutputStream;
import java.net.
URL;
import java.awt.datatransfer.
Transferable;
import java.awt.datatransfer.
DataFlavor;
import java.awt.datatransfer.
UnsupportedFlavorException;
/**
* The DataHandler class provides a consistent interface to data
* available in many different sources and formats.
* It manages simple stream to string conversions and related operations
* using DataContentHandlers.
* It provides access to commands that can operate on the data.
* The commands are found using a CommandMap. <p>
*
* <b>DataHandler and the Transferable Interface</b><p>
* DataHandler implements the Transferable interface so that data can
* be used in AWT data transfer operations, such as cut and paste and
* drag and drop. The implementation of the Transferable interface
* relies on the availability of an installed DataContentHandler
* object corresponding to the MIME type of the data represented in
* the specific instance of the DataHandler.<p>
*
* <b>DataHandler and CommandMaps</b><p>
* The DataHandler keeps track of the current CommandMap that it uses to
* service requests for commands (<code>getCommand</code>,
* <code>getAllCommands</code>, <code>getPreferredCommands</code>).
* Each instance of a DataHandler may have a CommandMap associated with
* it using the <code>setCommandMap</code> method. If a CommandMap was
* not set, DataHandler calls the <code>getDefaultCommandMap</code>
* method in CommandMap and uses the value it returns. See
* <i>CommandMap</i> for more information. <p>
*
* <b>DataHandler and URLs</b><p>
* The current DataHandler implementation creates a private
* instance of URLDataSource when it is constructed with a URL.
*
* @see javax.activation.CommandMap
* @see javax.activation.DataContentHandler
* @see javax.activation.DataSource
* @see javax.activation.URLDataSource
*/
public class
DataHandler implements
Transferable {
// Use the datasource to indicate whether we were started via the
// DataSource constructor or the object constructor.
private
DataSource dataSource = null;
private
DataSource objDataSource = null;
// The Object and mimetype from the constructor (if passed in).
// object remains null if it was instantiated with a
// DataSource.
private
Object object = null;
private
String objectMimeType = null;
// Keep track of the CommandMap
private
CommandMap currentCommandMap = null;
// our transfer flavors
private static final
DataFlavor emptyFlavors[] = new
DataFlavor[0];
private
DataFlavor transferFlavors[] =
emptyFlavors;
// our DataContentHandler
private
DataContentHandler dataContentHandler = null;
private
DataContentHandler factoryDCH = null;
// our DataContentHandlerFactory
private static
DataContentHandlerFactory factory = null;
private
DataContentHandlerFactory oldFactory = null;
// the short representation of the ContentType (sans params)
private
String shortType = null;
/**
* Create a <code>DataHandler</code> instance referencing the
* specified DataSource. The data exists in a byte stream form.
* The DataSource will provide an InputStream to access the data.
*
* @param ds the DataSource
*/
public
DataHandler(
DataSource ds) {
// save a reference to the incoming DS
dataSource =
ds;
oldFactory =
factory; // keep track of the factory
}
/**
* Create a <code>DataHandler</code> instance representing an object
* of this MIME type. This constructor is
* used when the application already has an in-memory representation
* of the data in the form of a Java Object.
*
* @param obj the Java Object
* @param mimeType the MIME type of the object
*/
public
DataHandler(
Object obj,
String mimeType) {
object =
obj;
objectMimeType =
mimeType;
oldFactory =
factory; // keep track of the factory
}
/**
* Create a <code>DataHandler</code> instance referencing a URL.
* The DataHandler internally creates a <code>URLDataSource</code>
* instance to represent the URL.
*
* @param url a URL object
*/
public
DataHandler(
URL url) {
dataSource = new
URLDataSource(
url);
oldFactory =
factory; // keep track of the factory
}
/**
* Return the CommandMap for this instance of DataHandler.
*/
private synchronized
CommandMap getCommandMap() {
if (
currentCommandMap != null)
return
currentCommandMap;
else
return
CommandMap.
getDefaultCommandMap();
}
/**
* Return the DataSource associated with this instance
* of DataHandler.
* <p>
* For DataHandlers that have been instantiated with a DataSource,
* this method returns the DataSource that was used to create the
* DataHandler object. In other cases the DataHandler
* constructs a DataSource from the data used to construct
* the DataHandler. DataSources created for DataHandlers <b>not</b>
* instantiated with a DataSource are cached for performance
* reasons.
*
* @return a valid DataSource object for this DataHandler
*/
public
DataSource getDataSource() {
if (
dataSource == null) {
// create one on the fly
if (
objDataSource == null)
objDataSource = new
DataHandlerDataSource(this);
return
objDataSource;
}
return
dataSource;
}
/**
* Return the name of the data object. If this DataHandler
* was created with a DataSource, this method calls through
* to the <code>DataSource.getName</code> method, otherwise it
* returns <i>null</i>.
*
* @return the name of the object
*/
public
String getName() {
if (
dataSource != null)
return
dataSource.
getName();
else
return null;
}
/**
* Return the MIME type of this object as retrieved from
* the source object. Note that this is the <i>full</i>
* type with parameters.
*
* @return the MIME type
*/
public
String getContentType() {
if (
dataSource != null) // data source case
return
dataSource.
getContentType();
else
return
objectMimeType; // obj/type case
}
/**
* Get the InputStream for this object. <p>
*
* For DataHandlers instantiated with a DataSource, the DataHandler
* calls the <code>DataSource.getInputStream</code> method and
* returns the result to the caller.
* <p>
* For DataHandlers instantiated with an Object, the DataHandler
* first attempts to find a DataContentHandler for the Object. If
* the DataHandler can not find a DataContentHandler for this MIME
* type, it throws an UnsupportedDataTypeException. If it is
* successful, it creates a pipe and a thread. The thread uses the
* DataContentHandler's <code>writeTo</code> method to write the
* stream data into one end of the pipe. The other end of the pipe
* is returned to the caller. Because a thread is created to copy
* the data, IOExceptions that may occur during the copy can not be
* propagated back to the caller. The result is an empty stream.<p>
*
* @return the InputStream representing this data
* @exception IOException if an I/O error occurs
*
* @see javax.activation.DataContentHandler#writeTo
* @see javax.activation.UnsupportedDataTypeException
*/
public
InputStream getInputStream() throws
IOException {
InputStream ins = null;
if (
dataSource != null) {
ins =
dataSource.
getInputStream();
} else {
DataContentHandler dch =
getDataContentHandler();
// we won't even try if we can't get a dch
if (
dch == null)
throw new
UnsupportedDataTypeException(
"no DCH for MIME type " +
getBaseType());
if (
dch instanceof
ObjectDataContentHandler) {
if (((
ObjectDataContentHandler)
dch).
getDCH() == null)
throw new
UnsupportedDataTypeException(
"no object DCH for MIME type " +
getBaseType());
}
// there is none but the default^^^^^^^^^^^^^^^^
final
DataContentHandler fdch =
dch;
// from bill s.
// ce n'est pas une pipe!
//
// NOTE: This block of code needs to throw exceptions, but
// can't because it is in another thread!!! ARG!
//
final
PipedOutputStream pos = new
PipedOutputStream();
PipedInputStream pin = new
PipedInputStream(
pos);
new
Thread(
new
Runnable() {
public void
run() {
try {
fdch.
writeTo(
object,
objectMimeType,
pos);
} catch (
IOException e) {
} finally {
try {
pos.
close();
} catch (
IOException ie) { }
}
}
},
"DataHandler.getInputStream").
start();
ins =
pin;
}
return
ins;
}
/**
* Write the data to an <code>OutputStream</code>.<p>
*
* If the DataHandler was created with a DataSource, writeTo
* retrieves the InputStream and copies the bytes from the
* InputStream to the OutputStream passed in.
* <p>
* If the DataHandler was created with an object, writeTo
* retrieves the DataContentHandler for the object's type.
* If the DataContentHandler was found, it calls the
* <code>writeTo</code> method on the <code>DataContentHandler</code>.
*
* @param os the OutputStream to write to
* @exception IOException if an I/O error occurs
*/
public void
writeTo(
OutputStream os) throws
IOException {
// for the DataSource case
if (
dataSource != null) {
InputStream is = null;
byte
data[] = new byte[8*1024];
int
bytes_read;
is =
dataSource.
getInputStream();
try {
while ((
bytes_read =
is.
read(
data)) > 0) {
os.
write(
data, 0,
bytes_read);
}
} finally {
is.
close();
is = null;
}
} else { // for the Object case
DataContentHandler dch =
getDataContentHandler();
dch.
writeTo(
object,
objectMimeType,
os);
}
}
/**
* Get an OutputStream for this DataHandler to allow overwriting
* the underlying data.
* If the DataHandler was created with a DataSource, the
* DataSource's <code>getOutputStream</code> method is called.
* Otherwise, <code>null</code> is returned.
*
* @return the OutputStream
*
* @see javax.activation.DataSource#getOutputStream
* @see javax.activation.URLDataSource
*/
public
OutputStream getOutputStream() throws
IOException {
if (
dataSource != null)
return
dataSource.
getOutputStream();
else
return null;
}
/**
* Return the DataFlavors in which this data is available. <p>
*
* Returns an array of DataFlavor objects indicating the flavors
* the data can be provided in. The array is usually ordered
* according to preference for providing the data, from most
* richly descriptive to least richly descriptive.<p>
*
* The DataHandler attempts to find a DataContentHandler that
* corresponds to the MIME type of the data. If one is located,
* the DataHandler calls the DataContentHandler's
* <code>getTransferDataFlavors</code> method. <p>
*
* If a DataContentHandler can <i>not</i> be located, and if the
* DataHandler was created with a DataSource (or URL), one
* DataFlavor is returned that represents this object's MIME type
* and the <code>java.io.InputStream</code> class. If the
* DataHandler was created with an object and a MIME type,
* getTransferDataFlavors returns one DataFlavor that represents
* this object's MIME type and the object's class.
*
* @return an array of data flavors in which this data can be transferred
* @see javax.activation.DataContentHandler#getTransferDataFlavors
*/
public synchronized
DataFlavor[]
getTransferDataFlavors() {
if (
factory !=
oldFactory) // if the factory has changed, clear cache
transferFlavors =
emptyFlavors;
// if it's not set, set it...
if (
transferFlavors ==
emptyFlavors)
transferFlavors =
getDataContentHandler().
getTransferDataFlavors();
return
transferFlavors;
}
/**
* Returns whether the specified data flavor is supported
* for this object.<p>
*
* This method iterates through the DataFlavors returned from
* <code>getTransferDataFlavors</code>, comparing each with
* the specified flavor.
*
* @param flavor the requested flavor for the data
* @return true if the data flavor is supported
* @see javax.activation.DataHandler#getTransferDataFlavors
*/
public boolean
isDataFlavorSupported(
DataFlavor flavor) {
DataFlavor[]
lFlavors =
getTransferDataFlavors();
for (int
i = 0;
i <
lFlavors.length;
i++) {
if (
lFlavors[
i].
equals(
flavor))
return true;
}
return false;
}
/**
* Returns an object that represents the data to be
* transferred. The class of the object returned is defined by the
* representation class of the data flavor.<p>
*
* <b>For DataHandler's created with DataSources or URLs:</b><p>
*
* The DataHandler attempts to locate a DataContentHandler
* for this MIME type. If one is found, the passed in DataFlavor
* and the type of the data are passed to its <code>getTransferData</code>
* method. If the DataHandler fails to locate a DataContentHandler
* and the flavor specifies this object's MIME type and the
* <code>java.io.InputStream</code> class, this object's InputStream
* is returned.
* Otherwise it throws an UnsupportedFlavorException. <p>
*
* <b>For DataHandler's created with Objects:</b><p>
*
* The DataHandler attempts to locate a DataContentHandler
* for this MIME type. If one is found, the passed in DataFlavor
* and the type of the data are passed to its getTransferData
* method. If the DataHandler fails to locate a DataContentHandler
* and the flavor specifies this object's MIME type and its class,
* this DataHandler's referenced object is returned.
* Otherwise it throws an UnsupportedFlavorException.
*
* @param flavor the requested flavor for the data
* @return the object
* @exception UnsupportedFlavorException if the data could not be
* converted to the requested flavor
* @exception IOException if an I/O error occurs
* @see javax.activation.ActivationDataFlavor
*/
public
Object getTransferData(
DataFlavor flavor)
throws
UnsupportedFlavorException,
IOException {
return
getDataContentHandler().
getTransferData(
flavor,
dataSource);
}
/**
* Set the CommandMap for use by this DataHandler.
* Setting it to <code>null</code> causes the CommandMap to revert
* to the CommandMap returned by the
* <code>CommandMap.getDefaultCommandMap</code> method.
* Changing the CommandMap, or setting it to <code>null</code>,
* clears out any data cached from the previous CommandMap.
*
* @param commandMap the CommandMap to use in this DataHandler
*
* @see javax.activation.CommandMap#setDefaultCommandMap
*/
public synchronized void
setCommandMap(
CommandMap commandMap) {
if (
commandMap !=
currentCommandMap ||
commandMap == null) {
// clear cached values...
transferFlavors =
emptyFlavors;
dataContentHandler = null;
currentCommandMap =
commandMap;
}
}
/**
* Return the <i>preferred</i> commands for this type of data.
* This method calls the <code>getPreferredCommands</code> method
* in the CommandMap associated with this instance of DataHandler.
* This method returns an array that represents a subset of
* available commands. In cases where multiple commands for the
* MIME type represented by this DataHandler are present, the
* installed CommandMap chooses the appropriate commands.
*
* @return the CommandInfo objects representing the preferred commands
*
* @see javax.activation.CommandMap#getPreferredCommands
*/
public
CommandInfo[]
getPreferredCommands() {
if (
dataSource != null)
return
getCommandMap().
getPreferredCommands(
getBaseType(),
dataSource);
else
return
getCommandMap().
getPreferredCommands(
getBaseType());
}
/**
* Return all the commands for this type of data.
* This method returns an array containing all commands
* for the type of data represented by this DataHandler. The
* MIME type for the underlying data represented by this DataHandler
* is used to call through to the <code>getAllCommands</code> method
* of the CommandMap associated with this DataHandler.
*
* @return the CommandInfo objects representing all the commands
*
* @see javax.activation.CommandMap#getAllCommands
*/
public
CommandInfo[]
getAllCommands() {
if (
dataSource != null)
return
getCommandMap().
getAllCommands(
getBaseType(),
dataSource);
else
return
getCommandMap().
getAllCommands(
getBaseType());
}
/**
* Get the command <i>cmdName</i>. Use the search semantics as
* defined by the CommandMap installed in this DataHandler. The
* MIME type for the underlying data represented by this DataHandler
* is used to call through to the <code>getCommand</code> method
* of the CommandMap associated with this DataHandler.
*
* @param cmdName the command name
* @return the CommandInfo corresponding to the command
*
* @see javax.activation.CommandMap#getCommand
*/
public
CommandInfo getCommand(
String cmdName) {
if (
dataSource != null)
return
getCommandMap().
getCommand(
getBaseType(),
cmdName,
dataSource);
else
return
getCommandMap().
getCommand(
getBaseType(),
cmdName);
}
/**
* Return the data in its preferred Object form. <p>
*
* If the DataHandler was instantiated with an object, return
* the object. <p>
*
* If the DataHandler was instantiated with a DataSource,
* this method uses a DataContentHandler to return the content
* object for the data represented by this DataHandler. If no
* <code>DataContentHandler</code> can be found for the
* the type of this data, the DataHandler returns an
* InputStream for the data.
*
* @return the content.
* @exception IOException if an IOException occurs during
* this operation.
*/
public
Object getContent() throws
IOException {
if (
object != null)
return
object;
else
return
getDataContentHandler().
getContent(
getDataSource());
}
/**
* A convenience method that takes a CommandInfo object
* and instantiates the corresponding command, usually
* a JavaBean component.
* <p>
* This method calls the CommandInfo's <code>getCommandObject</code>
* method with the <code>ClassLoader</code> used to load
* the <code>javax.activation.DataHandler</code> class itself.
*
* @param cmdinfo the CommandInfo corresponding to a command
* @return the instantiated command object
*/
public
Object getBean(
CommandInfo cmdinfo) {
Object bean = null;
try {
// make the bean
ClassLoader cld = null;
// First try the "application's" class loader.
cld =
SecuritySupport.
getContextClassLoader();
if (
cld == null)
cld = this.
getClass().
getClassLoader();
bean =
cmdinfo.
getCommandObject(this,
cld);
} catch (
IOException e) {
} catch (
ClassNotFoundException e) { }
return
bean;
}
/**
* Get the DataContentHandler for this DataHandler: <p>
*
* If a DataContentHandlerFactory is set, use it.
* Otherwise look for an object to serve DCH in the
* following order: <p>
*
* 1) if a factory is set, use it <p>
* 2) if a CommandMap is set, use it <p>
* 3) use the default CommandMap <p>
*
* In any case, wrap the real DataContentHandler with one of our own
* to handle any missing cases, fill in defaults, and to ensure that
* we always have a non-null DataContentHandler.
*
* @return the requested DataContentHandler
*/
private synchronized
DataContentHandler getDataContentHandler() {
// make sure the factory didn't change
if (
factory !=
oldFactory) {
oldFactory =
factory;
factoryDCH = null;
dataContentHandler = null;
transferFlavors =
emptyFlavors;
}
if (
dataContentHandler != null)
return
dataContentHandler;
String simpleMT =
getBaseType();
if (
factoryDCH == null &&
factory != null)
factoryDCH =
factory.
createDataContentHandler(
simpleMT);
if (
factoryDCH != null)
dataContentHandler =
factoryDCH;
if (
dataContentHandler == null) {
if (
dataSource != null)
dataContentHandler =
getCommandMap().
createDataContentHandler(
simpleMT,
dataSource);
else
dataContentHandler =
getCommandMap().
createDataContentHandler(
simpleMT);
}
// getDataContentHandler always uses these 'wrapper' handlers
// to make sure it returns SOMETHING meaningful...
if (
dataSource != null)
dataContentHandler = new
DataSourceDataContentHandler(
dataContentHandler,
dataSource);
else
dataContentHandler = new
ObjectDataContentHandler(
dataContentHandler,
object,
objectMimeType);
return
dataContentHandler;
}
/**
* Use the MimeType class to extract the MIME type/subtype,
* ignoring the parameters. The type is cached.
*/
private synchronized
String getBaseType() {
if (
shortType == null) {
String ct =
getContentType();
try {
MimeType mt = new
MimeType(
ct);
shortType =
mt.
getBaseType();
} catch (
MimeTypeParseException e) {
shortType =
ct;
}
}
return
shortType;
}
/**
* Sets the DataContentHandlerFactory. The DataContentHandlerFactory
* is called first to find DataContentHandlers.
* The DataContentHandlerFactory can only be set once.
* <p>
* If the DataContentHandlerFactory has already been set,
* this method throws an Error.
*
* @param newFactory the DataContentHandlerFactory
* @exception Error if the factory has already been defined.
*
* @see javax.activation.DataContentHandlerFactory
*/
public static synchronized void
setDataContentHandlerFactory(
DataContentHandlerFactory newFactory) {
if (
factory != null)
throw new
Error("DataContentHandlerFactory already defined");
SecurityManager security =
System.
getSecurityManager();
if (
security != null) {
try {
// if it's ok with the SecurityManager, it's ok with me...
security.
checkSetFactory();
} catch (
SecurityException ex) {
// otherwise, we also allow it if this code and the
// factory come from the same class loader (e.g.,
// the JAF classes were loaded with the applet classes).
if (
DataHandler.class.
getClassLoader() !=
newFactory.
getClass().
getClassLoader())
throw
ex;
}
}
factory =
newFactory;
}
}
/**
* The DataHanderDataSource class implements the
* DataSource interface when the DataHandler is constructed
* with an Object and a mimeType string.
*/
class
DataHandlerDataSource implements
DataSource {
DataHandler dataHandler = null;
/**
* The constructor.
*/
public
DataHandlerDataSource(
DataHandler dh) {
this.
dataHandler =
dh;
}
/**
* Returns an <code>InputStream</code> representing this object.
* @return the <code>InputStream</code>
*/
public
InputStream getInputStream() throws
IOException {
return
dataHandler.
getInputStream();
}
/**
* Returns the <code>OutputStream</code> for this object.
* @return the <code>OutputStream</code>
*/
public
OutputStream getOutputStream() throws
IOException {
return
dataHandler.
getOutputStream();
}
/**
* Returns the MIME type of the data represented by this object.
* @return the MIME type
*/
public
String getContentType() {
return
dataHandler.
getContentType();
}
/**
* Returns the name of this object.
* @return the name of this object
*/
public
String getName() {
return
dataHandler.
getName(); // what else would it be?
}
}
/*
* DataSourceDataContentHandler
*
* This is a <i>private</i> DataContentHandler that wraps the real
* DataContentHandler in the case where the DataHandler was instantiated
* with a DataSource.
*/
class
DataSourceDataContentHandler implements
DataContentHandler {
private
DataSource ds = null;
private
DataFlavor transferFlavors[] = null;
private
DataContentHandler dch = null;
/**
* The constructor.
*/
public
DataSourceDataContentHandler(
DataContentHandler dch,
DataSource ds) {
this.
ds =
ds;
this.
dch =
dch;
}
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
* @return the DataFlavors
*/
public
DataFlavor[]
getTransferDataFlavors() {
if (
transferFlavors == null) {
if (
dch != null) { // is there a dch?
transferFlavors =
dch.
getTransferDataFlavors();
} else {
transferFlavors = new
DataFlavor[1];
transferFlavors[0] =
new
ActivationDataFlavor(
ds.
getContentType(),
ds.
getContentType());
}
}
return
transferFlavors;
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
* @param df the DataFlavor
* @param ds the DataSource
* @return the constructed Object
*/
public
Object getTransferData(
DataFlavor df,
DataSource ds) throws
UnsupportedFlavorException,
IOException {
if (
dch != null)
return
dch.
getTransferData(
df,
ds);
else if (
df.
equals(
getTransferDataFlavors()[0])) // only have one now
return
ds.
getInputStream();
else
throw new
UnsupportedFlavorException(
df);
}
public
Object getContent(
DataSource ds) throws
IOException {
if (
dch != null)
return
dch.
getContent(
ds);
else
return
ds.
getInputStream();
}
/**
* Write the object to the output stream.
*/
public void
writeTo(
Object obj,
String mimeType,
OutputStream os)
throws
IOException {
if (
dch != null)
dch.
writeTo(
obj,
mimeType,
os);
else
throw new
UnsupportedDataTypeException(
"no DCH for content type " +
ds.
getContentType());
}
}
/*
* ObjectDataContentHandler
*
* This is a <i>private</i> DataContentHandler that wraps the real
* DataContentHandler in the case where the DataHandler was instantiated
* with an object.
*/
class
ObjectDataContentHandler implements
DataContentHandler {
private
DataFlavor transferFlavors[] = null;
private
Object obj;
private
String mimeType;
private
DataContentHandler dch = null;
/**
* The constructor.
*/
public
ObjectDataContentHandler(
DataContentHandler dch,
Object obj,
String mimeType) {
this.
obj =
obj;
this.
mimeType =
mimeType;
this.
dch =
dch;
}
/**
* Return the DataContentHandler for this object.
* Used only by the DataHandler class.
*/
public
DataContentHandler getDCH() {
return
dch;
}
/**
* Return the DataFlavors for this <code>DataContentHandler</code>.
* @return the DataFlavors
*/
public
DataFlavor[]
getTransferDataFlavors() {
if (
transferFlavors == null) {
if (
dch != null) {
transferFlavors =
dch.
getTransferDataFlavors();
} else {
transferFlavors = new
DataFlavor[1];
transferFlavors[0] = new
ActivationDataFlavor(
obj.
getClass(),
mimeType,
mimeType);
}
}
return
transferFlavors;
}
/**
* Return the Transfer Data of type DataFlavor from InputStream.
* @param df the DataFlavor
* @param ds the DataSource
* @return the constructed Object
*/
public
Object getTransferData(
DataFlavor df,
DataSource ds)
throws
UnsupportedFlavorException,
IOException {
if (
dch != null)
return
dch.
getTransferData(
df,
ds);
else if (
df.
equals(
transferFlavors[0])) // only have one now
return
obj;
else
throw new
UnsupportedFlavorException(
df);
}
public
Object getContent(
DataSource ds) {
return
obj;
}
/**
* Write the object to the output stream.
*/
public void
writeTo(
Object obj,
String mimeType,
OutputStream os)
throws
IOException {
if (
dch != null)
dch.
writeTo(
obj,
mimeType,
os);
else
throw new
UnsupportedDataTypeException(
"no object DCH for MIME type " + this.
mimeType);
}
}