2N/A * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 2N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2N/A * This code is free software; you can redistribute it and/or modify it 2N/A * under the terms of the GNU General Public License version 2 only, as 2N/A * published by the Free Software Foundation. Oracle designates this 2N/A * particular file as subject to the "Classpath" exception as provided 2N/A * by Oracle in the LICENSE file that accompanied this code. 2N/A * This code is distributed in the hope that it will be useful, but WITHOUT 2N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2N/A * version 2 for more details (a copy is included in the LICENSE file that 2N/A * accompanied this code). 2N/A * You should have received a copy of the GNU General Public License version 2N/A * 2 along with this work; if not, write to the Free Software Foundation, 2N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2N/A * or visit www.oracle.com if you need additional information or have any * 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 * @author David Mendenhall * @author Danila Sinopalnikov * Cached value of Class.forName("[C"); * Cached value of Class.forName("[B"); * The <code>DataFlavor</code> representing plain text with Unicode * representationClass = java.lang.String * The <code>DataFlavor</code> representing a Java text encoding String * encoded in UTF-8, where * representationClass = [B * Lazy initialization of Standard Encodings. * 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/<other> types. * Cache of the platform default encoding as specified in the * "file.encoding" system property. * a primary MIME type of "text". * The end-of-line markers for the Set of textNatives. * The number of terminating NUL bytes for the Set of textNatives. * The key used to store pending data conversion requests for an AppContext. * The singleton DataTransferer instance. It is created during MToolkit * or WToolkit initialization. (
"text/plain;charset=Unicode;class=java.lang.String");
* The accessor method for the singleton DataTransferer instance. Note * that in a headless environment, there may be no DataTransferer instance; * instead, null will be returned. throw new AWTError(
"Cannot instantiate DataTransferer: " +
name);
throw new AWTError(
"Access is denied for DataTransferer: " +
name);
throw new AWTError(
"Cannot instantiate DataTransferer: " +
name);
throw new AWTError(
"Cannot access DataTransferer: " +
name);
* Converts an arbitrary text encoding to its canonical 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 * Returns the platform's default character encoding. * Tests only whether the flavor's MIME type supports the charset * parameter. Must only be called for flavors with a primary type of dtLog.
fine(
"Assertion (\"text\".equals(flavor.getPrimaryType())) failed");
* Returns whether this flavor is a text type which supports the // 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 :
true;
// null equals default encoding which is always supported * Returns whether this flavor is a text type which does not support the * Determines whether this JRE can both encode and decode text in the * Returns {@code true} if the given type is a java.rmi.Remote. * Returns an Iterator which traverses a SortedSet of Strings which are * a total order of the standard character sets supported by the JRE. The * ordering follows the same principles as DataFlavor.selectBestTextFlavor. * So as to avoid loading all available character converters, optional, * non-standard, character sets are not included. * Converts a FlavorMap to a FlavorTable. * Returns the default Unicode encoding for the platform. The encoding * need not be canonical. This method is only used by the archaic function * DataFlavor.getTextPlainUnicodeFlavor(). * This method is called for text flavor mappings established while parsing * parameters which are not officially part of the MIME type. They are * Determines whether the native corresponding to the specified long format * Specifies whether text imported from the native system in the specified * format is locale-dependent. If so, when decoding such text, * 'nativeCharsets' should be ignored, and instead, the Transferable should * be queried for its javaTextEncodingFlavor data for the correct encoding. * Determines whether the DataFlavor corresponding to the specified long * Determines whether the DataFlavor corresponding to the specified long * format is DataFlavor.imageFlavor. * Determines whether the format is a URI list we can convert to * Returns a Map whose keys are all of the possible formats into which the * Transferable's transfer data flavors can be translated. The value of * each key is the DataFlavor in which the Transferable's data should be * requested when converting to the format. * The map keys are sorted according to the native formats preference * Returns a Map whose keys are all of the possible formats into which data * in the specified DataFlavor can be translated. The value of each key * is the DataFlavor in which a Transferable's data should be requested * when converting to the format. * The map keys are sorted according to the native formats preference * Returns a Map whose keys are all of the possible formats into which data * in the specified DataFlavors can be translated. The value of each key * is the DataFlavor in which the Transferable's data should be requested * when converting to the format. * The map keys are sorted according to the native formats preference * @param flavors the data flavors * @param map the FlavorTable which contains mappings between * DataFlavors and data formats * @throws NullPointerException if flavors or map is <code>null</code> // Maps formats to indices that will be used to sort the formats // according to the preference order. // Larger index value corresponds to the more preferable format. // Iterate backwards so that preferred DataFlavors are used over // other DataFlavors. (See javadoc for // Transferable.getTransferDataFlavors.) // Don't explicitly test for String, since it is just a special // SystemFlavorMap.getNativesForFlavor will return // text/plain natives for all text/*. While this is good // for a single text/* flavor, we would prefer that // Sort the map keys according to the formats preference order. * Reduces the Map output for the root function to an array of the * Returns a Map whose keys are all of the possible DataFlavors into which * data in the specified format can be translated. The value of each key * is the format in which the Clipboard or dropped data should be requested * when converting to the DataFlavor. * Returns a Map whose keys are all of the possible DataFlavors into which * data in the specified formats can be translated. The value of each key * is the format in which the Clipboard or dropped data should be requested * when converting to the DataFlavor. // First step: build flavorSet, mappingSet and initial flavorMap // flavorSet - the set of all the DataFlavors into which // data in the specified formats can be translated; // mappingSet - the set of all the mappings from the specified formats // flavorMap - after this step, this map maps each of the DataFlavors // from flavorSet to any of the specified formats. // Don't explicitly test for String, since it is just a special // Second step: for each DataFlavor try to figure out which of the // specified formats is the best to translate to this flavor. // Then map each flavor to the best format. // For the given flavor, FlavorTable indicates which native will // best reflect data in the specified flavor to the underlying native // platform. We assume that this native is the best to translate // Note: FlavorTable allows one-way mappings, so we can occasionally // map a flavor to the format for which the corresponding // format-to-flavor mapping doesn't exist. For this reason we have built // a mappingSet of all format-to-flavor mappings for the specified formats // and check if the format-to-flavor mapping exists for the // (flavor,format) pair being added. * Returns a Set of all DataFlavors for which * 1) a mapping from at least one of the specified formats exists in the * 2) the data translation for this mapping can be performed by the data * @param formats the data formats * @param map the FlavorTable which contains mappings between * DataFlavors and data formats * @throws NullPointerException if formats or map is <code>null</code> // Don't explicitly test for String, since it is just a special * Returns an array of all DataFlavors for which * 1) a mapping from the specified format exists in the specified map and * 2) the data translation for this mapping can be performed by the data * The array will be sorted according to a * <code>DataFlavorComparator</code> created with the specified * @param format the data format * @param map the FlavorTable which contains mappings between * DataFlavors and data formats * @throws NullPointerException if map is <code>null</code> * Returns an array of all DataFlavors for which * 1) a mapping from at least one of the specified formats exists in the * 2) the data translation for this mapping can be performed by the data * The array will be sorted according to a * <code>DataFlavorComparator</code> created with the specified * @param formats the data formats * @param map the FlavorTable which contains mappings between * DataFlavors and data formats * @throws NullPointerException if formats or map is <code>null</code> // getFlavorsForFormatsAsSet() is less expensive than // getFlavorsForFormats(). * Returns an object that represents a mapping between the specified * key and value. <tt>null</tt> values and the <tt>null</tt> keys are * permitted. The internal representation of the mapping object is * irrelevant. The only requrement is that the two mapping objects are equal * if and only if their keys are equal and their values are equal. * More formally, the two mapping objects are equal if and only if * <tt>(value1 == null ? value2 == null : value1.equals(value2)) * && (key1 == null ? key2 == null : key1.equals(key2))</tt>. // NOTE: Should be updated to use AbstractMap.SimpleEntry as // soon as it is made public. * Looks-up or registers the String native with the native data transfer * system and returns a long format corresponding to that native. * Looks-up the String native corresponding to the specified long format in * the native data transfer system. /* Contains common code for finding the best charset for * format and localeTransferable(on decoding, if available) // Only happens when we have a custom text type. * Translation function for converting string into * a byte array. Search-and-replace EOLN. Encode into the * target format. Append terminating NUL bytes. * Java to Native string conversion // Search and replace EOLN. Note that if EOLN is "\n", then we // never added an entry to nativeEOLNs anyway, so we'll skip this // windows: "abc\nde"->"abc\r\nde" for (
int i =
0; i <
length; i++) {
// Fix for 4914613 - skip native EOLN // Encode text in target format. // Append terminating NUL bytes. Note that if terminators is 0, // the we never added an entry to nativeTerminators anyway, so // we'll skip code altogether. * Translating either a byte array or an InputStream into an String. * Strip terminators and search-and-replace EOLN. * Native to Java string conversion // A String holds all of its data in memory at one time, so // we can't avoid reading the entire InputStream at this point. // Locate terminating NUL bytes. Note that if terminators is 0, // the we never added an entry to nativeTerminators anyway, so // we'll skip code altogether. // In other words: we are doing char alignment here basing on suggestion // that count of zero-'terminators' is a number of bytes in one symbol // for selected charset (clipboard format). It is not complitly true for // multibyte coding like UTF-8, but helps understand the procedure. // Decode text to chars. Don't include any terminators. // Search and replace EOLN. Note that if EOLN is "\n", then we // never added an entry to nativeEOLNs anyway, so we'll skip this // Count of NUL-terminators and EOLN coding are platform-specific and // windows: "abc\r\nde" -> "abc\nde" /* Fix for 4463560: replace EOLNs symbol-by-symbol instead * Primary translation function for translating a Transferable into * a byte array, given a source DataFlavor and target format. // Obtain the transfer data in the source DataFlavor. // Note that we special case DataFlavor.plainTextFlavor because // StringSelection supports this flavor incorrectly -- instead of // returning an InputStream as the DataFlavor representation class // states, it returns a Reader. Instead of using this broken // functionality, we request the data in stringFlavor (the other // DataFlavor which StringSelection supports) and use the String // Source data is a String. Search-and-replace EOLN. Encode into the // target format. Append terminating NUL bytes. // Source data is a Reader. Convert to a String and recur. In the // future, we may want to rewrite this so that we encode on demand. (
"cannot transfer non-text data as Reader");
while ((c = r.
read()) != -
1) {
// Source data is a CharBuffer. Convert to a String and recur. (
"cannot transfer non-text data as CharBuffer");
// Source data is a char array. Convert to a String and recur. (
"cannot transfer non-text data as char array");
// Source data is a ByteBuffer. For arbitrary flavors, simply return // the array. For text flavors, decode back to a String and recur to // reencode according to the requested format. // Source data is a byte array. For arbitrary flavors, simply return // the array. For text flavors, decode back to a String and recur to // reencode according to the requested format. "cannot convert java image to native format");
// Target data is a file list. Source data must be a // java.util.List which contains java.io.File or String instances. // Target data is a URI list. Source data must be a // java.util.List which contains java.io.File or String instances. // Some implementations are fussy about the number of slashes (file:///path/to/file is best) // Source data is an InputStream. For arbitrary flavors, just grab the // bytes and dump them into a byte array. For text flavors, decode back // to a String and recur to reencode according to the requested format. // Source data is an RMI object // Source data is Serializable // It is important do not use user's successors "deployment.system.cachedir",
"deployment.user.cachedir",
* Primary translation function for translating either a byte array or * an InputStream into an Object, given a source format and a target * One of str/bytes is non-null; the other is null. * The conversion from byte[] to InputStream is cheap, so do that * immediately if necessary. The opposite conversion is expensive, * so avoid it if possible. // Source data is a file list. Use the dragQueryFile native function to // do most of the decoding. Then wrap File objects around the String // filenames and return a List. // Convert the strings to File objects // Turn the list of Files into a List and return // When converting from URIs to less generic files, // common practice (Wine, SWT) seems to be to // silently drop the URIs that aren't local files. // Target data is a String. Strip terminating NUL bytes. Decode bytes // into characters. Search-and-replace EOLN. // Special hack to maintain backwards-compatibility with the brokenness // of StringSelection. Return a StringReader instead of an InputStream. // Recur to obtain String and encapsulate. // Target data is an InputStream. For arbitrary flavors, just return // the raw bytes. For text flavors, decode to strip terminators and // search-and-replace EOLN, then reencode according to the requested // Target data is a Reader. Obtain data in InputStream format, encoded // as "Unicode" (utf-16be). Then use an InputStreamReader to decode // back to chars on demand. (
"cannot transfer non-text data as Reader");
// Target data is a CharBuffer. Recur to obtain String and wrap. (
"cannot transfer non-text data as CharBuffer");
// Target data is a char array. Recur to obtain String and convert to (
"cannot transfer non-text data as char array");
// Target data is a ByteBuffer. For arbitrary flavors, just return // the raw bytes. For text flavors, convert to a String to strip // terminators and search-and-replace EOLN, then reencode according to // Target data is a byte array. For arbitrary flavors, just return // the raw bytes. For text flavors, convert to a String to strip // terminators and search-and-replace EOLN, then reencode according to // Target data is an RMI object // Target data is Serializable * For arbitrary flavors, just use the raw InputStream. For text flavors, * ReencodingInputStream will decode and reencode the InputStream on demand * so that we can strip terminators and search-and-replace EOLN. * We support representations which are exactly of the specified Class, * and also arbitrary Objects which have a constructor which takes an * instance of the Class as its sole parameter. return arg;
// simple case * Used for decoding and reencoding an InputStream on demand so that we * can strip NUL terminators and perform EOLN search-and-replace. protected final char[]
in =
new char[
2];
// Only happens when we have a custom text type. // Throw NullPointerException for compatibility with the former // call to sun.io.CharToByteConverter.getConverter(null) // (Charset.forName(null) throws unspecified IllegalArgumentException // A hope and a prayer that this works generically. This will // definitely work on Win32. if (c == -
1) {
// -1 is EOS // "c == 0" is not quite correct, but good enough on Windows. // deal with supplementary characters * Checks to see if the next array.length characters in wrapped * match array. The first character is provided as c. Subsequent * characters are read from wrapped itself. When this method returns, * the wrapped index may be different from what it was when this if ((
char)c ==
array[
0]) {
* Decodes a byte array into a set of String filenames. * Decodes URIs from either a byte array or a stream. * Translates either a byte array or an input stream which contain * platform-specific image data in the given format into an Image. * Translates either a byte array or an input stream which contain * an image data in the given standard format into an Image. throw new IOException(
"No registered service provider can decode " +
* Translates a Java Image into a byte array which contains platform- * specific image data in the given format. * Translates a Java Image into a byte array which contains * an image data in the given standard format. throw new IOException(
"No registered service provider can encode " +
// Try to encode the original image. // Retry with a BufferedImage. ioe =
new IOException(
"Registered service providers failed to encode " * Concatenates the data represented by two objects. Objects can be either * byte arrays or instances of <code>InputStream</code>. If both arguments * are byte arrays byte array will be returned. Otherwise an * <code>InputStream</code> will be returned. * Currently is only called from native code to prepend palette data to * platform-specific image data during image transfer on Win32. * @param obj1 the first object to be concatenated. * @param obj2 the second object to be concatenated. * @return a byte array or an <code>InputStream</code> which represents * a logical concatenation of the two arguments. * @throws NullPointerException is either of the arguments is * @throws ClassCastException is either of the arguments is * neither byte array nor an instance of <code>InputStream</code>. if (
obj1 instanceof byte[]) {
if (
obj2 instanceof byte[]) {
if (
obj2 instanceof byte[]) {
* If the current thread is the Toolkit thread we should post a * Runnable to the event dispatch thread associated with source Object, * since translateTransferable() calls Transferable.getTransferData() * that may contain client code. // Guard against multiple executions. private boolean done =
false;
* Helper function to reduce a Map with Long keys to a long array. * The map keys are sorted according to the native formats preference * Helper function to reduce a Map with DataFlavor keys to a DataFlavor * array. The array will be sorted according to * <code>DataFlavorComparator</code>. * Helper function to convert a Set of DataFlavors to a sorted array. * The array will be sorted according to <code>DataFlavorComparator</code>. * Helper function to convert a Set of DataFlavors to a sorted array. * The array will be sorted according to a * <code>DataFlavorComparator</code> created with the specified * flavor-to-native map as an argument. * Helper function to convert an InputStream to a byte[] array. byte[]
buf =
new byte[
8192];
* Returns platform-specific mappings for the specified native. * If there are no platform-specific mappings for this native, the method * returns an empty <code>List</code>. * Returns platform-specific mappings for the specified flavor. * If there are no platform-specific mappings for this flavor, the method * returns an empty <code>List</code>. * A Comparator which includes a helper function for comparing two Objects * which are likely to be keys in the specified Map. * The best Object (e.g., DataFlavor) will be the last in sequence. * The best Object (e.g., DataFlavor) will be the first in sequence. protected final boolean 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 * 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 * 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 // we prefer Unicode charsets // US-ASCII is the worst charset supported * 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 * @throws ClassCastException if either of the arguments is not * @throws NullPointerException if either of the arguments is * Compares charsets. Returns a negative integer, zero, or a positive * integer as the first charset is worse than, equal to, or better than * Charsets are ordered according to the following rules: * <li>All unsupported charsets are equal. * <li>Any unsupported charset is worse than any supported charset. * <li>Unicode charsets, such as "UTF-16", "UTF-8", "UTF-16BE" and * "UTF-16LE", are considered best. * <li>After them, platform default charset is selected. * <li>"US-ASCII" is the worst of supported charsets. * <li>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 * Returns encoding for the specified charset according to the * <li>If the charset is <code>null</code>, then <code>null</code> will * <li>Iff the charset specifies an encoding unsupported by this JRE, * <code>UNSUPPORTED_CHARSET</code> will be returned. * <li>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. // 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 * 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 * 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 // First, compare MIME types // 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. // Next, prefer the decoded text representations of Reader, // String, CharBuffer, and [C, in that order. // Next, compare charsets // Finally, prefer the encoded text representations of // InputStream, ByteBuffer, and [B, in that order. // First, prefer application types. // MIME types because if the user provides his own data flavor, // it will likely be the most descriptive one. // Finally, prefer the representation classes of Remote, // Serializable, and InputStream, in that order. // As a last resort, take the DataFlavor with the greater integer * Given the Map that maps objects to Integer indices and a boolean value, * this Comparator imposes a direct or reverse order on set of objects. * If the specified boolean value is SELECT_BEST, the Comparator imposes the * direct index-based order: an object A is greater than an object B if and * only if the index of A is greater than the index of B. An object that * doesn't have an associated index is less or equal than any other object. * If the specified boolean value is SELECT_WORST, the Comparator imposes the * reverse index-based order: an object A is greater than an object B if and * only if A is less than B with the direct index-based order. * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject * without creating a static dependency. private static class RMI {
* Returns {@code true} if the given class is java.rmi.Remote. * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}. * Returns a new MarshalledObject containing the serialized representation * Returns a new copy of the contained marshalled object.