/* 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;
  }
  
}

