All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.ocathain.sun.awt.datatransfer.DataTransferer Maven / Gradle / Ivy

Go to download

A minimal port of Java Activation Framework with the AWT dependencies removed. Exists purely to allow the Android port of JavaMail to work.

The newest version!
/*
 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package eu.ocathain.sun.awt.datatransfer;

import eu.ocathain.awt.datatransfer.DataFlavor;
//import eu.ocathain.awt.datatransfer.FlavorMap;
//import eu.ocathain.awt.datatransfer.FlavorTable;
//import eu.ocathain.awt.datatransfer.Transferable;
//import eu.ocathain.awt.datatransfer.UnsupportedFlavorException;

//import java.io.BufferedReader;
//import java.io.ByteArrayInputStream;
//import java.io.ByteArrayOutputStream;
//import java.io.File;
//import java.io.InputStream;
//import java.io.InputStreamReader;
//import java.io.IOException;
//import java.io.ObjectInputStream;
//import java.io.ObjectOutputStream;
//import java.io.Reader;
//import java.io.SequenceInputStream;
//import java.io.StringReader;
//
//import java.net.URI;
//import java.net.URISyntaxException;
//
//import java.nio.ByteBuffer;
//import java.nio.CharBuffer;
import java.nio.charset.Charset;
//import java.nio.charset.CharsetEncoder;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;

//import java.lang.reflect.Constructor;
//import java.lang.reflect.InvocationTargetException;
//import java.lang.reflect.Method;
//import java.lang.reflect.Modifier;
//
//import java.security.AccessController;
//import java.security.PrivilegedAction;
//import java.security.PrivilegedActionException;
//import java.security.PrivilegedExceptionAction;
//import java.security.ProtectionDomain;

//import java.util.ArrayList;
//import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
import java.util.Map;
//import java.util.SortedMap;
//import java.util.SortedSet;
//import java.util.Set;
//import java.util.Stack;
//import java.util.TreeMap;
//import java.util.TreeSet;
//
//import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
//import sun.util.logging.PlatformLogger;
//
//import sun.awt.AppContext;
//import sun.awt.SunToolkit;
//
//
//import javax.imageio.ImageIO;
//import javax.imageio.ImageReader;
//import javax.imageio.ImageReadParam;
//import javax.imageio.ImageWriter;
//import javax.imageio.ImageTypeSpecifier;
//
//import javax.imageio.spi.ImageWriterSpi;
//
//import javax.imageio.stream.ImageInputStream;
//import javax.imageio.stream.ImageOutputStream;
//
//import sun.awt.image.ImageRepresentation;
//import sun.awt.image.ToolkitImage;
//
//import java.io.FilePermission;


/**
 * NOTE THIS FILE WAS HEAVILY HACKED DOWN, IT CONTAINS JUST ENOUGH FOR THE ANDROID FORK TO COMPILE
 *
 * Provides a set of functions to be shared among the DataFlavor class and
 * platform-specific data transfer implementations.
 *
 * The concept of "flavors" and "natives" is extended to include "formats",
 * which are the numeric values Win32 and X11 use to express particular data
 * types. Like FlavorMap, which provides getNativesForFlavors(DataFlavor[]) and
 * getFlavorsForNatives(String[]) functions, DataTransferer provides a set
 * of getFormatsFor(Transferable|Flavor|Flavors) and
 * getFlavorsFor(Format|Formats) functions.
 *
 * Also provided are functions for translating a Transferable into a byte
 * array, given a source DataFlavor and a target format, and for translating
 * a byte array or InputStream into an Object, given a source format and
 * a target DataFlavor.
 *
 * @author David Mendenhall
 * @author Danila Sinopalnikov
 *
 * @since 1.3.1
 */
public abstract class DataTransferer {


    /**
     * Cached value of Class.forName("[C");
     */
    public static final Class charArrayClass;

    /**
     * Cached value of Class.forName("[B");
     */
    public static final Class byteArrayClass;


    /**
     * Cache of the platform default encoding as specified in the
     * "file.encoding" system property.
     */
    private static String defaultEncoding;

    /**
     * The singleton DataTransferer instance. It is created during MToolkit
     * or WToolkit initialization.
     */
    private static DataTransferer transferer;

