/* 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("rawtypes")
    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("rawtypes")
    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("rawtypes")
    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;
    }

}
