/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* 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");
*/
/**
* Cached value of Class.forName("[B");
*/
/**
* The <code>DataFlavor</code> representing plain text with Unicode
* encoding, where:
* <pre>
* representationClass = java.lang.String
* </pre>
*/
/**
* The <code>DataFlavor</code> representing a Java text encoding String
* encoded in UTF-8, where
* <pre>
* representationClass = [B
* mimeType = "application/x-java-text-encoding"
* </pre>
*/
/**
* Lazy initialization of Standard Encodings.
*/
private static class StandardEncodingsHolder {
final Comparator comparator =
}
}
/**
* 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 collection of all natives listed in flavormap.properties with
* 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.
*/
private static final PlatformLogger dtLog = PlatformLogger.getLogger("sun.awt.datatransfer.DataTransfer");
static {
try {
} catch (ClassNotFoundException cannotHappen) {
}
try {
} catch (ClassNotFoundException cannotHappen) {
}
try {
("application/x-java-text-encoding;class=\"[B\"");
} catch (ClassNotFoundException cannotHappen) {
}
}
/**
* 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.
*/
synchronized (DataTransferer.class) {
if (transferer == null) {
{
public DataTransferer run() {
try {
} catch (ClassNotFoundException e) {
try {
} catch (ClassNotFoundException ee) {
}
}
}
try {
method.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
try {
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return ret;
}
};
}
}
}
return transferer;
}
/**
* Converts an arbitrary text encoding to its canonical name.
*/
return null;
}
try {
} catch (IllegalCharsetNameException icne) {
return encoding;
} catch (UnsupportedCharsetException uce) {
return encoding;
}
}
/**
* 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.
*/
if (!isFlavorCharsetTextType(flavor)) {
return null;
}
}
/**
* Returns the platform's default character encoding.
*/
if (defaultEncoding != null) {
return defaultEncoding;
}
}
/**
* Tests only whether the flavor's MIME type supports the charset
* parameter. Must only be called for flavors with a primary type of
* "text".
*/
}
}
return false;
}
}
return ret_val;
}
{
}
return ret_val;
}
/**
* Returns whether this flavor is a text type which supports the
* 'charset' parameter.
*/
// 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
return true;
}
{
return false;
}
if (flavor.isRepresentationClassReader() ||
{
return true;
}
if (!(flavor.isRepresentationClassInputStream() ||
return false;
}
: true; // null equals default encoding which is always supported
}
/**
* Returns whether this flavor is a text type which does not support the
* 'charset' parameter.
*/
{
return false;
}
return (flavor.isRepresentationClassInputStream() ||
}
/**
* Determines whether this JRE can both encode and decode text in the
* specified encoding.
*/
return false;
}
try {
} catch (IllegalCharsetNameException icne) {
return false;
}
}
/**
* 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.
*/
if (map instanceof FlavorTable) {
return (FlavorTable)map;
}
return new FlavorTable() {
}
}
return list;
} else {
return Collections.EMPTY_LIST;
}
}
return list;
} else {
return Collections.EMPTY_LIST;
}
}
};
}
/**
* 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
* the flavormap.properties file. It stores the "eoln" and "terminators"
* parameters which are not officially part of the MIME type. They are
* MIME parameters specific to the flavormap.properties file format.
*/
? charset : getDefaultTextCharset());
}
}
}
}
/**
* Determines whether the native corresponding to the specified long format
* was listed in the flavormap.properties file.
*/
}
}
/**
* 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
* format is DataFlavor.javaFileListFlavor.
*/
/**
* 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
* a DataFlavor.javaFileListFlavor.
*/
return false;
}
/**
* 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.
* <p>
* The map keys are sorted according to the native formats preference
* order.
*/
FlavorTable map) {
return new TreeMap();
}
}
/**
* 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.
* <p>
* The map keys are sorted according to the native formats preference
* order.
*/
map);
}
/**
* 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.
* <p>
* The map keys are sorted according to the native formats preference
* order.
*
* @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.
int currentIndex = 0;
// 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
// case of Serializable
if (flavor.isFlavorTextType() ||
{
// SystemFlavorMap.getNativesForFlavor will return
// for a single text/* flavor, we would prefer that
{
}
}
}
}
// Sort the map keys according to the formats preference order.
return sortedMap;
}
/**
* Reduces the Map output for the root function to an array of the
* Map's keys.
*/
FlavorTable map) {
}
FlavorTable map) {
}
FlavorTable map) {
}
/**
* 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
// into any DataFlavor;
// 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
// case of Serializable
if (flavor.isFlavorTextType() ||
{
}
}
}
// 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
// to this flavor.
// 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.
flavorIter.hasNext(); ) {
nativeIter.hasNext(); ) {
break;
}
}
}
return flavorMap;
}
/**
* Returns a Set of all DataFlavors for which
* 1) a mapping from at least one of the specified formats exists in the
* specified map and
* 2) the data translation for this mapping can be performed by the data
* transfer subsystem.
*
* @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
// case of Serializable
if (flavor.isFlavorTextType() ||
{
}
}
}
return flavorSet;
}
/**
* 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
* transfer subsystem.
* The array will be sorted according to a
* <code>DataFlavorComparator</code> created with the specified
* map as an argument.
*
* @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>
*/
FlavorTable map) {
}
/**
* Returns an array of all DataFlavors for which
* 1) a mapping from at least one of the specified formats exists in the
* specified map and
* 2) the data translation for this mapping can be performed by the data
* transfer subsystem.
* The array will be sorted according to a
* <code>DataFlavorComparator</code> created with the specified
* map as an argument.
*
* @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>
*/
FlavorTable map) {
// 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)
*/
{
if (localeTransferable != null &&
{
try {
"UTF-8"
);
} catch (UnsupportedFlavorException cannotHappen) {
}
} else {
}
// Only happens when we have a custom text type.
}
return charset;
}
/**
* 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
*/
long format) throws IOException
{
// Search and replace EOLN. Note that if EOLN is "\n", then we
// never added an entry to nativeEOLNs anyway, so we'll skip this
// code altogether.
// windows: "abc\nde"->"abc\r\nde"
for (int i = 0; i < length; i++) {
// Fix for 4914613 - skip native EOLN
continue;
}
if (c == '\n') {
} else {
}
}
}
// 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.
// "abcde" -> "abcde\0"
if (terminators != null) {
byte[] terminatedBytes =
terminatedBytes[i] = 0x0;
}
}
return bytes;
}
/**
* Translating either a byte array or an InputStream into an String.
* Strip terminators and search-and-replace EOLN.
*
* Native to Java string conversion
*/
long format,
throws IOException
{
// 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.
// "abcde\0" -> "abcde"
int count;
if (terminators != null) {
if (bytes[i] != 0x0) {
continue search;
}
}
// found terminators
break search;
}
} else {
}
// 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
// code altogether.
// Count of NUL-terminators and EOLN coding are platform-specific and
// loaded from flavormap.properties file
// windows: "abc\r\nde" -> "abc\nde"
/* Fix for 4463560: replace EOLNs symbol-by-symbol instead
* of using buf.replace()
*/
int j = 0;
boolean match;
// Catch last few bytes
continue;
}
match = true;
match = false;
break;
}
}
if (match) {
buf[j++] = '\n';
} else {
}
}
}
return converted;
}
/**
* Primary translation function for translating a Transferable into
* a byte array, given a source DataFlavor and target format.
*/
long format) throws IOException
{
// 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
// translator.
boolean stringSelectionHack;
try {
return null;
}
!(obj instanceof InputStream))
{
return null;
}
stringSelectionHack = true;
} else {
stringSelectionHack = false;
}
} catch (UnsupportedFlavorException e) {
throw new IOException(e.getMessage());
}
// Source data is a String. Search-and-replace EOLN. Encode into the
// target format. Append terminating NUL bytes.
if (stringSelectionHack ||
return translateTransferableString(
str,
format);
// 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.
} else if (flavor.isRepresentationClassReader()) {
throw new IOException
("cannot transfer non-text data as Reader");
}
int c;
while ((c = r.read()) != -1) {
}
r.close();
return translateTransferableString(
format);
// Source data is a CharBuffer. Convert to a String and recur.
} else if (flavor.isRepresentationClassCharBuffer()) {
throw new IOException
("cannot transfer non-text data as CharBuffer");
}
return translateTransferableString(
format);
// Source data is a char array. Convert to a String and recur.
throw new IOException
("cannot transfer non-text data as char array");
}
return translateTransferableString(
format);
// 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.
} else if (flavor.isRepresentationClassByteBuffer()) {
return translateTransferableString(
format);
} else {
return bytes;
}
// 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.
return translateTransferableString(
format);
} else {
return bytes;
}
// Source data is Image
if (!isImageFormat(format)) {
throw new IOException("Data translation failed: " +
"not an image format");
}
throw new IOException("Data translation failed: " +
"cannot convert java image to native format");
}
return bytes;
}
// Target data is a file list. Source data must be a
// java.util.List which contains java.io.File or String instances.
if (isFileFormat(format)) {
throw new IOException("data translation failed");
}
// Target data is a URI list. Source data must be a
// java.util.List which contains java.io.File or String instances.
} else if (isURIListFormat(format)) {
throw new IOException("data translation failed");
}
try {
} catch (ClassNotFoundException cnfe) {
throw new IOException(cnfe);
}
}
if (targetCharset == null) {
targetCharset = "UTF-8";
}
try {
} catch (URISyntaxException uriSyntaxException) {
throw new IOException(uriSyntaxException);
}
}
}
// 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.
} else if (flavor.isRepresentationClassInputStream()) {
boolean eof = false;
do {
int ret;
}
} while (!eof);
return translateTransferableString(
format);
}
// Source data is an RMI object
} else if (flavor.isRepresentationClassRemote()) {
// Source data is Serializable
} else if (flavor.isRepresentationClassSerializable()) {
} else {
throw new IOException("data translation failed");
}
return ret;
}
protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException;
private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str)
throws IOException
{
{
return str;
}
try {
{
!(isFileInWebstartedCache(file) ||
{
{
}
}
}
return allowedFiles.toString();
}
});
} catch (PrivilegedActionException pae) {
}
return ret_val;
}
}
{
if (null == protectionDomain) {
return false;
}
try {
return false;
}
} catch (IOException e) {}
return true;
}
{
try {
{
!(isFileInWebstartedCache(file) ||
{
}
}
return null;
}
});
} catch (PrivilegedActionException pae) {
}
return fileList;
}
// It is important do not use user's successors
// of File class.
if (fileObject instanceof File) {
} else if (fileObject instanceof String) {
} else {
return null;
}
}
"deployment.system.cachedir",
"deployment.user.cachedir",
"deployment.javaws.cachedir",
"deployment.javapi.cachedir"
};
if (deploymentCacheDirectoryList.isEmpty()) {
if (cacheDirectoryPath != null) {
try {
if (cacheDirectory != null) {
}
} catch (IOException ioe) {}
}
}
}
return true;
}
}
}
return false;
}
throws IOException
{
}
throws IOException
{
}
/**
* Primary translation function for translating either a byte array or
* an InputStream into an Object, given a source format and a target
* DataFlavor.
*
* The conversion from byte[] to InputStream is cheap, so do that
* immediately if necessary. The opposite conversion is expensive,
* so avoid it if possible.
*/
throws IOException
{
}
// 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.
if (isFileFormat(format)) {
throw new IOException("data translation failed");
}
}
return null;
}
// Convert the strings to File objects
}
// Turn the list of Files into a List and return
// Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
// where possible.
try {
return null;
}
try {
} catch (IllegalArgumentException illegalArg) {
// 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.
}
}
return files;
} finally {
}
// Target data is a String. Strip terminating NUL bytes. Decode bytes
// into characters. Search-and-replace EOLN.
return translateBytesOrStreamToString(
// Special hack to maintain backwards-compatibility with the brokenness
// of StringSelection. Return a StringReader instead of an InputStream.
// Recur to obtain String and encapsulate.
return new StringReader(translateBytesOrStreamToString(
// 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
// flavor.
} else if (flavor.isRepresentationClassInputStream()) {
// 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.
} else if (flavor.isRepresentationClassReader()) {
throw new IOException
("cannot transfer non-text data as Reader");
}
// Target data is a CharBuffer. Recur to obtain String and wrap.
} else if (flavor.isRepresentationClassCharBuffer()) {
throw new IOException
("cannot transfer non-text data as CharBuffer");
}
// Target data is a char array. Recur to obtain String and convert to
// char array.
throw new IOException
("cannot transfer non-text data as char array");
}
return translateBytesOrStreamToString(
// 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
// the requested flavor.
} else if (flavor.isRepresentationClassByteBuffer()) {
).getBytes(
);
} else {
}
}
// 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
// the requested flavor.
return translateBytesOrStreamToString(
).getBytes(
);
} else {
}
// Target data is an RMI object
} else if (flavor.isRepresentationClassRemote()) {
try {
return ret;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
// Target data is Serializable
} else if (flavor.isRepresentationClassSerializable()) {
try {
return ret;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
// Target data is Image
if (!isImageFormat(format)) {
throw new IOException("data translation failed");
}
return image;
}
throw new IOException("data translation failed");
}
/**
* 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.
*/
{
str = new ReencodingInputStream
}
}
/**
* 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.
*/
throws IOException
{
return arg; // simple case
} else {
try {
constructors = (Constructor[])
return dfrc.getConstructors();
}
});
} catch (SecurityException se) {
}
continue;
}
constructor = constructors[j];
break;
}
}
if (constructor == null) {
}
try {
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
}
/**
* Used for decoding and reencoding an InputStream on demand so that we
* can strip NUL terminators and perform EOLN search-and-replace.
*/
protected byte[] out;
protected char[] eoln;
protected int numTerminators;
protected boolean eos;
throws IOException
{
if (isLocaleDependentTextFormat(format) &&
localeTransferable != null &&
{
try {
"UTF-8");
} catch (UnsupportedFlavorException cannotHappen) {
}
} else {
}
if (sourceEncoding == null) {
// Only happens when we have a custom text type.
}
wrapped = new BufferedReader
if (targetEncoding == null) {
// Throw NullPointerException for compatibility with the former
// call to sun.io.CharToByteConverter.getConverter(null)
// (Charset.forName(null) throws unspecified IllegalArgumentException
// now; see 6228568)
throw new NullPointerException("null target encoding");
}
try {
} catch (IllegalCharsetNameException e) {
throw new IOException(e.toString());
} catch (UnsupportedCharsetException e) {
throw new IOException(e.toString());
} catch (UnsupportedOperationException e) {
throw new IOException(e.toString());
}
}
// A hope and a prayer that this works generically. This will
// definitely work on Win32.
if (terminators != null) {
}
}
if (c == -1) { // -1 is EOS
eos = true;
return -1;
}
// "c == 0" is not quite correct, but good enough on Windows.
eos = true;
return -1;
c = '\n' & 0xFFFF;
}
return c;
}
if (eos) {
return -1;
}
// deal with supplementary characters
int c = readChar();
if (c == -1) {
return -1;
}
in[0] = (char) c;
if (Character.isHighSurrogate((char) c)) {
c = readChar();
if (c != -1) {
in[1] = (char) c;
}
}
index = 0;
return read();
} else {
}
}
}
}
/**
* 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
* method was called.
*/
throws IOException
{
int count = 0;
if ((char)c == array[0]) {
break;
}
}
}
return true;
} else {
return false;
}
}
}
/**
* Decodes a byte array into a set of String filenames.
*/
/**
* Decodes URIs from either a byte array or a stream.
*/
byte[] bytes,
long format,
throws IOException
{
throw new IOException(
new UnsupportedOperationException("not implemented on this platform"));
}
/**
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
*/
byte[] bytes,
long format)
throws IOException;
/**
* Translates either a byte array or an input stream which contain
* an image data in the given standard format into an Image.
*
*/
byte[] bytes,
throws IOException {
if (inputStream == null) {
}
if (!readerIterator.hasNext()) {
throw new IOException("No registered service provider can decode " +
" an image from " + mimeType);
}
while (readerIterator.hasNext()) {
try {
try {
if (bufferedImage != null) {
return bufferedImage;
}
} finally {
}
} catch (IOException e) {
ioe = e;
continue;
}
}
+ " an image from " + mimeType);
}
throw ioe;
}
/**
* Translates a Java Image into a byte array which contains platform-
* specific image data in the given format.
*/
throws IOException;
/**
* Translates a Java Image into a byte array which contains
* an image data in the given standard format.
*
*/
throws IOException {
if (!writerIterator.hasNext()) {
throw new IOException("No registered service provider can encode " +
" an image to " + mimeType);
}
if (image instanceof RenderedImage) {
// Try to encode the original image.
try {
} catch (IOException ioe) {
originalIOE = ioe;
}
}
// Retry with a BufferedImage.
int width = 0;
int height = 0;
if (image instanceof ToolkitImage) {
} else {
}
null);
try {
} finally {
g.dispose();
}
try {
} catch (IOException ioe) {
if (originalIOE != null) {
throw originalIOE;
} else {
throw ioe;
}
}
}
throws IOException {
while (writerIterator.hasNext()) {
continue;
}
try {
try {
} finally {
}
} catch (IOException e) {
ioe = e;
continue;
}
return baos.toByteArray();
}
}
throw ioe;
}
/**
* 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.
* <p>
* 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
* <code>null</code>
* @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[]) {
return ret;
} else {
}
} else {
if (obj2 instanceof byte[]) {
} else {
}
}
}
final Transferable contents,
final long format,
final boolean isToolkitThread)
throws IOException
{
/*
* 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.
*/
if (isToolkitThread) try {
// Guard against multiple executions.
private boolean done = false;
public void run() {
if (done) {
return;
}
try {
}
} catch (Exception e) {
e.printStackTrace();
}
try {
} finally {
done = true;
}
}
};
if (appContext != null) {
}
}
if (appContext != null) {
}
} finally {
} else {
}
}
return ret;
}
public void processDataConversionRequests() {
if (EventQueue.isDispatchThread()) {
try {
if (dataConverter != null) {
dataConverter.run();
}
} finally {
}
}
}
public abstract ToolkitThreadBlockedHandler
/**
* Helper function to reduce a Map with Long keys to a long array.
* <p>
* The map keys are sorted according to the native formats preference
* order.
*/
int i = 0;
}
return retval;
}
/**
* 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>.
*/
final Comparator comparator =
return flavors;
}
/**
* 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.
*/
{
return flavors;
}
/**
* Helper function to convert an InputStream to a byte[] array.
*/
throws IOException
{
int len = 0;
byte[] buf = new byte[8192];
}
return baos.toByteArray();
}
/**
* 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>.
*/
return new ArrayList();
}
/**
* 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>.
*/
return new ArrayList();
}
/**
* 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.
*/
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);
}
}
/**
* 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.
*/
}
}
}
/**
* 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.
*/
}
}
}
}
/**
* 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.
*/
static {
// we prefer Unicode charsets
// US-ASCII is the worst charset supported
}
}
public CharsetComparator() {
this(SELECT_BEST);
}
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
* <code>null</code>.
*/
if (order == SELECT_BEST) {
} else {
}
}
/**
* 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.
* <p>
* Charsets are ordered according to the following rules:
* <ul>
* <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.
* </ul>
*
* @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.
*/
if (comp == 0) {
}
return comp;
}
/**
* Returns encoding for the specified charset according to the
* following rules:
* <ul>
* <li>If the charset is <code>null</code>, then <code>null</code> will
* be returned.
* <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.
* </ul>
*
* @param charset the charset.
* @return an encoding for this charset.
*/
return null;
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.
: 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.
*/
static {
{
// application/x-java-* MIME types
}
{
}
{
if (remoteClass != null) {
}
}
{
// plain text
// stringFlavor
// misc
// enriched
// markup
}
{
}
{
}
}
public DataFlavorComparator() {
this(SELECT_BEST);
}
super(order);
}
this(map, SELECT_BEST);
}
super(order);
}
if (order == SELECT_BEST) {
} else {
}
return 0;
}
int comp = 0;
// First, compare MIME types
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.
if (comp != 0) {
return comp;
}
// Next, compare charsets
if (comp != 0) {
return comp;
}
}
// Finally, prefer the encoded text representations of
// InputStream, ByteBuffer, and [B, in that order.
if (comp != 0) {
return comp;
}
} else {
// First, prefer application types.
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.
if (comp != 0) {
return comp;
}
// Finally, prefer the representation classes of Remote,
// Serializable, and InputStream, in that order.
if (comp != 0) {
return comp;
}
}
// As a last resort, take the DataFlavor with the greater integer
// format.
}
}
/*
* 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.
* <p>
* 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.
* <p>
* 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.
*/
super(SELECT_BEST);
}
super(order);
}
if (order == SELECT_WORST) {
} else {
}
}
}
/**
* A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject
* without creating a static dependency.
*/
private static class RMI {
getClass("java.rmi.MarshalledObject");
try {
} catch (ClassNotFoundException e) {
return null;
}
}
try {
} catch (NoSuchMethodException x) {
throw new AssertionError(x);
}
}
try {
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
}
/**
* Returns {@code true} if the given class is java.rmi.Remote.
*/
}
/**
* Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}.
*/
return remoteClass;
}
/**
* Returns a new MarshalledObject containing the serialized representation
* of the given object.
*/
try {
} catch (InstantiationException x) {
throw new AssertionError(x);
} catch (IllegalAccessException x) {
throw new AssertionError(x);
} catch (InvocationTargetException x) {
if (cause instanceof IOException)
throw (IOException)cause;
throw new AssertionError(x);
}
}
/**
* Returns a new copy of the contained marshalled object.
*/
throws IOException, ClassNotFoundException
{
try {
} catch (IllegalAccessException x) {
throw new AssertionError(x);
} catch (InvocationTargetException x) {
if (cause instanceof IOException)
throw (IOException)cause;
if (cause instanceof ClassNotFoundException)
throw (ClassNotFoundException)cause;
throw new AssertionError(x);
}
}
}
}