    static {
        Class tCharArrayClass = null, tByteArrayClass = null;
        try {
            tCharArrayClass = Class.forName("[C");
            tByteArrayClass = Class.forName("[B");
        } catch (ClassNotFoundException cannotHappen) {
        }
        charArrayClass = tCharArrayClass;
        byteArrayClass = tByteArrayClass;

        Map tempMap = new HashMap(17);
        tempMap.put("sgml", Boolean.TRUE);
        tempMap.put("xml", Boolean.TRUE);
        tempMap.put("html", Boolean.TRUE);
        tempMap.put("enriched", Boolean.TRUE);
        tempMap.put("richtext", Boolean.TRUE);
        tempMap.put("uri-list", Boolean.TRUE);
        tempMap.put("directory", Boolean.TRUE);
        tempMap.put("css", Boolean.TRUE);
        tempMap.put("calendar", Boolean.TRUE);
        tempMap.put("plain", Boolean.TRUE);
        tempMap.put("rtf", Boolean.FALSE);
        tempMap.put("tab-separated-values", Boolean.FALSE);
        tempMap.put("t140", Boolean.FALSE);
        tempMap.put("rfc822-headers", Boolean.FALSE);
        tempMap.put("parityfec", Boolean.FALSE);
        textMIMESubtypeCharsetSupport = Collections.synchronizedMap(tempMap);
    }


    /**
     * Tracks whether a particular text/* MIME type supports the charset
     * parameter. The Map is initialized with all of the standard MIME types
     * listed in the DataFlavor.selectBestTextFlavor method comment. Additional
     * entries may be added during the life of the JRE for text/ types.
     */
    private static final Map textMIMESubtypeCharsetSupport;

    /**
     * Converts an arbitrary text encoding to its canonical name.
     */
    public static String canonicalName(String encoding) {
        if (encoding == null) {
            return null;
        }
        try {
            return Charset.forName(encoding).name();
        } catch (IllegalCharsetNameException icne) {
            return encoding;
        } catch (UnsupportedCharsetException uce) {
            return encoding;
        }
    }


    /**
     * Returns whether this flavor is a text type which supports the
     * 'charset' parameter.
     */
    public static boolean isFlavorCharsetTextType(DataFlavor flavor) {
        // Although stringFlavor doesn't actually support the charset
        // parameter (because its primary MIME type is not "text"), it should
        // be treated as though it does. stringFlavor is semantically
        // equivalent to "text/plain" data.
        if (DataFlavor.stringFlavor.equals(flavor)) {
            return true;
        }

        if (!"text".equals(flavor.getPrimaryType()) ||
                !doesSubtypeSupportCharset(flavor))
        {
            return false;
        }

        Class rep_class = flavor.getRepresentationClass();

        if (flavor.isRepresentationClassReader() ||
                String.class.equals(rep_class) ||
                flavor.isRepresentationClassCharBuffer() ||
                DataTransferer.charArrayClass.equals(rep_class))
        {
            return true;
        }

        if (!(flavor.isRepresentationClassInputStream() ||
                flavor.isRepresentationClassByteBuffer() ||
                DataTransferer.byteArrayClass.equals(rep_class))) {
            return false;
        }

        String charset = flavor.getParameter("charset");

        return (charset != null)
                ? DataTransferer.isEncodingSupported(charset)
                : true; // null equals default encoding which is always supported
    }

    /**
     * Returns whether this flavor is a text type which does not support the
     * 'charset' parameter.
     */
    public static boolean isFlavorNoncharsetTextType(DataFlavor flavor) {
        if (!"text".equals(flavor.getPrimaryType()) ||
                doesSubtypeSupportCharset(flavor))
        {
            return false;
        }

        return (flavor.isRepresentationClassInputStream() ||
                flavor.isRepresentationClassByteBuffer() ||
                DataTransferer.byteArrayClass.
                        equals(flavor.getRepresentationClass()));
    }

    /**
     * Determines whether this JRE can both encode and decode text in the
     * specified encoding.
     */
    public static boolean isEncodingSupported(String encoding) {
        if (encoding == null) {
            return false;
        }
        try {
            return Charset.isSupported(encoding);
        } catch (IllegalCharsetNameException icne) {
            return false;
        }
    }

    /**
     * Returns {@code true} if the given type is a java.rmi.Remote.
     */
    public static boolean isRemote(Class type) {
        return false;
    }

    /**
     * Returns the platform's default character encoding.
     */
    public static String getDefaultTextCharset() {
        if (defaultEncoding != null) {
            return defaultEncoding;
        }
        return defaultEncoding = Charset.defaultCharset().name();
    }


