You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by ff...@apache.org on 2010/07/29 08:35:51 UTC
svn commit: r980327 -
/servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java
Author: ffang
Date: Thu Jul 29 06:35:51 2010
New Revision: 980327
URL: http://svn.apache.org/viewvc?rev=980327&view=rev
Log:
[SMX4-569]activation-api-1.1 specs bundle should use OsgiMailcapCommandMap to create DataContentHandler
Added:
servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java
Added: servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java?rev=980327&view=auto
==============================================================================
--- servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java (added)
+++ servicemix/smx4/specs/trunk/activation-api-1.1/src/main/java/javax/activation/DataHandler.java Thu Jul 29 06:35:51 2010
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package javax.activation;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.net.URL;
+
+/**
+ * @version $Rev: 467742 $ $Date: 2006-10-25 21:30:38 +0200 (Wed, 25 Oct 2006) $
+ */
+public class DataHandler implements Transferable {
+ private final DataSource ds;
+ private final DataFlavor flavor;
+
+ private CommandMap commandMap;
+ private DataContentHandler dch;
+
+ public DataHandler(DataSource ds) {
+ this.ds = ds;
+ this.flavor = new ActivationDataFlavor(ds.getContentType(), null);
+ }
+
+ public DataHandler(Object data, String type) {
+ this.ds = new ObjectDataSource(data, type);
+ this.flavor = new ActivationDataFlavor(data.getClass(), null);
+ }
+
+ public DataHandler(URL url) {
+ this.ds = new URLDataSource(url);
+ this.flavor = new ActivationDataFlavor(ds.getContentType(), null);
+ }
+
+ public DataSource getDataSource() {
+ return ds;
+ }
+
+ public String getName() {
+ return ds.getName();
+ }
+
+ public String getContentType() {
+ return ds.getContentType();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return ds.getInputStream();
+ }
+
+ public void writeTo(OutputStream os) throws IOException {
+ if (ds instanceof ObjectDataSource) {
+ ObjectDataSource ods = (ObjectDataSource) ds;
+ DataContentHandler dch = getDataContentHandler();
+ if (dch == null) {
+ throw new UnsupportedDataTypeException(ods.mimeType);
+ }
+ dch.writeTo(ods.data, ods.mimeType, os);
+ } else {
+ byte[] buffer = new byte[1024];
+ InputStream is = getInputStream();
+ try {
+ int count;
+ while ((count = is.read(buffer)) != -1) {
+ os.write(buffer, 0, count);
+ }
+ } finally {
+ is.close();
+ }
+ }
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ return ds.getOutputStream();
+ }
+
+ public synchronized DataFlavor[] getTransferDataFlavors() {
+ return getDataContentHandler().getTransferDataFlavors();
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ DataFlavor[] flavors = getTransferDataFlavors();
+ for (int i = 0; i < flavors.length; i++) {
+ DataFlavor dataFlavor = flavors[i];
+ if (dataFlavor.equals(flavor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+ DataContentHandler dch = getDataContentHandler();
+ if (dch != null) {
+ return dch.getTransferData(flavor, ds);
+ } else if (this.flavor.match(flavor)) {
+ if (ds instanceof ObjectDataSource) {
+ return ((ObjectDataSource) ds).data;
+ } else {
+ return ds.getInputStream();
+ }
+ } else {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ }
+
+ public CommandInfo[] getPreferredCommands() {
+ return getCommandMap().getPreferredCommands(ds.getContentType());
+ }
+
+ public CommandInfo[] getAllCommands() {
+ return getCommandMap().getAllCommands(ds.getContentType());
+ }
+
+ public CommandInfo getCommand(String cmdName) {
+ return getCommandMap().getCommand(ds.getContentType(), cmdName);
+ }
+
+ public Object getContent() throws IOException {
+ if (ds instanceof ObjectDataSource) {
+ return ((ObjectDataSource) ds).data;
+ } else {
+ DataContentHandler dch = getDataContentHandler();
+ if (dch != null) {
+ return dch.getContent(ds);
+ } else {
+ return ds.getInputStream();
+ }
+ }
+ }
+
+ public Object getBean(CommandInfo cmdinfo) {
+ try {
+ return cmdinfo.getCommandObject(this, this.getClass().getClassLoader());
+ } catch (IOException e) {
+ return null;
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+
+ /**
+ * A local implementation of DataSouce used to wrap an Object and mime-type.
+ */
+ private class ObjectDataSource implements DataSource {
+ private final Object data;
+ private final String mimeType;
+
+ public ObjectDataSource(Object data, String mimeType) {
+ this.data = data;
+ this.mimeType = mimeType;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public String getContentType() {
+ return mimeType;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ final DataContentHandler dch = getDataContentHandler();
+ if (dch == null) {
+ throw new UnsupportedDataTypeException(mimeType);
+ }
+ final PipedInputStream is = new PipedInputStream();
+ final PipedOutputStream os = new PipedOutputStream(is);
+ Thread thread = new Thread("DataHandler Pipe Pump") {
+ public void run() {
+ try {
+ try {
+ dch.writeTo(data, mimeType, os);
+ } finally {
+ os.close();
+ }
+ } catch (IOException e) {
+ // ignore, per spec - doh!
+ }
+ }
+ };
+ thread.start();
+ return is;
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ return null;
+ }
+ }
+
+ public synchronized void setCommandMap(CommandMap commandMap) {
+ this.commandMap = commandMap;
+ this.dch = null;
+ }
+
+ private synchronized CommandMap getCommandMap() {
+ return commandMap != null ? commandMap : CommandMap.getDefaultCommandMap();
+ }
+
+ /**
+ * Search for a DataContentHandler for our mime type.
+ * The search is performed by first checking if a global factory has been set using
+ * {@link #setDataContentHandlerFactory(DataContentHandlerFactory)};
+ * if found then it is called to attempt to create a handler.
+ * If this attempt fails, we then call the command map set using {@link #setCommandMap(CommandMap)}
+ * (or if that has not been set, the default map returned by {@link CommandMap#getDefaultCommandMap()})
+ * to create the handler.
+ *
+ * The resulting handler is cached until the global factory is changed.
+ *
+ * @return
+ */
+ private synchronized DataContentHandler getDataContentHandler() {
+ DataContentHandlerFactory localFactory;
+ synchronized (DataHandler.class) {
+ if (factory != originalFactory) {
+ // setDCHF was called - clear our cached copy of the DCH and DCHF
+ dch = null;
+ originalFactory = factory;
+ }
+ localFactory = originalFactory;
+ }
+ if (dch == null) {
+ // get the main mime-type portion of the content.
+ String mimeType = getMimeType(ds.getContentType());
+ if (localFactory != null) {
+ dch = localFactory.createDataContentHandler(mimeType);
+ }
+ if (dch == null) {
+ dch = CommandMap.getDefaultCommandMap().createDataContentHandler(mimeType);
+ }
+ }
+ return dch;
+ }
+
+ /**
+ * Retrieve the base MIME type from a content type. This parses
+ * the type into its base components, stripping off any parameter
+ * information.
+ *
+ * @param contentType
+ * The content type string.
+ *
+ * @return The MIME type identifier portion of the content type.
+ */
+ private String getMimeType(String contentType) {
+ try {
+ MimeType mimeType = new MimeType(contentType);
+ return mimeType.getBaseType();
+ } catch (MimeTypeParseException e) {
+ }
+ return contentType;
+ }
+
+ /**
+ * This is used to check if the DataContentHandlerFactory has been changed.
+ * This is not specified behaviour but this check is required to make this work like the RI.
+ */
+ private DataContentHandlerFactory originalFactory;
+
+ {
+ synchronized (DataHandler.class) {
+ originalFactory = factory;
+ }
+ }
+
+ private static DataContentHandlerFactory factory;
+
+ /**
+ * Set the DataContentHandlerFactory to use.
+ * If this method has already been called then an Error is raised.
+ *
+ * @param newFactory the new factory
+ * @throws SecurityException if the caller does not have "SetFactory" RuntimePermission
+ */
+ public static synchronized void setDataContentHandlerFactory(DataContentHandlerFactory newFactory) {
+ if (factory != null) {
+ throw new Error("javax.activation.DataHandler.setDataContentHandlerFactory has already been defined");
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkSetFactory();
+ }
+ factory = newFactory;
+ }
+}