/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

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.io.OutputStreamWriter;
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();
	if (transferFlavors == emptyFlavors)
	    return transferFlavors;	// no need to clone an empty array
	else
	    return transferFlavors.clone();
    }

    /**
     * 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 synchronized 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(getTransferDataFlavors()[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 if (obj instanceof byte[])
	    os.write((byte[])obj);
	else if (obj instanceof String) {
	    OutputStreamWriter osw = new OutputStreamWriter(os);
	    osw.write((String)obj);
	    osw.flush();
	} else
	    throw new UnsupportedDataTypeException(
				"no object DCH for MIME type " + this.mimeType);
    }
}