    /**
     * If the specified flavor is a text flavor which supports the "charset"
     * parameter, then this method returns that parameter, or the default
     * charset if no such parameter was specified at construction. For non-
     * text DataFlavors, and for non-charset text flavors, this method returns
     * null.
     */
    public static String getTextCharset(DataFlavor flavor) {
        if (!isFlavorCharsetTextType(flavor)) {
            return null;
        }

        String encoding = flavor.getParameter("charset");

        return (encoding != null) ? encoding : getDefaultTextCharset();
    }



    /**
     * Tests only whether the flavor's MIME type supports the charset
     * parameter. Must only be called for flavors with a primary type of
     * "text".
     */
    public static boolean doesSubtypeSupportCharset(DataFlavor flavor) {
//        if (dtLog.isLoggable(PlatformLogger.FINE)) {
//            if (!"text".equals(flavor.getPrimaryType())) {
//                dtLog.fine("Assertion (\"text\".equals(flavor.getPrimaryType())) failed");
//            }
//        }

        String subType = flavor.getSubType();
        if (subType == null) {
            return false;
        }

        Object support = textMIMESubtypeCharsetSupport.get(subType);

        if (support != null) {
            return (support == Boolean.TRUE);
        }

        boolean ret_val = (flavor.getParameter("charset") != null);
        textMIMESubtypeCharsetSupport.put
                (subType, (ret_val) ? Boolean.TRUE : Boolean.FALSE);
        return ret_val;
    }



    /**
     * A Comparator which includes a helper function for comparing two Objects
     * which are likely to be keys in the specified Map.
     */
    public abstract static class IndexedComparator implements Comparator {

        /**
         * The best Object (e.g., DataFlavor) will be the last in sequence.
         */
        public static final boolean SELECT_BEST = true;

        /**
         * The best Object (e.g., DataFlavor) will be the first in sequence.
         */
        public static final boolean SELECT_WORST = false;

        protected final boolean order;

        public IndexedComparator() {
            this(SELECT_BEST);
        }

        public IndexedComparator(boolean order) {
            this.order = order;
        }

        /**
         * Helper method to compare two objects by their Integer indices in the
         * given map. If the map doesn't contain an entry for either of the
         * objects, the fallback index will be used for the object instead.
         *
         * @param indexMap the map which maps objects into Integer indexes.
         * @param obj1 the first object to be compared.
         * @param obj2 the second object to be compared.
         * @param fallbackIndex the Integer to be used as a fallback index.
         * @return a negative integer, zero, or a positive integer as the
         *             first object is mapped to a less, equal to, or greater
         *             index than the second.
         */
        protected static int compareIndices(Map indexMap,
                                            Object obj1, Object obj2,
                                            Integer fallbackIndex) {
            Integer index1 = (Integer)indexMap.get(obj1);
            Integer index2 = (Integer)indexMap.get(obj2);

            if (index1 == null) {
                index1 = fallbackIndex;
            }
            if (index2 == null) {
                index2 = fallbackIndex;
            }

            return index1.compareTo(index2);
        }

        /**
         * Helper method to compare two objects by their Long indices in the
         * given map. If the map doesn't contain an entry for either of the
         * objects, the fallback index will be used for the object instead.
         *
         * @param indexMap the map which maps objects into Long indexes.
         * @param obj1 the first object to be compared.
         * @param obj2 the second object to be compared.
         * @param fallbackIndex the Long to be used as a fallback index.
         * @return a negative integer, zero, or a positive integer as the
         *             first object is mapped to a less, equal to, or greater
         *             index than the second.
         */
        protected static int compareLongs(Map indexMap,
                                          Object obj1, Object obj2,
                                          Long fallbackIndex) {
            Long index1 = (Long)indexMap.get(obj1);
            Long index2 = (Long)indexMap.get(obj2);

            if (index1 == null) {
                index1 = fallbackIndex;
            }
            if (index2 == null) {
                index2 = fallbackIndex;
            }

            return index1.compareTo(index2);
        }
    }

    /**
     * An IndexedComparator which compares two String charsets. The comparison
     * follows the rules outlined in DataFlavor.selectBestTextFlavor. In order
     * to ensure that non-Unicode, non-ASCII, non-default charsets are sorted
     * in alphabetical order, charsets are not automatically converted to their
     * canonical forms.
     */
    public static class CharsetComparator extends IndexedComparator {
        private static final Map charsets;
        private static String defaultEncoding;

