summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/activation/DataHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/activation/DataHandler.java')
-rw-r--r--libjava/classpath/javax/activation/DataHandler.java481
1 files changed, 481 insertions, 0 deletions
diff --git a/libjava/classpath/javax/activation/DataHandler.java b/libjava/classpath/javax/activation/DataHandler.java
new file mode 100644
index 000000000..63ad0c418
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataHandler.java
@@ -0,0 +1,481 @@
+/* DataHandler.java -- Handler for data available in multiple formats.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.activation;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.net.URL;
+
+/**
+ * Handler for data available in multiple sources and formats.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class DataHandler
+ implements Transferable
+{
+
+ private static final DataFlavor[] NO_FLAVORS = new DataFlavor[0];
+ private static DataContentHandlerFactory factory = null;
+
+ private final DataSource dataSource;
+ private DataSource objDataSource;
+ private Object object;
+ private String objectMimeType;
+ private CommandMap currentCommandMap;
+ private DataFlavor[] transferFlavors = NO_FLAVORS;
+ private DataContentHandler dataContentHandler;
+ private DataContentHandler factoryDCH;
+ private DataContentHandlerFactory oldFactory;
+ private String shortType;
+
+ /**
+ * Constructor in which the data is read from a data source.
+ * @param ds the data source
+ */
+ public DataHandler(DataSource ds)
+ {
+ dataSource = ds;
+ oldFactory = factory;
+ }
+
+ /**
+ * Constructor using a reified object representation.
+ * @param obj the object representation of the data
+ * @param mimeType the MIME type of the object
+ */
+ public DataHandler(Object obj, String mimeType)
+ {
+ dataSource = null;
+ object = obj;
+ objectMimeType = mimeType;
+ oldFactory = factory;
+ }
+
+ /**
+ * Constructor in which the data is read from a URL.
+ * @param url the URL
+ */
+ public DataHandler(URL url)
+ {
+ dataSource = new URLDataSource(url);
+ oldFactory = factory;
+ }
+
+ /**
+ * Returns the data source from which data is read.
+ */
+ public DataSource getDataSource()
+ {
+ if (dataSource != null)
+ {
+ return dataSource;
+ }
+ if (objDataSource == null)
+ {
+ objDataSource = new DataHandlerDataSource(this);
+ }
+ return objDataSource;
+ }
+
+ /**
+ * Returns the name of the data object if created with a DataSource.
+ */
+ public String getName()
+ {
+ if (dataSource != null)
+ {
+ return dataSource.getName();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the MIME type of the data (with parameters).
+ */
+ public String getContentType()
+ {
+ if (dataSource != null)
+ {
+ return dataSource.getContentType();
+ }
+ return objectMimeType;
+ }
+
+ /**
+ * Returns an input stream from which the data can be read.
+ */
+ public InputStream getInputStream()
+ throws IOException
+ {
+ if (dataSource != null)
+ {
+ return dataSource.getInputStream();
+ }
+ DataContentHandler dch = getDataContentHandler();
+ if (dch == null)
+ {
+ throw new UnsupportedDataTypeException("no DCH for MIME type " +
+ getShortType());
+ }
+ if ((dch instanceof ObjectDataContentHandler) &&
+ ((ObjectDataContentHandler)dch).getDCH() == null)
+ {
+ throw new UnsupportedDataTypeException("no object DCH " +
+ "for MIME type " +
+ getShortType());
+ }
+ PipedOutputStream pos = new PipedOutputStream();
+ DataContentHandlerWriter dchw =
+ new DataContentHandlerWriter(dch, object, objectMimeType, pos);
+ Thread thread = new Thread(dchw, "DataHandler.getInputStream");
+ thread.start();
+ return new PipedInputStream(pos);
+ }
+
+ static class DataContentHandlerWriter
+ implements Runnable
+ {
+
+ DataContentHandler dch;
+ Object object;
+ String mimeType;
+ OutputStream out;
+
+ DataContentHandlerWriter(DataContentHandler dch, Object object,
+ String mimeType, OutputStream out)
+ {
+ this.dch = dch;
+ this.object = object;
+ this.mimeType = mimeType;
+ this.out = out;
+ }
+
+ public void run()
+ {
+ try
+ {
+ dch.writeTo(object, mimeType, out);
+ }
+ catch(IOException e)
+ {
+ }
+ finally
+ {
+ try
+ {
+ out.close();
+ }
+ catch(IOException e)
+ {
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes the data as a byte stream.
+ * @param os the stream to write to
+ */
+ public void writeTo(OutputStream os)
+ throws IOException
+ {
+ if (dataSource != null)
+ {
+ InputStream in = dataSource.getInputStream();
+ byte[] buf = new byte[8192];
+ for (int len = in.read(buf); len != -1; len = in.read(buf))
+ {
+ os.write(buf, 0, len);
+ }
+ in.close();
+ }
+ else
+ {
+ DataContentHandler dch = getDataContentHandler();
+ dch.writeTo(object, objectMimeType, os);
+ }
+ }
+
+ /**
+ * Returns an output stream that can be used to overwrite the underlying
+ * data, if the DataSource constructor was used.
+ */
+ public OutputStream getOutputStream()
+ throws IOException
+ {
+ if (dataSource != null)
+ {
+ return dataSource.getOutputStream();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the data flavors in which this data is available.
+ */
+ public synchronized DataFlavor[] getTransferDataFlavors()
+ {
+ if (factory != oldFactory || transferFlavors == NO_FLAVORS)
+ {
+ DataContentHandler dch = getDataContentHandler();
+ transferFlavors = dch.getTransferDataFlavors();
+ }
+ return transferFlavors;
+ }
+
+ /**
+ * Indicates whether the specified data flavor is supported for this
+ * data.
+ */
+ public boolean isDataFlavorSupported(DataFlavor flavor)
+ {
+ DataFlavor[] flavors = getTransferDataFlavors();
+ for (int i = 0; i < flavors.length; i++)
+ {
+ if (flavors[i].equals(flavor))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns an object representing the data to be transferred.
+ * @param flavor the requested data flavor
+ */
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException
+ {
+ DataContentHandler dch = getDataContentHandler();
+ return dch.getTransferData(flavor, dataSource);
+ }
+
+ /**
+ * Sets the command map to be used by this data handler.
+ * Setting to null uses the default command map.
+ * @param commandMap the command map to use
+ */
+ public synchronized void setCommandMap(CommandMap commandMap)
+ {
+ if (commandMap != currentCommandMap || commandMap == null)
+ {
+ transferFlavors = NO_FLAVORS;
+ dataContentHandler = null;
+ currentCommandMap = commandMap;
+ }
+ }
+
+ /**
+ * Returns the preferred commands for this type of data.
+ */
+ public CommandInfo[] getPreferredCommands()
+ {
+ CommandMap commandMap = getCommandMap();
+ return commandMap.getPreferredCommands(getShortType());
+ }
+
+ /**
+ * Returns the complete list of commands for this type of data.
+ */
+ public CommandInfo[] getAllCommands()
+ {
+ CommandMap commandMap = getCommandMap();
+ return commandMap.getAllCommands(getShortType());
+ }
+
+ /**
+ * Returns the specified command.
+ * @param cmdName the command name
+ */
+ public CommandInfo getCommand(String cmdName)
+ {
+ CommandMap commandMap = getCommandMap();
+ return commandMap.getCommand(getShortType(), cmdName);
+ }
+
+ /**
+ * Returns the data as a reified object.
+ */
+ public Object getContent()
+ throws IOException
+ {
+ DataContentHandler dch = getDataContentHandler();
+ return dch.getContent(getDataSource());
+ }
+
+ /**
+ * Returns the instantiated bean using the specified command.
+ * @param cmdInfo the command to instantiate the bean with
+ */
+ public Object getBean(CommandInfo cmdInfo)
+ {
+ try
+ {
+ return cmdInfo.getCommandObject(this, getClass().getClassLoader());
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace(System.err);
+ return null;
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace(System.err);
+ return null;
+ }
+ }
+
+ /**
+ * Sets the data content handler factory.
+ * If the factory has already been set, throws an Error.
+ * @param newFactory the factory to set
+ */
+ public static synchronized void
+ setDataContentHandlerFactory(DataContentHandlerFactory newFactory)
+ {
+ if (factory != null)
+ {
+ throw new Error("DataContentHandlerFactory already defined");
+ }
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ try
+ {
+ security.checkSetFactory();
+ }
+ catch (SecurityException e)
+ {
+ if (newFactory != null && DataHandler.class.getClassLoader()
+ != newFactory.getClass().getClassLoader())
+ {
+ throw e;
+ }
+ }
+ }
+ factory = newFactory;
+ }
+
+ /*
+ * Returns just the base part of the data's content-type, with no
+ * parameters.
+ */
+ private synchronized String getShortType()
+ {
+ if (shortType == null)
+ {
+ String contentType = getContentType();
+ try
+ {
+ MimeType mimeType = new MimeType(contentType);
+ shortType = mimeType.getBaseType();
+ }
+ catch (MimeTypeParseException e)
+ {
+ shortType = contentType;
+ }
+ }
+ return shortType;
+ }
+
+ /*
+ * Returns the command map for this handler.
+ */
+ private synchronized CommandMap getCommandMap()
+ {
+ if (currentCommandMap != null)
+ {
+ return currentCommandMap;
+ }
+ return CommandMap.getDefaultCommandMap();
+ }
+
+ /*
+ * Returns the DCH for this handler.
+ */
+ private synchronized DataContentHandler getDataContentHandler()
+ {
+ if (factory != oldFactory)
+ {
+ oldFactory = factory;
+ factoryDCH = null;
+ dataContentHandler = null;
+ transferFlavors = NO_FLAVORS;
+ }
+ if (dataContentHandler != null)
+ {
+ return dataContentHandler;
+ }
+ String mimeType = getShortType();
+ if (factoryDCH == null && factory != null)
+ {
+ factoryDCH = factory.createDataContentHandler(mimeType);
+ }
+ if (factoryDCH != null)
+ {
+ dataContentHandler = factoryDCH;
+ }
+ if (dataContentHandler == null)
+ {
+ CommandMap commandMap = getCommandMap();
+ dataContentHandler = commandMap.createDataContentHandler(mimeType);
+ }
+ if (dataSource != null)
+ {
+ dataContentHandler =
+ new DataSourceDataContentHandler(dataContentHandler, dataSource);
+ }
+ else
+ {
+ dataContentHandler =
+ new ObjectDataContentHandler(dataContentHandler, object,
+ objectMimeType);
+ }
+ return dataContentHandler;
+ }
+
+}