mirror of
https://github.com/autc04/Retro68.git
synced 2025-02-20 02:29:11 +00:00
482 lines
12 KiB
Java
482 lines
12 KiB
Java
/* 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;
|
|
}
|
|
|
|
}
|