        private static final Integer DEFAULT_CHARSET_INDEX = Integer.valueOf(2);
        private static final Integer OTHER_CHARSET_INDEX = Integer.valueOf(1);
        private static final Integer WORST_CHARSET_INDEX = Integer.valueOf(0);
        private static final Integer UNSUPPORTED_CHARSET_INDEX =
                Integer.valueOf(Integer.MIN_VALUE);

        private static final String UNSUPPORTED_CHARSET = "UNSUPPORTED";

        static {
            HashMap charsetsMap = new HashMap(8, 1.0f);

            // we prefer Unicode charsets
            charsetsMap.put(canonicalName("UTF-16LE"), Integer.valueOf(4));
            charsetsMap.put(canonicalName("UTF-16BE"), Integer.valueOf(5));
            charsetsMap.put(canonicalName("UTF-8"), Integer.valueOf(6));
            charsetsMap.put(canonicalName("UTF-16"), Integer.valueOf(7));

            // US-ASCII is the worst charset supported
            charsetsMap.put(canonicalName("US-ASCII"), WORST_CHARSET_INDEX);

            String defEncoding = DataTransferer.canonicalName
                    (DataTransferer.getDefaultTextCharset());

            if (charsetsMap.get(defaultEncoding) == null) {
                charsetsMap.put(defaultEncoding, DEFAULT_CHARSET_INDEX);
            }
            charsetsMap.put(UNSUPPORTED_CHARSET, UNSUPPORTED_CHARSET_INDEX);

            charsets = Collections.unmodifiableMap(charsetsMap);
        }

        public CharsetComparator() {
            this(SELECT_BEST);
        }

        public CharsetComparator(boolean order) {
            super(order);
        }

        /**
         * Compares two String objects. Returns a negative integer, zero,
         * or a positive integer as the first charset is worse than, equal to,
         * or better than the second.
         *
         * @param obj1 the first charset to be compared
         * @param obj2 the second charset to be compared
         * @return a negative integer, zero, or a positive integer as the
         *         first argument is worse, equal to, or better than the
         *         second.
         * @throws ClassCastException if either of the arguments is not
         *         instance of String
         * @throws NullPointerException if either of the arguments is
         *         null.
         */
        public int compare(Object obj1, Object obj2) {
            String charset1 = null;
            String charset2 = null;
            if (order == SELECT_BEST) {
                charset1 = (String)obj1;
                charset2 = (String)obj2;
            } else {
                charset1 = (String)obj2;
                charset2 = (String)obj1;
            }

            return compareCharsets(charset1, charset2);
        }

