summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/activation
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/activation')
-rw-r--r--libjava/classpath/javax/activation/ActivationDataFlavor.java161
-rw-r--r--libjava/classpath/javax/activation/CommandInfo.java116
-rw-r--r--libjava/classpath/javax/activation/CommandMap.java211
-rw-r--r--libjava/classpath/javax/activation/CommandObject.java61
-rw-r--r--libjava/classpath/javax/activation/DataContentHandler.java84
-rw-r--r--libjava/classpath/javax/activation/DataContentHandlerFactory.java55
-rw-r--r--libjava/classpath/javax/activation/DataHandler.java481
-rw-r--r--libjava/classpath/javax/activation/DataHandlerDataSource.java83
-rw-r--r--libjava/classpath/javax/activation/DataSource.java75
-rw-r--r--libjava/classpath/javax/activation/DataSourceDataContentHandler.java125
-rw-r--r--libjava/classpath/javax/activation/FileDataSource.java122
-rw-r--r--libjava/classpath/javax/activation/FileTypeMap.java107
-rw-r--r--libjava/classpath/javax/activation/MailcapCommandMap.java803
-rw-r--r--libjava/classpath/javax/activation/MimeType.java292
-rw-r--r--libjava/classpath/javax/activation/MimeTypeParameterList.java335
-rw-r--r--libjava/classpath/javax/activation/MimeTypeParseException.java83
-rw-r--r--libjava/classpath/javax/activation/MimetypesFileTypeMap.java439
-rw-r--r--libjava/classpath/javax/activation/ObjectDataContentHandler.java127
-rw-r--r--libjava/classpath/javax/activation/URLDataSource.java137
-rw-r--r--libjava/classpath/javax/activation/UnsupportedDataTypeException.java69
-rw-r--r--libjava/classpath/javax/activation/package.html44
21 files changed, 4010 insertions, 0 deletions
diff --git a/libjava/classpath/javax/activation/ActivationDataFlavor.java b/libjava/classpath/javax/activation/ActivationDataFlavor.java
new file mode 100644
index 000000000..91812092e
--- /dev/null
+++ b/libjava/classpath/javax/activation/ActivationDataFlavor.java
@@ -0,0 +1,161 @@
+/* ActivationDataFlavor.java -- Activation-specific DataFlavor instance.
+ 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 gnu.java.lang.CPStringBuilder;
+
+import java.awt.datatransfer.DataFlavor;
+import java.io.InputStream;
+
+/**
+ * Activation-specific DataFlavor with improved MIME parsing.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.0.2
+ */
+public class ActivationDataFlavor extends DataFlavor
+{
+
+ private final String mimeType;
+ private final Class<?> representationClass;
+ private String humanPresentableName;
+
+ /**
+ * Constructor.
+ * @param representationClass the representation class
+ * @param mimeType the MIME type of the data
+ * @param humanPresentableName the human-presentable name of the data
+ * flavor
+ */
+ // Raw types enforced as part of spec.
+ @SuppressWarnings("unchecked")
+ public ActivationDataFlavor(Class representationClass, String mimeType,
+ String humanPresentableName)
+ {
+ super(mimeType, humanPresentableName);
+ this.mimeType = mimeType;
+ this.humanPresentableName = humanPresentableName;
+ this.representationClass = representationClass;
+ }
+
+ /**
+ * Constructor.
+ * @param representationClass the representation class
+ * @param humanPresentableName the human-presentable name of the data
+ * flavor
+ */
+ // Raw types enforced as part of spec.
+ @SuppressWarnings("unchecked")
+ public ActivationDataFlavor(Class representationClass,
+ String humanPresentableName)
+ {
+ super(representationClass, humanPresentableName);
+ mimeType = super.getMimeType();
+ this.representationClass = representationClass;
+ this.humanPresentableName = humanPresentableName;
+ }
+
+ /**
+ * Constructor. The representation class is an InputStream.
+ * @param mimeType the MIME type of the data
+ * @param humanPresentableName the human-presentable name of the data
+ * flavor
+ */
+ public ActivationDataFlavor(String mimeType, String humanPresentableName)
+ {
+ super(mimeType, humanPresentableName);
+ this.mimeType = mimeType;
+ this.humanPresentableName = humanPresentableName;
+ representationClass = InputStream.class;
+ }
+
+ public String getMimeType()
+ {
+ return mimeType;
+ }
+
+ // Raw types enforced as part of spec.
+ @SuppressWarnings("unchecked")
+ public Class getRepresentationClass()
+ {
+ return representationClass;
+ }
+
+ public String getHumanPresentableName()
+ {
+ return humanPresentableName;
+ }
+
+ public void setHumanPresentableName(String humanPresentableName)
+ {
+ this.humanPresentableName = humanPresentableName;
+ }
+
+ public boolean equals(DataFlavor dataFlavor)
+ {
+ return (isMimeTypeEqual(dataFlavor) &&
+ dataFlavor.getRepresentationClass() == representationClass);
+ }
+
+ public boolean isMimeTypeEqual(String mimeType)
+ {
+ try
+ {
+ return new MimeType(this.mimeType).match(new MimeType(mimeType));
+ }
+ catch (MimeTypeParseException e)
+ {
+ return false;
+ }
+ }
+
+ protected String normalizeMimeTypeParameter(String parameterName,
+ String parameterValue)
+ {
+ return new CPStringBuilder(parameterName)
+ .append('=')
+ .append(parameterValue)
+ .toString();
+ }
+
+ protected String normalizeMimeType(String mimeType)
+ {
+ return mimeType;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/CommandInfo.java b/libjava/classpath/javax/activation/CommandInfo.java
new file mode 100644
index 000000000..c0b81e62c
--- /dev/null
+++ b/libjava/classpath/javax/activation/CommandInfo.java
@@ -0,0 +1,116 @@
+/* CommandInfo.java -- Description of the result of a command request.
+ 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.beans.Beans;
+import java.io.Externalizable;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Description of the result of a command request.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class CommandInfo
+{
+
+ private final String verb;
+ private final String className;
+
+ /**
+ * Constructor.
+ * @param verb the command verb
+ * @param className the command class name
+ */
+ public CommandInfo(String verb, String className)
+ {
+ this.verb = verb;
+ this.className = className;
+ }
+
+ /**
+ * Returns the command verb.
+ */
+ public String getCommandName()
+ {
+ return verb;
+ }
+
+ /**
+ * Returns the command class name.
+ */
+ public String getCommandClass()
+ {
+ return className;
+ }
+
+ /**
+ * Returns the instantiated bean.
+ * If the bean implements <code>CommandObject</code>, its
+ * <code>setCommandContext</code> method will be called.
+ * @param dh the data handler describing the command data
+ * @param loader the class loader used to instantiate the bean
+ */
+ public Object getCommandObject(DataHandler dh, ClassLoader loader)
+ throws IOException, ClassNotFoundException
+ {
+ Object object = Beans.instantiate(loader, className);
+ if (object != null)
+ {
+ if (object instanceof CommandObject)
+ {
+ CommandObject command = (CommandObject)object;
+ command.setCommandContext(verb, dh);
+ }
+ else if (dh != null && (object instanceof Externalizable))
+ {
+ InputStream in = dh.getInputStream();
+ if (in != null)
+ {
+ Externalizable externalizable = (Externalizable)object;
+ externalizable.readExternal(new ObjectInputStream(in));
+ }
+ }
+ }
+ return object;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/CommandMap.java b/libjava/classpath/javax/activation/CommandMap.java
new file mode 100644
index 000000000..dbe80a952
--- /dev/null
+++ b/libjava/classpath/javax/activation/CommandMap.java
@@ -0,0 +1,211 @@
+/* CommandMap.java -- Registry of available command objects.
+ Copyright (C) 2004, 2005 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;
+
+/**
+ * Registry of command objects available to the system.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public abstract class CommandMap
+{
+
+ /* Class scope */
+
+ private static CommandMap defaultCommandMap;
+
+ /**
+ * Returns the default command map.
+ * This returns a MailcapCommandMap if no value has been set using
+ * <code>setDefaultCommandMap</code>.
+ */
+ public static CommandMap getDefaultCommandMap()
+ {
+ if (defaultCommandMap == null)
+ {
+ defaultCommandMap = new MailcapCommandMap();
+ }
+ return defaultCommandMap;
+ }
+
+ /**
+ * Sets the default command map.
+ * @param commandMap the new default command map
+ */
+ public static void setDefaultCommandMap(CommandMap commandMap)
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ try
+ {
+ security.checkSetFactory();
+ }
+ catch (SecurityException e)
+ {
+ if (commandMap != null && CommandMap.class.getClassLoader() !=
+ commandMap.getClass().getClassLoader())
+ {
+ throw e;
+ }
+ }
+ }
+ defaultCommandMap = commandMap;
+ }
+
+ /* Instance scope */
+
+ /**
+ * Returns the list of preferred commands for a MIME type.
+ * @param mimeType the MIME type
+ */
+ public abstract CommandInfo[] getPreferredCommands(String mimeType);
+
+ /**
+ * Returns the complete list of commands for a MIME type.
+ * @param mimeType the MIME type
+ */
+ public abstract CommandInfo[] getAllCommands(String mimeType);
+
+ /**
+ * Returns the command corresponding to the specified MIME type and
+ * command name.
+ * @param mimeType the MIME type
+ * @param cmdName the command name
+ */
+ public abstract CommandInfo getCommand(String mimeType, String cmdName);
+
+ /**
+ * Returns a DataContentHandler corresponding to the MIME type.
+ * @param mimeType the MIME type
+ */
+ public abstract DataContentHandler createDataContentHandler(String mimeType);
+
+ /**
+ * Get all the MIME types known to this command map.
+ * If the command map doesn't support this operation, null is returned.
+ * @return array of MIME types as strings, or null if not supported
+ * @since JAF 1.1
+ */
+ public String[] getMimeTypes()
+ {
+ return null;
+ }
+
+ /**
+ * Get the preferred command list from a MIME Type. The actual semantics
+ * are determined by the implementation of the CommandMap.
+ * <p>
+ * The <code>DataSource</code> provides extra information, such as
+ * the file name, that a CommandMap implementation may use to further
+ * refine the list of commands that are returned. The implementation
+ * in this class simply calls the <code>getPreferredCommands</code>
+ * method that ignores this argument.
+ * @param mimeType the MIME type
+ * @param ds a DataSource for the data
+ * @return the CommandInfo classes that represent the command Beans.
+ * @since JAF 1.1
+ */
+ public CommandInfo[] getPreferredCommands(String mimeType,
+ DataSource ds)
+ {
+ return getPreferredCommands(mimeType);
+ }
+
+ /**
+ * Get all the available commands for this type. This method
+ * should return all the possible commands for this MIME type.
+ * <p>
+ * The <code>DataSource</code> provides extra information, such as
+ * the file name, that a CommandMap implementation may use to further
+ * refine the list of commands that are returned. The implementation
+ * in this class simply calls the <code>getAllCommands</code>
+ * method that ignores this argument.
+ * @param mimeType the MIME type
+ * @param ds a DataSource for the data
+ * @return the CommandInfo objects representing all the commands.
+ * @since JAF 1.1
+ */
+ public CommandInfo[] getAllCommands(String mimeType, DataSource ds)
+ {
+ return getAllCommands(mimeType);
+ }
+
+ /**
+ * Get the default command corresponding to the MIME type.
+ * <p>
+ * The <code>DataSource</code> provides extra information, such as
+ * the file name, that a CommandMap implementation may use to further
+ * refine the command that is chosen. The implementation
+ * in this class simply calls the <code>getCommand</code>
+ * method that ignores this argument.
+ * @param mimeType the MIME type
+ * @param cmdName the command name
+ * @param ds a DataSource for the data
+ * @return the CommandInfo corresponding to the command.
+ * @since JAF 1.1
+ */
+ public CommandInfo getCommand(String mimeType, String cmdName,
+ DataSource ds)
+ {
+ return getCommand(mimeType, cmdName);
+ }
+
+ /**
+ * Locate a DataContentHandler that corresponds to the MIME type.
+ * The mechanism and semantics for determining this are determined
+ * by the implementation of the particular CommandMap.
+ * <p>
+ * The <code>DataSource</code> provides extra information, such as
+ * the file name, that a CommandMap implementation may use to further
+ * refine the choice of DataContentHandler. The implementation
+ * in this class simply calls the <code>createDataContentHandler</code>
+ * method that ignores this argument.
+ * @param mimeType the MIME type
+ * @param ds a DataSource for the data
+ * @return the DataContentHandler for the MIME type
+ * @since JAF 1.1
+ */
+ public DataContentHandler createDataContentHandler(String mimeType,
+ DataSource ds)
+ {
+ return createDataContentHandler(mimeType);
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/CommandObject.java b/libjava/classpath/javax/activation/CommandObject.java
new file mode 100644
index 000000000..f89a976c7
--- /dev/null
+++ b/libjava/classpath/javax/activation/CommandObject.java
@@ -0,0 +1,61 @@
+/* CommandObject.java -- Bean interface for notifications.
+ 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.io.IOException;
+
+/**
+ * Bean interface to implement in order to receive notification of the
+ * command verb.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public interface CommandObject
+{
+
+ /**
+ * Initializes the command with the verb it is expected to perform and
+ * the data handler describing the data to operate on.
+ * @param verb the command verb
+ * @param dh the data handler describing the data to process
+ */
+ void setCommandContext(String verb, DataHandler dh)
+ throws IOException;
+
+}
diff --git a/libjava/classpath/javax/activation/DataContentHandler.java b/libjava/classpath/javax/activation/DataContentHandler.java
new file mode 100644
index 000000000..be919c231
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataContentHandler.java
@@ -0,0 +1,84 @@
+/* DataContentHandler.java -- Converts streams to objects and vice versa.
+ 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.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Provider that can convert streams to objects and vice versa.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public interface DataContentHandler
+{
+
+ /**
+ * Returns a list of the flavors that data can be provided in, ordered
+ * by preference.
+ */
+ DataFlavor[] getTransferDataFlavors();
+
+ /**
+ * Returns an object representing the data to be transferred.
+ * @param df the flavor representing the requested type
+ * @param ds the data source of the data to be converted
+ */
+ Object getTransferData(DataFlavor df, DataSource ds)
+ throws UnsupportedFlavorException, IOException;
+
+ /**
+ * Returns an object representing the data in its most preferred form.
+ * @param ds the data source of the data to be converted
+ */
+ Object getContent(DataSource ds)
+ throws IOException;
+
+ /**
+ * Writes the object as a stream of bytes.
+ * @param obj the object to convert
+ * @param mimeType the MIME type of the stream
+ * @param os the byte stream
+ */
+ void writeTo(Object obj, String mimeType, OutputStream os)
+ throws IOException;
+
+}
diff --git a/libjava/classpath/javax/activation/DataContentHandlerFactory.java b/libjava/classpath/javax/activation/DataContentHandlerFactory.java
new file mode 100644
index 000000000..815c1a9a4
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataContentHandlerFactory.java
@@ -0,0 +1,55 @@
+/* DataContentHandlerFactory.java -- Factory for creating DataContentHandlers.
+ 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;
+
+/**
+ * Factory interface for creating data content handlers.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public interface DataContentHandlerFactory
+{
+
+ /**
+ * Returns a new data content handler for the specified MIME type.
+ * @param mimeType the MIME type
+ */
+ DataContentHandler createDataContentHandler(String mimeType);
+
+}
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;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/DataHandlerDataSource.java b/libjava/classpath/javax/activation/DataHandlerDataSource.java
new file mode 100644
index 000000000..9781b3950
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataHandlerDataSource.java
@@ -0,0 +1,83 @@
+/* DataHandlerDataSource.java -- Data source proxy for a DataHandler.
+ 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.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Data source that is a proxy for a data handler.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+final class DataHandlerDataSource
+ implements DataSource
+{
+
+ final DataHandler dh;
+
+ DataHandlerDataSource(DataHandler dh)
+ {
+ this.dh = dh;
+ }
+
+ public String getContentType()
+ {
+ return dh.getContentType();
+ }
+
+ public InputStream getInputStream()
+ throws IOException
+ {
+ return dh.getInputStream();
+ }
+
+ public String getName()
+ {
+ return dh.getName();
+ }
+
+ public OutputStream getOutputStream()
+ throws IOException
+ {
+ return dh.getOutputStream();
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/DataSource.java b/libjava/classpath/javax/activation/DataSource.java
new file mode 100644
index 000000000..c4da9d3af
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataSource.java
@@ -0,0 +1,75 @@
+/* DataSource.java -- An interface for MIME data storage and retrieval.
+ 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.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An interface by which MIME data can be retrieved and stored.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public interface DataSource
+{
+
+ /**
+ * Returns an input stream from which the data can be read.
+ */
+ InputStream getInputStream()
+ throws IOException;
+
+ /**
+ * Returns an output stream to which the data can be written.
+ */
+ OutputStream getOutputStream()
+ throws IOException;
+
+ /**
+ * Returns the MIME content type of the data.
+ */
+ String getContentType();
+
+ /**
+ * Returns the underlying name of this object.
+ */
+ String getName();
+
+}
diff --git a/libjava/classpath/javax/activation/DataSourceDataContentHandler.java b/libjava/classpath/javax/activation/DataSourceDataContentHandler.java
new file mode 100644
index 000000000..8b16fd150
--- /dev/null
+++ b/libjava/classpath/javax/activation/DataSourceDataContentHandler.java
@@ -0,0 +1,125 @@
+/* DataSourceDataContentHolder.java -- DCH using an existing data source.
+ 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.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Data content handler using an existing DCH and a data source.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+class DataSourceDataContentHandler
+ implements DataContentHandler
+{
+
+ private DataSource ds;
+ private DataFlavor[] flavors;
+ private DataContentHandler dch;
+
+ public DataSourceDataContentHandler(DataContentHandler dch, DataSource ds)
+ {
+ this.ds = ds;
+ this.dch = dch;
+ }
+
+ public Object getContent(DataSource ds)
+ throws IOException
+ {
+ if (dch != null)
+ {
+ return dch.getContent(ds);
+ }
+ else
+ {
+ return ds.getInputStream();
+ }
+ }
+
+ public Object getTransferData(DataFlavor flavor, DataSource ds)
+ throws UnsupportedFlavorException, IOException
+ {
+ if (dch != null)
+ {
+ return dch.getTransferData(flavor, ds);
+ }
+ DataFlavor[] tdf = getTransferDataFlavors();
+ if (tdf.length > 0 && flavor.equals(tdf[0]))
+ {
+ return ds.getInputStream();
+ }
+ else
+ {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ }
+
+ public DataFlavor[] getTransferDataFlavors()
+ {
+ if (flavors == null)
+ {
+ if (dch != null)
+ {
+ flavors = dch.getTransferDataFlavors();
+ }
+ else
+ {
+ String mimeType = ds.getContentType();
+ flavors = new DataFlavor[1];
+ flavors[0] = new ActivationDataFlavor(mimeType, mimeType);
+ }
+ }
+ return flavors;
+ }
+
+ public void writeTo(Object obj, String mimeType, OutputStream out)
+ throws IOException
+ {
+ if (dch == null)
+ {
+ throw new UnsupportedDataTypeException("no DCH for content type " +
+ ds.getContentType());
+ }
+ dch.writeTo(obj, mimeType, out);
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/FileDataSource.java b/libjava/classpath/javax/activation/FileDataSource.java
new file mode 100644
index 000000000..72ef066d9
--- /dev/null
+++ b/libjava/classpath/javax/activation/FileDataSource.java
@@ -0,0 +1,122 @@
+/* FileDataSource.java -- Data source for a File object.
+ 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.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Data source encapsulating a file.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class FileDataSource
+ implements DataSource
+{
+
+ private final File file;
+ private FileTypeMap typeMap;
+
+ /**
+ * Constructor.
+ * @param file the underlying file to use
+ */
+ public FileDataSource(File file)
+ {
+ this.file = file;
+ }
+
+ /**
+ * Constructor.
+ * @param name the path to the underlying file to use
+ */
+ public FileDataSource(String name)
+ {
+ this(new File(name));
+ }
+
+ public InputStream getInputStream()
+ throws IOException
+ {
+ return new FileInputStream(file);
+ }
+
+ public OutputStream getOutputStream()
+ throws IOException
+ {
+ return new FileOutputStream(file);
+ }
+
+ public String getContentType()
+ {
+ if (typeMap == null)
+ {
+ FileTypeMap dftm = FileTypeMap.getDefaultFileTypeMap();
+ return dftm.getContentType(file);
+ }
+ return typeMap.getContentType(file);
+ }
+
+ public String getName()
+ {
+ return file.getName();
+ }
+
+ /**
+ * Returns the underlying file.
+ */
+ public File getFile()
+ {
+ return file;
+ }
+
+ /**
+ * Sets the file type map to use to determine the content type of the file.
+ * @param map the file type map
+ */
+ public void setFileTypeMap(FileTypeMap map)
+ {
+ typeMap = map;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/FileTypeMap.java b/libjava/classpath/javax/activation/FileTypeMap.java
new file mode 100644
index 000000000..bbd088c1c
--- /dev/null
+++ b/libjava/classpath/javax/activation/FileTypeMap.java
@@ -0,0 +1,107 @@
+/* FileTypeMap.java -- Classifies the MIME content of files.
+ 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.io.File;
+
+/**
+ * Classifier for the MIME content type of files.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public abstract class FileTypeMap
+{
+
+ /* Class scope */
+
+ private static FileTypeMap defaultMap;
+
+ /**
+ * Returns the system default file type map.
+ * If one has not been set, this returns a MimetypesFileTypeMap.
+ */
+ public static FileTypeMap getDefaultFileTypeMap()
+ {
+ if (defaultMap == null)
+ {
+ defaultMap = new MimetypesFileTypeMap();
+ }
+ return defaultMap;
+ }
+
+ /**
+ * Sets the default file type map.
+ * @param map the new file type map
+ */
+ public static void setDefaultFileTypeMap(FileTypeMap map)
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ try
+ {
+ security.checkSetFactory();
+ }
+ catch (SecurityException e)
+ {
+ if (map != null && FileTypeMap.class.getClassLoader() !=
+ map.getClass().getClassLoader())
+ {
+ throw e;
+ }
+ }
+ }
+ defaultMap = map;
+ }
+
+ /* Instance scope */
+
+ /**
+ * Returns the content type of the specified file.
+ * @param file the file to classify
+ */
+ public abstract String getContentType(File file);
+
+ /**
+ * Returns the content type of the specified file path.
+ * @param filename the path of the file to classify
+ */
+ public abstract String getContentType(String filename);
+
+}
diff --git a/libjava/classpath/javax/activation/MailcapCommandMap.java b/libjava/classpath/javax/activation/MailcapCommandMap.java
new file mode 100644
index 000000000..48b1bbb08
--- /dev/null
+++ b/libjava/classpath/javax/activation/MailcapCommandMap.java
@@ -0,0 +1,803 @@
+/* MailcapCommandMap.java -- Command map implementation using a mailcap file.
+ 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 gnu.java.lang.CPStringBuilder;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of a command map using a <code>mailcap</code> file (RFC
+ * 1524). Mailcap files are searched for in the following places:
+ * <ol>
+ * <li>Programmatically added entries to this interface</li>
+ * <li>the file <tt>.mailcap</tt> in the user's home directory</li>
+ * <li>the file <i>&lt;java.home&gt;</i><tt>/lib/mailcap</tt></li>
+ * <li>the resource <tt>META-INF/mailcap</tt></li>
+ * <li>the resource <tt>META-INF/mailcap.default</tt> in the JAF
+ * distribution</li>
+ * </ol>
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class MailcapCommandMap
+ extends CommandMap
+{
+
+ private static final int PROG = 0;
+ private static final int HOME = 1;
+ private static final int SYS = 2;
+ private static final int JAR = 3;
+ private static final int DEF = 4;
+ private static boolean debug = false;
+ private static final int NORMAL = 0;
+ private static final int FALLBACK = 1;
+
+ static
+ {
+ try
+ {
+ String d = System.getProperty("javax.activation.debug");
+ debug = Boolean.valueOf(d).booleanValue();
+ }
+ catch (SecurityException e)
+ {
+ }
+ }
+
+ private Map<String,Map<String,List<String>>>[][] mailcaps;
+
+ /**
+ * Default constructor.
+ */
+ public MailcapCommandMap()
+ {
+ init(null);
+ }
+
+ /**
+ * Constructor specifying a filename.
+ * @param fileName the name of the file to read mailcap entries from
+ */
+ public MailcapCommandMap(String fileName)
+ throws IOException
+ {
+ Reader in = null;
+ try
+ {
+ in = new FileReader(fileName);
+ }
+ catch (IOException e)
+ {
+ }
+ init(in);
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Constructor specifying an input stream.
+ * @param is the input stream to read mailcap entries from
+ */
+ public MailcapCommandMap(InputStream is)
+ {
+ init(new InputStreamReader(is));
+ }
+
+ private void init(Reader in)
+ {
+ mailcaps = new Map[5][2];
+ for (int i = 0; i < 5; i++)
+ {
+ for (int j = 0; j < 2; j++)
+ {
+ mailcaps[i][j] =
+ new LinkedHashMap<String,Map<String,List<String>>>();
+ }
+ }
+ if (in != null)
+ {
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: load PROG");
+ }
+ try
+ {
+ parse(PROG, in);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: load HOME");
+ }
+ try
+ {
+ String home = System.getProperty("user.home");
+ if (home != null)
+ {
+ parseFile(HOME, new CPStringBuilder(home)
+ .append(File.separatorChar)
+ .append(".mailcap")
+ .toString());
+ }
+ }
+ catch (SecurityException e)
+ {
+ }
+
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: load SYS");
+ }
+ try
+ {
+ parseFile(SYS,
+ new CPStringBuilder(System.getProperty("java.home"))
+ .append(File.separatorChar)
+ .append("lib")
+ .append(File.separatorChar)
+ .append("mailcap")
+ .toString());
+ }
+ catch (SecurityException e)
+ {
+ }
+
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: load JAR");
+ }
+ List<URL> systemResources = getSystemResources("META-INF/mailcap");
+ int len = systemResources.size();
+ if (len > 0)
+ {
+ for (int i = 0; i < len ; i++)
+ {
+ Reader urlIn = null;
+ URL url = systemResources.get(i);
+ try
+ {
+ if (debug)
+ {
+ System.out.println("\t" + url.toString());
+ }
+ urlIn = new InputStreamReader(url.openStream());
+ parse(JAR, urlIn);
+ }
+ catch (IOException e)
+ {
+ if (debug)
+ {
+ System.out.println(e.getClass().getName() + ": " +
+ e.getMessage());
+ }
+ }
+ finally
+ {
+ if (urlIn != null)
+ {
+ try
+ {
+ urlIn.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ parseResource(JAR, "/META-INF/mailcap");
+ }
+
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: load DEF");
+ }
+ parseResource(DEF, "/META-INF/mailcap.default");
+ }
+
+ /**
+ * Returns the list of preferred commands for a given MIME type.
+ * @param mimeType the MIME type
+ */
+ public synchronized CommandInfo[] getPreferredCommands(String mimeType)
+ {
+ List<CommandInfo> cmdList = new ArrayList<CommandInfo>();
+ List<String> verbList = new ArrayList<String>();
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
+ if (map != null)
+ {
+ for (Map.Entry<String,List<String>> entry : map.entrySet())
+ {
+ String verb = entry.getKey();
+ if (!verbList.contains(verb))
+ {
+ List<String> classNames = entry.getValue();
+ String className = classNames.get(0);
+ CommandInfo cmd = new CommandInfo(verb, className);
+ cmdList.add(cmd);
+ verbList.add(verb);
+ }
+ }
+ }
+ }
+ }
+ CommandInfo[] cmds = new CommandInfo[cmdList.size()];
+ cmdList.toArray(cmds);
+ return cmds;
+ }
+
+ /**
+ * Returns all commands for the given MIME type.
+ * @param mimeType the MIME type
+ */
+ public synchronized CommandInfo[] getAllCommands(String mimeType)
+ {
+ List<CommandInfo> cmdList = new ArrayList<CommandInfo>();
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
+ if (map != null)
+ {
+ for (Map.Entry<String,List<String>> entry : map.entrySet())
+ {
+ String verb = entry.getKey();
+ List<String> classNames = entry.getValue();
+ int len = classNames.size();
+ for (int l = 0; l < len; l++)
+ {
+ String className = classNames.get(l);
+ CommandInfo cmd = new CommandInfo(verb, className);
+ cmdList.add(cmd);
+ }
+ }
+ }
+ }
+ }
+ CommandInfo[] cmds = new CommandInfo[cmdList.size()];
+ cmdList.toArray(cmds);
+ return cmds;
+ }
+
+ /**
+ * Returns the command with the specified name for the given MIME type.
+ * @param mimeType the MIME type
+ * @param cmdName the command verb
+ */
+ public synchronized CommandInfo getCommand(String mimeType,
+ String cmdName)
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ Map<String,List<String>> map =
+ getCommands(mailcaps[j][i], mimeType);
+ if (map != null)
+ {
+ List<String> classNames = map.get(cmdName);
+ if (classNames == null)
+ {
+ classNames = map.get("x-java-" + cmdName);
+ }
+ if (classNames != null)
+ {
+ String className = classNames.get(0);
+ return new CommandInfo(cmdName, className);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Adds entries programmatically to the registry.
+ * @param mailcap a mailcap string
+ */
+ public synchronized void addMailcap(String mailcap)
+ {
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: add to PROG");
+ }
+ try
+ {
+ parse(PROG, new StringReader(mailcap));
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ /**
+ * Returns the DCH for the specified MIME type.
+ * @param mimeType the MIME type
+ */
+ public synchronized DataContentHandler
+ createDataContentHandler(String mimeType)
+ {
+ if (debug)
+ {
+ System.out.println("MailcapCommandMap: " +
+ "createDataContentHandler for " + mimeType);
+ }
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ if (debug)
+ {
+ System.out.println(" search DB #" + i);
+ }
+ Map<String,List<String>> map = getCommands(mailcaps[j][i], mimeType);
+ if (map != null)
+ {
+ List<String> classNames = map.get("content-handler");
+ if (classNames == null)
+ {
+ classNames = map.get("x-java-content-handler");
+ }
+ if (classNames != null)
+ {
+ String className = classNames.get(0);
+ if (debug)
+ {
+ System.out.println(" In " + nameOf(j) +
+ ", content-handler=" + className);
+ }
+ try
+ {
+ Class<?> clazz = Class.forName(className);
+ return (DataContentHandler)clazz.newInstance();
+ }
+ catch (IllegalAccessException e)
+ {
+ if (debug)
+ {
+ e.printStackTrace();
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ if (debug)
+ {
+ e.printStackTrace();
+ }
+ }
+ catch (InstantiationException e)
+ {
+ if (debug)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the native commands for the given MIME type.
+ * Returns an array of strings where each string is
+ * an entire mailcap file entry. The application
+ * will need to parse the entry to extract the actual
+ * command as well as any attributes it needs. See
+ * <a href="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</a>
+ * for details of the mailcap entry syntax. Only mailcap
+ * entries that specify a view command for the specified
+ * MIME type are returned.
+ * @return array of native command entries
+ * @since JAF 1.1
+ */
+ public String[] getNativeCommands(String mimeType)
+ {
+ List<String> acc = new ArrayList<String>();
+ for (int i = 0; i < 2; i++)
+ {
+ for (int j = 0; j < 5; j++)
+ {
+ addNativeCommands(acc, mailcaps[j][i], mimeType);
+ }
+ }
+ String[] ret = new String[acc.size()];
+ acc.toArray(ret);
+ return ret;
+ }
+
+ private void addNativeCommands(List<String> acc,
+ Map<String,Map<String,List<String>>> mailcap,
+ String mimeType)
+ {
+ for (Map.Entry<String,Map<String,List<String>>> mEntry : mailcap.entrySet())
+ {
+ String entryMimeType = mEntry.getKey();
+ if (!entryMimeType.equals(mimeType))
+ {
+ continue;
+ }
+ Map<String,List<String>> commands = mEntry.getValue();
+ String viewCommand = commands.get("view-command").get(0);
+ if (viewCommand == null)
+ {
+ continue;
+ }
+ CPStringBuilder buf = new CPStringBuilder();
+ buf.append(mimeType);
+ buf.append(';');
+ buf.append(' ');
+ buf.append(viewCommand);
+ for (Map.Entry<String,List<String>> cEntry : commands.entrySet())
+ {
+ String verb = cEntry.getKey();
+ List<String> classNames = cEntry.getValue();
+ if (!"view-command".equals(verb))
+ {
+ for (String command : classNames)
+ {
+ buf.append(';');
+ buf.append(' ');
+ buf.append(verb);
+ buf.append('=');
+ buf.append(command);
+ }
+ }
+ }
+ if (buf.length() > 0)
+ {
+ acc.add(buf.toString());
+ }
+ }
+ }
+
+ private static String nameOf(int mailcap)
+ {
+ switch (mailcap)
+ {
+ case PROG:
+ return "PROG";
+ case HOME:
+ return "HOME";
+ case SYS:
+ return "SYS";
+ case JAR:
+ return "JAR";
+ case DEF:
+ return "DEF";
+ default:
+ return "ERR";
+ }
+ }
+
+ private void parseFile(int index, String filename)
+ {
+ Reader in = null;
+ try
+ {
+ if (debug)
+ {
+ System.out.println("\t" + filename);
+ }
+ in = new FileReader(filename);
+ parse(index, in);
+ }
+ catch (IOException e)
+ {
+ if (debug)
+ {
+ System.out.println(e.getClass().getName() + ": " +
+ e.getMessage());
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+
+ private void parseResource(int index, String name)
+ {
+ Reader in = null;
+ try
+ {
+ InputStream is = getClass().getResourceAsStream(name);
+ if (is != null)
+ {
+ if (debug)
+ {
+ System.out.println("\t" + name);
+ }
+ in = new InputStreamReader(is);
+ parse(index, in);
+ }
+ }
+ catch (IOException e)
+ {
+ if (debug)
+ {
+ System.out.println(e.getClass().getName() + ": " +
+ e.getMessage());
+ }
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+
+ private void parse(int index, Reader in)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(in);
+ CPStringBuilder buf = null;
+ for (String line = br.readLine(); line != null; line = br.readLine())
+ {
+ line = line.trim();
+ int len = line.length();
+ if (len == 0 || line.charAt(0) == '#')
+ {
+ continue; // Comment
+ }
+ if (line.charAt(len - 1) == '\\')
+ {
+ if (buf == null)
+ {
+ buf = new CPStringBuilder();
+ }
+ buf.append(line.substring(0, len - 1));
+ }
+ else if (buf != null)
+ {
+ buf.append(line);
+ parseEntry(index, buf.toString());
+ buf = null;
+ }
+ else
+ {
+ parseEntry(index, line);
+ }
+ }
+ }
+
+ private void parseEntry(int index, String line)
+ {
+ // Tokenize entry into fields
+ char[] chars = line.toCharArray();
+ int len = chars.length;
+ boolean inQuotedString = false;
+ boolean fallback = false;
+ CPStringBuilder buffer = new CPStringBuilder();
+ List<String> fields = new ArrayList<String>();
+ for (int i = 0; i < len; i++)
+ {
+ char c = chars[i];
+ if (c == '\\')
+ {
+ c = chars[++i]; // qchar
+ }
+ if (c == ';' && !inQuotedString)
+ {
+ String field = buffer.toString().trim();
+ if ("x-java-fallback-entry".equals(field))
+ {
+ fallback = true;
+ }
+ fields.add(field);
+ buffer.setLength(0);
+ }
+ else
+ {
+ if (c == '"')
+ {
+ inQuotedString = !inQuotedString;
+ }
+ buffer.append(c);
+ }
+ }
+ String field = buffer.toString().trim();
+ if ("x-java-fallback-entry".equals(field))
+ {
+ fallback = true;
+ }
+ fields.add(field);
+
+ len = fields.size();
+ if (len < 2)
+ {
+ if (debug)
+ {
+ System.err.println("Invalid mailcap entry: " + line);
+ }
+ return;
+ }
+
+ Map<String,Map<String,List<String>>> mailcap =
+ fallback ? mailcaps[index][FALLBACK] : mailcaps[index][NORMAL];
+ String mimeType = fields.get(0);
+ addField(mailcap, mimeType, "view-command", (String) fields.get(1));
+ for (int i = 2; i < len; i++)
+ {
+ addField(mailcap, mimeType, null, (String) fields.get(i));
+ }
+ }
+
+ private void addField(Map<String,Map<String,List<String>>> mailcap,
+ String mimeType, String verb, String command)
+ {
+ if (verb == null)
+ {
+ int ei = command.indexOf('=');
+ if (ei != -1)
+ {
+ verb = command.substring(0, ei);
+ command = command.substring(ei + 1);
+ }
+ }
+ if (command.length() == 0 || verb == null || verb.length() == 0)
+ {
+ return; // Invalid field or flag
+ }
+
+ Map<String,List<String>> commands = mailcap.get(mimeType);
+ if (commands == null)
+ {
+ commands = new LinkedHashMap<String,List<String>>();
+ mailcap.put(mimeType, commands);
+ }
+ List<String> classNames = commands.get(verb);
+ if (classNames == null)
+ {
+ classNames = new ArrayList<String>();
+ commands.put(verb, classNames);
+ }
+ classNames.add(command);
+ }
+
+ private Map<String,List<String>>
+ getCommands(Map<String,Map<String,List<String>>> mailcap,
+ String mimeType)
+ {
+ int si = mimeType.indexOf('/');
+ String genericMimeType = new CPStringBuilder(mimeType.substring(0, si))
+ .append('/')
+ .append('*')
+ .toString();
+ Map<String,List<String>> specific = mailcap.get(mimeType);
+ Map<String,List<String>> generic = mailcap.get(genericMimeType);
+ if (generic == null)
+ {
+ return specific;
+ }
+ if (specific == null)
+ {
+ return generic;
+ }
+ Map<String,List<String>> combined = new LinkedHashMap<String,List<String>>();
+ combined.putAll(specific);
+ for (String verb : generic.keySet())
+ {
+ List<String> genericClassNames = generic.get(verb);
+ List<String> classNames = combined.get(verb);
+ if (classNames == null)
+ {
+ combined.put(verb, genericClassNames);
+ }
+ else
+ {
+ classNames.addAll(genericClassNames);
+ }
+ }
+ return combined;
+ }
+
+ // -- Utility methods --
+
+ private List<URL> getSystemResources(String name)
+ {
+ List<URL> acc = new ArrayList<URL>();
+ try
+ {
+ for (Enumeration<URL> i = ClassLoader.getSystemResources(name);
+ i.hasMoreElements(); )
+ {
+ acc.add(i.nextElement());
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ return acc;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/MimeType.java b/libjava/classpath/javax/activation/MimeType.java
new file mode 100644
index 000000000..bc3afc18e
--- /dev/null
+++ b/libjava/classpath/javax/activation/MimeType.java
@@ -0,0 +1,292 @@
+/* MimeType.java -- A MIME type as defined in RFC2046 and RFC2047.
+ 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 gnu.java.lang.CPStringBuilder;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+/**
+ * A MIME content type, as defined in RFCs 2045 and 2046.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class MimeType
+ implements Externalizable
+{
+
+ static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
+
+ private String primaryType;
+ private String subType;
+ private MimeTypeParameterList parameters;
+
+ /**
+ * Constructor for an <code>application/*</code> content type.
+ */
+ public MimeType()
+ {
+ primaryType = "application";
+ subType = "*";
+ parameters = new MimeTypeParameterList();
+ }
+
+ /**
+ * Constructor that parses a raw String.
+ * @param rawdata the MIME type string
+ */
+ public MimeType(String rawdata)
+ throws MimeTypeParseException
+ {
+ parse(rawdata);
+ }
+
+ /**
+ * Constructor for a new MIME type with the given primary and sub types
+ * and an empty parameter list.
+ * @param primary the primary type
+ * @param sub the subtype
+ */
+ public MimeType(String primary, String sub)
+ throws MimeTypeParseException
+ {
+ checkValidity(primary, "Primary type is invalid");
+ checkValidity(sub, "Sub type is invalid");
+ primaryType = primary.toLowerCase();
+ subType = sub.toLowerCase();
+ parameters = new MimeTypeParameterList();
+ }
+
+ /**
+ * Returns the primary type.
+ */
+ public String getPrimaryType()
+ {
+ return primaryType;
+ }
+
+ /**
+ * Sets the primary type.
+ * @param primary the new primary type
+ */
+ public void setPrimaryType(String primary)
+ throws MimeTypeParseException
+ {
+ checkValidity(primary, "Primary type is invalid");
+ primaryType = primary.toLowerCase();
+ }
+
+ /**
+ * Returns the subtype.
+ */
+ public String getSubType()
+ {
+ return subType;
+ }
+
+ /**
+ * Sets the subtype.
+ * @param sub the new subtype
+ */
+ public void setSubType(String sub)
+ throws MimeTypeParseException
+ {
+ checkValidity(sub, "Sub type is invalid");
+ subType = sub.toLowerCase();
+ }
+
+ /**
+ * Returns the MIME parameters.
+ */
+ public MimeTypeParameterList getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * Returns the parameter value for the specified name.
+ * @param name the parameter name
+ */
+ public String getParameter(String name)
+ {
+ return parameters.get(name);
+ }
+
+ /**
+ * Sets the parameter value for the specified name.
+ * @param name the parameter name
+ * @param value the new value
+ */
+ public void setParameter(String name, String value)
+ {
+ parameters.set(name, value);
+ }
+
+ /**
+ * Removes the parameter value for the specified name.
+ * @param name the parameter name
+ */
+ public void removeParameter(String name)
+ {
+ parameters.remove(name);
+ }
+
+ /**
+ * Returns the complete string representation of this MIME type.
+ */
+ public String toString()
+ {
+ return new CPStringBuilder(primaryType)
+ .append('/')
+ .append(subType)
+ .append(parameters.toString())
+ .toString();
+ }
+
+ /**
+ * Returns the string representation of this MIME type without
+ * parameters.
+ */
+ public String getBaseType()
+ {
+ return new CPStringBuilder(primaryType)
+ .append('/')
+ .append(subType)
+ .toString();
+ }
+
+ /**
+ * Returns true if the primary and subtype of this MIME type are the
+ * same as in the given MIME type.
+ */
+ public boolean match(MimeType type)
+ {
+ String primary2 = type.getPrimaryType();
+ String sub2 = type.getSubType();
+ return primaryType.equals(primary2) && (subType.equals(sub2) ||
+ "*".equals(subType) ||
+ "*".equals(sub2));
+ }
+
+ /**
+ * Returns true if the primary and subtype of this MIME type are the
+ * same as in the given MIME type string.
+ */
+ public boolean match(String rawdata)
+ throws MimeTypeParseException
+ {
+ return match(new MimeType(rawdata));
+ }
+
+ public void writeExternal(ObjectOutput out)
+ throws IOException
+ {
+ out.writeUTF(toString());
+ out.flush();
+ }
+
+ public void readExternal(ObjectInput in)
+ throws IOException, ClassNotFoundException
+ {
+ try
+ {
+ parse(in.readUTF());
+ }
+ catch (MimeTypeParseException e)
+ {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ private void parse(String rawdata)
+ throws MimeTypeParseException
+ {
+ int si = rawdata.indexOf('/');
+ int pi = rawdata.indexOf(';');
+ if (si == -1)
+ {
+ throw new MimeTypeParseException("Unable to find a sub type.");
+ }
+ if (pi == -1)
+ {
+ primaryType = rawdata.substring(0, si).toLowerCase().trim();
+ subType = rawdata.substring(si + 1).toLowerCase().trim();
+ parameters = new MimeTypeParameterList();
+ }
+ else if (si < pi)
+ {
+ primaryType = rawdata.substring(0, si).toLowerCase().trim();
+ subType = rawdata.substring(si + 1, pi).toLowerCase().trim();
+ parameters = new MimeTypeParameterList(rawdata.substring(pi));
+ }
+ else
+ {
+ throw new MimeTypeParseException("Unable to find a sub type.");
+ }
+ checkValidity(primaryType, "Primary type is invalid");
+ checkValidity(subType, "Sub type is invalid");
+ }
+
+ static void checkValidity(String token, String message)
+ throws MimeTypeParseException
+ {
+ int len = token.length();
+ if (len == 0)
+ {
+ throw new MimeTypeParseException(message, token);
+ }
+ for (int i = 0; i < len; i++)
+ {
+ char c = token.charAt(i);
+ if (!isValidChar(c))
+ {
+ throw new MimeTypeParseException(message, token);
+ }
+ }
+ }
+
+ static boolean isValidChar(char c)
+ {
+ return c > ' ' && c <= '~' && TSPECIALS.indexOf(c) == -1;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/MimeTypeParameterList.java b/libjava/classpath/javax/activation/MimeTypeParameterList.java
new file mode 100644
index 000000000..3d36ede94
--- /dev/null
+++ b/libjava/classpath/javax/activation/MimeTypeParameterList.java
@@ -0,0 +1,335 @@
+/* MimeTypeParameterList.java -- Handle a list of MIME type parameters.
+ 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 gnu.java.lang.CPStringBuilder;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A list of MIME type parameters, as specified in RFCs 2045 and 2046.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class MimeTypeParameterList
+{
+
+ private final List<String> parameterNames;
+ private final Map<String,String> parameterValues;
+
+ /**
+ * Constructor for an empty parameter list.
+ */
+ public MimeTypeParameterList()
+ {
+ parameterNames = new ArrayList<String>();
+ parameterValues = new HashMap<String,String>();
+ }
+
+ /**
+ * Constructor that parses the specified MIME parameter data.
+ * @param parameterList a MIME parameter list string representation
+ */
+ public MimeTypeParameterList(String parameterList)
+ throws MimeTypeParseException
+ {
+ this();
+ parse(parameterList);
+ }
+
+ /**
+ * Parses the specified MIME parameter data, storing the results in this
+ * object.
+ * @param parameterList a MIME parameter list string representation
+ */
+ protected void parse(String parameterList)
+ throws MimeTypeParseException
+ {
+ if (parameterList == null)
+ {
+ return;
+ }
+ // Tokenize list into parameters
+ char[] chars = parameterList.toCharArray();
+ int len = chars.length;
+ boolean inQuotedString = false;
+ CPStringBuilder buffer = new CPStringBuilder();
+ List<String> params = new ArrayList<String>();
+ for (int i = 0; i < len; i++)
+ {
+ char c = chars[i];
+ if (c == ';' && !inQuotedString)
+ {
+ String param = buffer.toString().trim();
+ if (param.length() > 0)
+ {
+ params.add(param);
+ }
+ buffer.setLength(0);
+ }
+ else
+ {
+ if (c == '"')
+ {
+ inQuotedString = !inQuotedString;
+ }
+ buffer.append(c);
+ }
+ }
+ String param = buffer.toString().trim();
+ if (param.length() > 0)
+ {
+ params.add(param);
+ }
+
+ // Tokenize each parameter into name + value
+ for (Iterator<String> i = params.iterator(); i.hasNext();)
+ {
+ param = i.next();
+ int ei = param.indexOf('=');
+ if (ei == -1)
+ {
+ throw new MimeTypeParseException("Couldn't find the '=' that " +
+ "separates a parameter name " +
+ "from its value.");
+ }
+ String name = param.substring(0, ei).trim();
+ MimeType.checkValidity(name, "Parameter name is invalid");
+ String value = param.substring(ei + 1).trim();
+ len = value.length();
+ if (len > 1 && value.charAt(0) == '"' &&
+ value.charAt(len - 1) == '"')
+ {
+ value = unquote(value);
+ }
+ else
+ {
+ MimeType.checkValidity(name, "Parameter value is invalid");
+ }
+
+ parameterNames.add(name);
+ parameterValues.put(name.toLowerCase(), value);
+ }
+ }
+
+ /**
+ * Returns the number of parameters.
+ */
+ public synchronized int size()
+ {
+ return parameterNames.size();
+ }
+
+ /**
+ * Indicates if there are no parameters.
+ */
+ public synchronized boolean isEmpty()
+ {
+ return parameterNames.isEmpty();
+ }
+
+ /**
+ * Returns the value for the specified parameter name.
+ * @param name the parameter name
+ */
+ public synchronized String get(String name)
+ {
+ name = name.trim();
+ return parameterValues.get(name.toLowerCase());
+ }
+
+ /**
+ * Sets the value for the specified parameter name.
+ * @param name the parameter name
+ * @param value the parameter value
+ */
+ public synchronized void set(String name, String value)
+ {
+ name = name.trim();
+ boolean exists = false;
+ for (String pname : parameterNames)
+ {
+ if (name.equalsIgnoreCase(pname))
+ {
+ exists = true;
+ }
+ }
+ if (!exists)
+ {
+ parameterNames.add(name);
+ }
+ parameterValues.put(name.toLowerCase(), value);
+ }
+
+ /**
+ * Removes the parameter identified by the specified name.
+ * @param name the parameter name
+ */
+ public synchronized void remove(String name)
+ {
+ name = name.trim();
+ for (Iterator<String> i = parameterNames.iterator();i.hasNext();)
+ {
+ String pname = i.next();
+ if (name.equalsIgnoreCase(pname))
+ {
+ i.remove();
+ }
+ }
+ parameterValues.remove(name.toLowerCase());
+ }
+
+ /**
+ * Returns an enumeration of all the parameter names.
+ */
+ // Raw type is forced by public spec.
+ @SuppressWarnings("unchecked")
+ public synchronized Enumeration getNames()
+ {
+ return new IteratorEnumeration(parameterNames.iterator());
+ }
+
+ /**
+ * Returns an RFC 2045-compliant string representation of this parameter
+ * list.
+ */
+ public synchronized String toString()
+ {
+ CPStringBuilder buffer = new CPStringBuilder();
+ for (String name : parameterNames)
+ {
+ String value = parameterValues.get(name.toLowerCase());
+
+ buffer.append(';');
+ buffer.append(' ');
+ buffer.append(name);
+ buffer.append('=');
+ buffer.append(quote(value));
+ }
+ return buffer.toString();
+ }
+
+ private static String quote(String value)
+ {
+ boolean needsQuoting = false;
+ int len = value.length();
+ for (int i = 0; i < len; i++)
+ {
+ if (!MimeType.isValidChar(value.charAt(i)))
+ {
+ needsQuoting = true;
+ break;
+ }
+ }
+
+ if (needsQuoting)
+ {
+ CPStringBuilder buffer = new CPStringBuilder();
+ buffer.append('"');
+ for (int i = 0; i < len; i++)
+ {
+ char c = value.charAt(i);
+ if (c == '\\' || c == '"')
+ {
+ buffer.append('\\');
+ }
+ buffer.append(c);
+ }
+ buffer.append('"');
+ return buffer.toString();
+ }
+ return value;
+ }
+
+ private static String unquote(String value)
+ {
+ int len = value.length();
+ CPStringBuilder buffer = new CPStringBuilder();
+ for (int i = 1; i < len - 1; i++)
+ {
+ char c = value.charAt(i);
+ if (c == '\\')
+ {
+ i++;
+ if (i < len - 1)
+ {
+ c = value.charAt(i);
+ if (c != '\\' && c != '"')
+ {
+ buffer.append('\\');
+ }
+ }
+ }
+ buffer.append(c);
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Enumeration proxy for an Iterator.
+ */
+ static class IteratorEnumeration
+ implements Enumeration<String>
+ {
+
+ final Iterator<String> iterator;
+
+ IteratorEnumeration(Iterator<String> iterator)
+ {
+ this.iterator = iterator;
+ }
+
+ public boolean hasMoreElements()
+ {
+ return iterator.hasNext();
+ }
+
+ public String nextElement()
+ {
+ return iterator.next();
+ }
+
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/MimeTypeParseException.java b/libjava/classpath/javax/activation/MimeTypeParseException.java
new file mode 100644
index 000000000..18e8a62e2
--- /dev/null
+++ b/libjava/classpath/javax/activation/MimeTypeParseException.java
@@ -0,0 +1,83 @@
+/* MimeTypeParseException.java -- Exception due to invalid MIME type.
+ 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 gnu.java.lang.CPStringBuilder;
+
+/**
+ * Exception thrown to indicate a malformed MIME content type.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class MimeTypeParseException
+ extends Exception
+{
+
+ /**
+ * Constructs a MimeTypeParseException with no detail message.
+ */
+ public MimeTypeParseException()
+ {
+ }
+
+ /**
+ * MimeTypeParseException with the specified detail message.
+ * @param message the exception message
+ */
+ public MimeTypeParseException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * Constructs a MimeTypeParseException with the specified detail message
+ * and token in error.
+ * @param message the exception message
+ * @param token the token in error
+ */
+ MimeTypeParseException(String message, String token)
+ {
+ this(new CPStringBuilder(message)
+ .append(':')
+ .append(' ')
+ .append(token)
+ .toString());
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/MimetypesFileTypeMap.java b/libjava/classpath/javax/activation/MimetypesFileTypeMap.java
new file mode 100644
index 000000000..0c381d8e4
--- /dev/null
+++ b/libjava/classpath/javax/activation/MimetypesFileTypeMap.java
@@ -0,0 +1,439 @@
+/* MimeTypesFileTypeMap.java -- A file type map using mime.types.
+ 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 gnu.java.lang.CPStringBuilder;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of FileTypeMap that uses the <tt>mime.types</tt> format.
+ * File entries are searched for in the following locations and order:
+ * <ol>
+ * <li>Programmatically added entries to this instance</li>
+ * <li>The file <tt>.mime.types</tt> in the user's home directory</li>
+ * <li>The file <i>&lt;java.home&gt;</i><tt>/lib/mime.types</tt></li>
+ * <li>The resource <tt>META-INF/mime.types</tt></li>
+ * <li>The resource <tt>META-INF/mimetypes.default</tt> in the JAF
+ * distribution</li>
+ * </ol>
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class MimetypesFileTypeMap
+ extends FileTypeMap
+{
+
+ private static final int PROG = 0;
+ private static final int HOME = 1;
+ private static final int SYS = 2;
+ private static final int JAR = 3;
+ private static final int DEF = 4;
+ private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
+ private static boolean debug = false;
+ static
+ {
+ try
+ {
+ String d = System.getProperty("javax.activation.debug");
+ debug = Boolean.valueOf(d).booleanValue();
+ }
+ catch (SecurityException e)
+ {
+ }
+ }
+
+ private Map<String,String>[] mimetypes;
+
+ /**
+ * Default constructor.
+ */
+ public MimetypesFileTypeMap()
+ {
+ init(null);
+ }
+
+ /**
+ * Constructor specifying a filename.
+ * @param mimeTypeFileName the name of the file to read mime.types
+ * entries from
+ */
+ public MimetypesFileTypeMap(String mimeTypeFileName)
+ throws IOException
+ {
+ Reader in = null;
+ try
+ {
+ in = new FileReader(mimeTypeFileName);
+ init(in);
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+ }
+ }
+
+ /**
+ * Constructor specifying an input stream.
+ * @param is the input stream to read mime.types entries from
+ */
+ public MimetypesFileTypeMap(InputStream is)
+ {
+ init(new InputStreamReader(is));
+ }
+
+ private void init(Reader in)
+ {
+ mimetypes = new Map[5];
+ for (int i = 0; i < mimetypes.length; i++)
+ {
+ mimetypes[i] = new HashMap<String,String>();
+ }
+ if (in != null)
+ {
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: load PROG");
+ }
+ try
+ {
+ parse(mimetypes[PROG], in);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: load HOME");
+ }
+ try
+ {
+ String home = System.getProperty("user.home");
+ if (home != null)
+ {
+ parseFile(mimetypes[HOME], new CPStringBuilder(home)
+ .append(File.separatorChar)
+ .append(".mime.types")
+ .toString());
+ }
+ }
+ catch (SecurityException e)
+ {
+ }
+
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: load SYS");
+ }
+ try
+ {
+ parseFile(mimetypes[SYS],
+ new CPStringBuilder(System.getProperty("java.home"))
+ .append(File.separatorChar)
+ .append("lib")
+ .append(File.separatorChar)
+ .append("mime.types")
+ .toString());
+ }
+ catch (SecurityException e)
+ {
+ }
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: load JAR");
+ }
+ List<URL> systemResources = getSystemResources("META-INF/mime.types");
+ int len = systemResources.size();
+ if (len > 0)
+ {
+ for (int i = 0; i < len ; i++)
+ {
+ Reader urlIn = null;
+ URL url = (URL)systemResources.get(i);
+ try
+ {
+ urlIn = new InputStreamReader(url.openStream());
+ parse(mimetypes[JAR], urlIn);
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ if (urlIn != null)
+ {
+ try
+ {
+ urlIn.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ parseResource(mimetypes[JAR], "/META-INF/mime.types");
+ }
+
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: load DEF");
+ }
+ parseResource(mimetypes[DEF], "/META-INF/mimetypes.default");
+ }
+
+ /**
+ * Adds entries prorammatically to the registry.
+ * @param mime_types a mime.types formatted entries string
+ */
+ public synchronized void addMimeTypes(String mime_types)
+ {
+ if (debug)
+ {
+ System.out.println("MimetypesFileTypeMap: add to PROG");
+ }
+ try
+ {
+ parse(mimetypes[PROG], new StringReader(mime_types));
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ /**
+ * Returns the MIME content type of the file.
+ * This calls <code>getContentType(f.getName())</code>.
+ * @param f the file
+ */
+ public String getContentType(File f)
+ {
+ return getContentType(f.getName());
+ }
+
+ /**
+ * Returns the MIME type based on the given filename.
+ * If no entry is found, returns "application/octet-stream".
+ * @param filename the filename
+ */
+ public synchronized String getContentType(String filename)
+ {
+ int di = filename.lastIndexOf('.');
+ if (di < 0)
+ {
+ return DEFAULT_MIME_TYPE;
+ }
+ String tail = filename.substring(di + 1);
+ if (tail.length() < 1)
+ {
+ return DEFAULT_MIME_TYPE;
+ }
+ for (int i = 0; i < mimetypes.length; i++)
+ {
+ String mimeType = (String)mimetypes[i].get(tail);
+ if (mimeType != null)
+ {
+ return mimeType;
+ }
+ }
+ return DEFAULT_MIME_TYPE;
+ }
+
+ private void parseFile(Map<String,String> mimetypes, String filename)
+ {
+ Reader in = null;
+ try
+ {
+ in = new FileReader(filename);
+ parse(mimetypes, in);
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+
+ private void parseResource(Map<String,String> mimetypes, String name)
+ {
+ Reader in = null;
+ try
+ {
+ InputStream is = getClass().getResourceAsStream(name);
+ if (is != null)
+ {
+ in = new InputStreamReader(is);
+ parse(mimetypes, in);
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ }
+
+ private void parse(Map<String,String> mimetypes, Reader in)
+ throws IOException
+ {
+ BufferedReader br = new BufferedReader(in);
+ CPStringBuilder buf = null;
+ for (String line = br.readLine(); line != null; line = br.readLine())
+ {
+ line = line.trim();
+ int len = line.length();
+ if (len == 0 || line.charAt(0) == '#')
+ {
+ continue; // Empty line / comment
+ }
+ if (line.charAt(len - 1) == '\\')
+ {
+ if (buf == null)
+ {
+ buf = new CPStringBuilder();
+ }
+ buf.append(line.substring(0, len - 1));
+ }
+ else if (buf != null)
+ {
+ buf.append(line);
+ parseEntry(mimetypes, buf.toString());
+ buf = null;
+ }
+ else
+ {
+ parseEntry(mimetypes, line);
+ }
+ }
+ }
+
+ private void parseEntry(Map<String,String> mimetypes,
+ String line)
+ {
+ // Tokenize
+ String mimeType = null;
+ char[] chars = line.toCharArray();
+ int len = chars.length;
+ CPStringBuilder buffer = new CPStringBuilder();
+ for (int i = 0; i < len; i++)
+ {
+ char c = chars[i];
+ if (Character.isWhitespace(c))
+ {
+ if (mimeType == null)
+ {
+ mimeType = buffer.toString();
+ }
+ else if (buffer.length() > 0)
+ {
+ mimetypes.put(buffer.toString(), mimeType);
+ }
+ buffer.setLength(0);
+ }
+ else
+ buffer.append(c);
+ }
+ if (buffer.length() > 0)
+ {
+ mimetypes.put(buffer.toString(), mimeType);
+ }
+ }
+
+ // -- Utility methods --
+
+ private List<URL> getSystemResources(String name)
+ {
+ List<URL> acc = new ArrayList<URL>();
+ try
+ {
+ for (Enumeration<URL> i = ClassLoader.getSystemResources(name);
+ i.hasMoreElements(); )
+ acc.add(i.nextElement());
+ }
+ catch (IOException e)
+ {
+ }
+ return acc;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/ObjectDataContentHandler.java b/libjava/classpath/javax/activation/ObjectDataContentHandler.java
new file mode 100644
index 000000000..3f5e2967a
--- /dev/null
+++ b/libjava/classpath/javax/activation/ObjectDataContentHandler.java
@@ -0,0 +1,127 @@
+/* ObjectDataContentHandler.java -- Data content handler using an object.
+ 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.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Data content handler that uses an existing DCH and reified object.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+class ObjectDataContentHandler
+ implements DataContentHandler
+{
+
+ private DataContentHandler dch;
+ private Object object;
+ private String mimeType;
+ private DataFlavor[] flavors;
+
+ public ObjectDataContentHandler(DataContentHandler dch, Object object,
+ String mimeType)
+ {
+ this.dch = dch;
+ this.object = object;
+ this.mimeType = mimeType;
+ }
+
+ public Object getContent(DataSource ds)
+ {
+ return object;
+ }
+
+ public DataContentHandler getDCH()
+ {
+ return dch;
+ }
+
+ public Object getTransferData(DataFlavor flavor, DataSource ds)
+ throws UnsupportedFlavorException, IOException
+ {
+ if (dch != null)
+ {
+ return dch.getTransferData(flavor, ds);
+ }
+ if (flavors == null)
+ {
+ getTransferDataFlavors();
+ }
+ if (flavor.equals(flavors[0]))
+ {
+ return object;
+ }
+ throw new UnsupportedFlavorException(flavor);
+ }
+
+ public DataFlavor[] getTransferDataFlavors()
+ {
+ if (flavors == null)
+ {
+ if (dch != null)
+ {
+ flavors = dch.getTransferDataFlavors();
+ }
+ else
+ {
+ flavors = new DataFlavor[1];
+ flavors[0] = new ActivationDataFlavor(object.getClass(),
+ mimeType, mimeType);
+ }
+ }
+ return flavors;
+ }
+
+ public void writeTo(Object object, String mimeType, OutputStream out)
+ throws IOException
+ {
+ if (dch != null)
+ {
+ dch.writeTo(object, mimeType, out);
+ }
+ else
+ {
+ throw new UnsupportedDataTypeException("no object DCH for MIME type " + mimeType);
+ }
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/URLDataSource.java b/libjava/classpath/javax/activation/URLDataSource.java
new file mode 100644
index 000000000..66472ada9
--- /dev/null
+++ b/libjava/classpath/javax/activation/URLDataSource.java
@@ -0,0 +1,137 @@
+/* URLDataSource.java -- Data source for a URL object.
+ 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.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * DataSource implementation that retrieves its data from a URL.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class URLDataSource
+ implements DataSource
+{
+
+ private final URL url;
+ private URLConnection connection;
+
+ /**
+ * Constructor.
+ * This will not open the connection to the URL.
+ */
+ public URLDataSource(URL url)
+ {
+ this.url = url;
+ }
+
+ /**
+ * Returns the Content-Type header for the URL.
+ * In the case of failure or lack of such a header,
+ * returns "application/octet-stream".
+ */
+ public String getContentType()
+ {
+ try
+ {
+ if (connection == null)
+ {
+ connection = url.openConnection();
+ }
+ }
+ catch (IOException e)
+ {
+ }
+ String contentType = null;
+ if (connection != null)
+ {
+ contentType = connection.getContentType();
+ }
+ if (contentType == null)
+ {
+ contentType = "application/octet-stream";
+ }
+ return contentType;
+ }
+
+ /**
+ * Returns the result of <code>getFile</code> of the underlying URL.
+ */
+ public String getName()
+ {
+ return url.getFile();
+ }
+
+ public InputStream getInputStream()
+ throws IOException
+ {
+ connection = url.openConnection();
+ if (connection != null)
+ {
+ connection.setDoInput(true);
+ return connection.getInputStream();
+ }
+ return null;
+ }
+
+ public OutputStream getOutputStream()
+ throws IOException
+ {
+ connection = url.openConnection();
+ if (connection != null)
+ {
+ connection.setDoOutput(true);
+ return connection.getOutputStream();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the underlying URL.
+ */
+ public URL getURL()
+ {
+ return url;
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/UnsupportedDataTypeException.java b/libjava/classpath/javax/activation/UnsupportedDataTypeException.java
new file mode 100644
index 000000000..d0c4b9d8a
--- /dev/null
+++ b/libjava/classpath/javax/activation/UnsupportedDataTypeException.java
@@ -0,0 +1,69 @@
+/* UnsupportedDataTypeException.java -- Thrown when a data type is not supported.
+ 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.io.IOException;
+
+/**
+ * Exception indicating that the requested method doesn't support the
+ * specified data type.
+ *
+ * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
+ * @version 1.1
+ */
+public class UnsupportedDataTypeException extends IOException
+{
+
+ /**
+ * Constructs an UnsupportedDataTypeException with no detail message.
+ */
+ public UnsupportedDataTypeException()
+ {
+ }
+
+ /**
+ * Constructs an UnsupportedDataTypeException with the specified detail
+ * message.
+ * @param message the message
+ */
+ public UnsupportedDataTypeException(String message)
+ {
+ super(message);
+ }
+
+}
diff --git a/libjava/classpath/javax/activation/package.html b/libjava/classpath/javax/activation/package.html
new file mode 100644
index 000000000..74027ec32
--- /dev/null
+++ b/libjava/classpath/javax/activation/package.html
@@ -0,0 +1,44 @@
+<body>
+
+<p>
+The GNU JavaBeans&trade; Activation Framework (JAF) provides a
+<a href="http://www.gnu.org/">Free</a> implementation of the
+JavaBeans&trade; Activation Framework, version 1.1.
+</p>
+
+<p>
+JAF links together beans and internet standards for specifying MIME
+types and how MIME types are processed. It provides a means to associate
+data of a given MIME type with bean actions operating on that data.
+</p>
+
+
+<h4>Important files</h4>
+
+<p>
+Standard <code>mime.types</code> files are parsed by the JAF MIME
+handling classes to work out the MIME types available on the local
+system.
+</p>
+
+<p>
+Standard <code>mailcap</code> files (defined in RFC1524) are parsed by
+mail capability handling classes to work out what beans should be linked
+to what MIME types.
+</p>
+
+<p>
+<small>Neither the authors nor the Free Software Foundation offer
+ANY SUPPORT for this software or imply any warranty.<br>
+Use it at your own risk.
+</small>
+</p>
+
+<p>
+<small>If you can suggest improvements in either the implementation
+code or in the documentation please contact the
+<a href="mailto:classpath@gnu.org">GNU Classpath project</a> developers.
+</small>
+</p>
+
+</body>