        /**
         * Compares charsets. Returns a negative integer, zero, or a positive
         * integer as the first charset is worse than, equal to, or better than
         * the second.
         * 

* Charsets are ordered according to the following rules: *

    *
  • All unsupported charsets are equal. *
  • Any unsupported charset is worse than any supported charset. *
  • Unicode charsets, such as "UTF-16", "UTF-8", "UTF-16BE" and * "UTF-16LE", are considered best. *
  • After them, platform default charset is selected. *
  • "US-ASCII" is the worst of supported charsets. *
  • For all other supported charsets, the lexicographically less * one is considered the better. *
* * @param charset1 the first charset to be compared * @param charset2 the second charset to be compared. * @return a negative integer, zero, or a positive integer as the * first argument is worse, equal to, or better than the * second. */ protected int compareCharsets(String charset1, String charset2) { charset1 = getEncoding(charset1); charset2 = getEncoding(charset2); int comp = compareIndices(charsets, charset1, charset2, OTHER_CHARSET_INDEX); if (comp == 0) { return charset2.compareTo(charset1); } return comp; } /** * Returns encoding for the specified charset according to the * following rules: *
    *
  • If the charset is null, then null will * be returned. *
  • Iff the charset specifies an encoding unsupported by this JRE, * UNSUPPORTED_CHARSET will be returned. *
  • If the charset specifies an alias name, the corresponding * canonical name will be returned iff the charset is a known * Unicode, ASCII, or default charset. *
* * @param charset the charset. * @return an encoding for this charset. */ protected static String getEncoding(String charset) { if (charset == null) { return null; } else if (!DataTransferer.isEncodingSupported(charset)) { return UNSUPPORTED_CHARSET; } else { // Only convert to canonical form if the charset is one // of the charsets explicitly listed in the known charsets // map. This will happen only for Unicode, ASCII, or default // charsets. String canonicalName = DataTransferer.canonicalName(charset); return (charsets.containsKey(canonicalName)) ? canonicalName : charset; } } } /** * An IndexedComparator which compares two DataFlavors. For text flavors, * the comparison follows the rules outlined in * DataFlavor.selectBestTextFlavor. For non-text flavors, unknown * application MIME types are preferred, followed by known * application/x-java-* MIME types. Unknown application types are preferred * because if the user provides his own data flavor, it will likely be the * most descriptive one. For flavors which are otherwise equal, the * flavors' native formats are compared, with greater long values * taking precedence. */ public static class DataFlavorComparator extends IndexedComparator { protected final Map flavorToFormatMap; private final CharsetComparator charsetComparator; private static final Map exactTypes; private static final Map primaryTypes; private static final Map nonTextRepresentations; private static final Map textTypes; private static final Map decodedTextRepresentations; private static final Map encodedTextRepresentations; private static final Integer UNKNOWN_OBJECT_LOSES = Integer.valueOf(Integer.MIN_VALUE); private static final Integer UNKNOWN_OBJECT_WINS = Integer.valueOf(Integer.MAX_VALUE); private static final Long UNKNOWN_OBJECT_LOSES_L = Long.valueOf(Long.MIN_VALUE); private static final Long UNKNOWN_OBJECT_WINS_L = Long.valueOf(Long.MAX_VALUE); static { { HashMap exactTypesMap = new HashMap(4, 1.0f); // application/x-java-* MIME types exactTypesMap.put("application/x-java-file-list", Integer.valueOf(0)); exactTypesMap.put("application/x-java-serialized-object", Integer.valueOf(1)); exactTypesMap.put("application/x-java-jvm-local-objectref", Integer.valueOf(2)); exactTypesMap.put("application/x-java-remote-object", Integer.valueOf(3)); exactTypes = Collections.unmodifiableMap(exactTypesMap); } { HashMap primaryTypesMap = new HashMap(1, 1.0f); primaryTypesMap.put("application", Integer.valueOf(0)); primaryTypes = Collections.unmodifiableMap(primaryTypesMap); } { HashMap nonTextRepresentationsMap = new HashMap(3, 1.0f); nonTextRepresentationsMap.put(java.io.InputStream.class, Integer.valueOf(0)); nonTextRepresentationsMap.put(java.io.Serializable.class, Integer.valueOf(1)); Class remoteClass = null; if (remoteClass != null) { nonTextRepresentationsMap.put(remoteClass, Integer.valueOf(2)); } nonTextRepresentations = Collections.unmodifiableMap(nonTextRepresentationsMap); } { HashMap textTypesMap = new HashMap(16, 1.0f); // plain text textTypesMap.put("text/plain", Integer.valueOf(0)); // stringFlavor textTypesMap.put("application/x-java-serialized-object", Integer.valueOf(1)); // misc textTypesMap.put("text/calendar", Integer.valueOf(2)); textTypesMap.put("text/css", Integer.valueOf(3)); textTypesMap.put("text/directory", Integer.valueOf(4)); textTypesMap.put("text/parityfec", Integer.valueOf(5)); textTypesMap.put("text/rfc822-headers", Integer.valueOf(6)); textTypesMap.put("text/t140", Integer.valueOf(7)); textTypesMap.put("text/tab-separated-values", Integer.valueOf(8)); textTypesMap.put("text/uri-list", Integer.valueOf(9)); // enriched textTypesMap.put("text/richtext", Integer.valueOf(10)); textTypesMap.put("text/enriched", Integer.valueOf(11)); textTypesMap.put("text/rtf", Integer.valueOf(12)); // markup textTypesMap.put("text/html", Integer.valueOf(13)); textTypesMap.put("text/xml", Integer.valueOf(14)); textTypesMap.put("text/sgml", Integer.valueOf(15)); textTypes = Collections.unmodifiableMap(textTypesMap); } { HashMap decodedTextRepresentationsMap = new HashMap(4, 1.0f); decodedTextRepresentationsMap.put (DataTransferer.charArrayClass, Integer.valueOf(0)); decodedTextRepresentationsMap.put (java.nio.CharBuffer.class, Integer.valueOf(1)); decodedTextRepresentationsMap.put (java.lang.String.class, Integer.valueOf(2)); decodedTextRepresentationsMap.put (java.io.Reader.class, Integer.valueOf(3)); decodedTextRepresentations = Collections.unmodifiableMap(decodedTextRepresentationsMap); } { HashMap encodedTextRepresentationsMap = new HashMap(3, 1.0f); encodedTextRepresentationsMap.put (DataTransferer.byteArrayClass, Integer.valueOf(0)); encodedTextRepresentationsMap.put (java.nio.ByteBuffer.class, Integer.valueOf(1)); encodedTextRepresentationsMap.put (java.io.InputStream.class, Integer.valueOf(2)); encodedTextRepresentations = Collections.unmodifiableMap(encodedTextRepresentationsMap); } } public DataFlavorComparator() { this(SELECT_BEST); } public DataFlavorComparator(boolean order) { super(order); charsetComparator = new CharsetComparator(order); flavorToFormatMap = Collections.EMPTY_MAP; } public DataFlavorComparator(Map map) { this(map, SELECT_BEST); } public DataFlavorComparator(Map map, boolean order) { super(order); charsetComparator = new CharsetComparator(order); HashMap hashMap = new HashMap(map.size()); hashMap.putAll(map); flavorToFormatMap = Collections.unmodifiableMap(hashMap); } public int compare(Object obj1, Object obj2) { DataFlavor flavor1 = null; DataFlavor flavor2 = null; if (order == SELECT_BEST) { flavor1 = (DataFlavor)obj1; flavor2 = (DataFlavor)obj2; } else { flavor1 = (DataFlavor)obj2; flavor2 = (DataFlavor)obj1; } if (flavor1.equals(flavor2)) { return 0; } int comp = 0; String primaryType1 = flavor1.getPrimaryType(); String subType1 = flavor1.getSubType(); String mimeType1 = primaryType1 + "/" + subType1; Class class1 = flavor1.getRepresentationClass(); String primaryType2 = flavor2.getPrimaryType(); String subType2 = flavor2.getSubType(); String mimeType2 = primaryType2 + "/" + subType2; Class class2 = flavor2.getRepresentationClass(); if (flavor1.isFlavorTextType() && flavor2.isFlavorTextType()) { // First, compare MIME types comp = compareIndices(textTypes, mimeType1, mimeType2, UNKNOWN_OBJECT_LOSES); if (comp != 0) { return comp; } // Only need to test one flavor because they both have the // same MIME type. Also don't need to worry about accidentally // passing stringFlavor because either // 1. Both flavors are stringFlavor, in which case the // equality test at the top of the function succeeded. // 2. Only one flavor is stringFlavor, in which case the MIME // type comparison returned a non-zero value. if (doesSubtypeSupportCharset(flavor1)) { // Next, prefer the decoded text representations of Reader, // String, CharBuffer, and [C, in that order. comp = compareIndices(decodedTextRepresentations, class1, class2, UNKNOWN_OBJECT_LOSES); if (comp != 0) { return comp; } // Next, compare charsets comp = charsetComparator.compareCharsets (DataTransferer.getTextCharset(flavor1), DataTransferer.getTextCharset(flavor2)); if (comp != 0) { return comp; } } // Finally, prefer the encoded text representations of // InputStream, ByteBuffer, and [B, in that order. comp = compareIndices(encodedTextRepresentations, class1, class2, UNKNOWN_OBJECT_LOSES); if (comp != 0) { return comp; } } else { // First, prefer application types. comp = compareIndices(primaryTypes, primaryType1, primaryType2, UNKNOWN_OBJECT_LOSES); if (comp != 0) { return comp; } // Next, look for application/x-java-* types. Prefer unknown // MIME types because if the user provides his own data flavor, // it will likely be the most descriptive one. comp = compareIndices(exactTypes, mimeType1, mimeType2, UNKNOWN_OBJECT_WINS); if (comp != 0) { return comp; } // Finally, prefer the representation classes of Remote, // Serializable, and InputStream, in that order. comp = compareIndices(nonTextRepresentations, class1, class2, UNKNOWN_OBJECT_LOSES); if (comp != 0) { return comp; } } // As a last resort, take the DataFlavor with the greater integer // format. return compareLongs(flavorToFormatMap, flavor1, flavor2, UNKNOWN_OBJECT_LOSES_L); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy