src/share/classes/sun/awt/datatransfer/DataTransferer.java

Print this page




 154      *     representationClass = java.lang.String
 155      *     mimeType            = "text/plain; charset=Unicode"
 156      * </pre>
 157      */
 158     public static final DataFlavor plainTextStringFlavor;
 159 
 160     /**
 161      * The <code>DataFlavor</code> representing a Java text encoding String
 162      * encoded in UTF-8, where
 163      * <pre>
 164      *     representationClass = [B
 165      *     mimeType            = "application/x-java-text-encoding"
 166      * </pre>
 167      */
 168     public static final DataFlavor javaTextEncodingFlavor;
 169 
 170     /**
 171      * Lazy initialization of Standard Encodings.
 172      */
 173     private static class StandardEncodingsHolder {
 174         private static final SortedSet standardEncodings = load();
 175 
 176         private static SortedSet load() {
 177             final Comparator comparator =
 178                     new CharsetComparator(IndexedComparator.SELECT_WORST);
 179             final SortedSet tempSet = new TreeSet(comparator);
 180             tempSet.add("US-ASCII");
 181             tempSet.add("ISO-8859-1");
 182             tempSet.add("UTF-8");
 183             tempSet.add("UTF-16BE");
 184             tempSet.add("UTF-16LE");
 185             tempSet.add("UTF-16");
 186             tempSet.add(getDefaultTextCharset());
 187             return Collections.unmodifiableSortedSet(tempSet);
 188         }
 189     }
 190 
 191     /**
 192      * Tracks whether a particular text/* MIME type supports the charset
 193      * parameter. The Map is initialized with all of the standard MIME types
 194      * listed in the DataFlavor.selectBestTextFlavor method comment. Additional
 195      * entries may be added during the life of the JRE for text/<other> types.
 196      */
 197     private static final Map textMIMESubtypeCharsetSupport;
 198 
 199     /**


 506             return Charset.isSupported(encoding);
 507         } catch (IllegalCharsetNameException icne) {
 508             return false;
 509         }
 510     }
 511 
 512     /**
 513      * Returns {@code true} if the given type is a java.rmi.Remote.
 514      */
 515     public static boolean isRemote(Class<?> type) {
 516         return RMI.isRemote(type);
 517     }
 518 
 519     /**
 520      * Returns an Iterator which traverses a SortedSet of Strings which are
 521      * a total order of the standard character sets supported by the JRE. The
 522      * ordering follows the same principles as DataFlavor.selectBestTextFlavor.
 523      * So as to avoid loading all available character converters, optional,
 524      * non-standard, character sets are not included.
 525      */
 526     public static Iterator standardEncodings() {
 527         return StandardEncodingsHolder.standardEncodings.iterator();
 528     }
 529 
 530     /**
 531      * Converts a FlavorMap to a FlavorTable.
 532      */
 533     public static FlavorTable adaptFlavorMap(final FlavorMap map) {
 534         if (map instanceof FlavorTable) {
 535             return (FlavorTable)map;
 536         }
 537 
 538         return new FlavorTable() {
 539                 public Map getNativesForFlavors(DataFlavor[] flavors) {
 540                     return map.getNativesForFlavors(flavors);
 541                 }
 542                 public Map getFlavorsForNatives(String[] natives) {
 543                     return map.getFlavorsForNatives(natives);
 544                 }
 545                 public List getNativesForFlavor(DataFlavor flav) {
 546                     Map natives =
 547                         getNativesForFlavors(new DataFlavor[] { flav } );


1046         Integer terminators = (Integer)nativeTerminators.get(lFormat);
1047         if (terminators != null) {
1048             int numTerminators = terminators.intValue();
1049             byte[] terminatedBytes =
1050                 new byte[bytes.length + numTerminators];
1051             System.arraycopy(bytes, 0, terminatedBytes, 0, bytes.length);
1052             for (int i = bytes.length; i < terminatedBytes.length; i++) {
1053                 terminatedBytes[i] = 0x0;
1054             }
1055             bytes = terminatedBytes;
1056         }
1057         return bytes;
1058     }
1059 
1060     /**
1061      * Translating either a byte array or an InputStream into an String.
1062      * Strip terminators and search-and-replace EOLN.
1063      *
1064      * Native to Java string conversion
1065      */
1066     private String translateBytesOrStreamToString(InputStream str,  byte[] bytes,
1067                                                     long format,
1068                                                     Transferable localeTransferable)
1069             throws IOException
1070     {
1071         // A String holds all of its data in memory at one time, so
1072         // we can't avoid reading the entire InputStream at this point.
1073         if (bytes == null) {
1074             bytes = inputStreamToByteArray(str);
1075         }
1076         str.close();
1077 
1078         Long lFormat = Long.valueOf(format);
1079         String charset = getBestCharsetForTextFormat(lFormat, localeTransferable);
1080 
1081         // Locate terminating NUL bytes. Note that if terminators is 0,
1082         // the we never added an entry to nativeTerminators anyway, so
1083         // we'll skip code altogether.
1084 
1085         // In other words: we are doing char alignment here basing on suggestion
1086         // that count of zero-'terminators' is a number of bytes in one symbol
1087         // for selected charset (clipboard format). It is not complitly true for
1088         // multibyte coding like UTF-8, but helps understand the procedure.
1089         // "abcde\0" -> "abcde"
1090 
1091         String eoln = (String)nativeEOLNs.get(lFormat);
1092         Integer terminators = (Integer)nativeTerminators.get(lFormat);
1093         int count;
1094         if (terminators != null) {
1095             int numTerminators = terminators.intValue();
1096 search:


1199         // Source data is a String. Search-and-replace EOLN. Encode into the
1200         // target format. Append terminating NUL bytes.
1201         if (stringSelectionHack ||
1202             (String.class.equals(flavor.getRepresentationClass()) &&
1203              isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1204 
1205             String str = removeSuspectedData(flavor, contents, (String)obj);
1206 
1207             return translateTransferableString(
1208                 str,
1209                 format);
1210 
1211         // Source data is a Reader. Convert to a String and recur. In the
1212         // future, we may want to rewrite this so that we encode on demand.
1213         } else if (flavor.isRepresentationClassReader()) {
1214             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1215                 throw new IOException
1216                     ("cannot transfer non-text data as Reader");
1217             }
1218 
1219             Reader r = (Reader)obj;
1220             StringBuffer buf = new StringBuffer();

1221             int c;
1222             while ((c = r.read()) != -1) {
1223                 buf.append((char)c);
1224             }
1225             r.close();
1226 
1227             return translateTransferableString(
1228                 buf.toString(),
1229                 format);
1230 
1231         // Source data is a CharBuffer. Convert to a String and recur.
1232         } else if (flavor.isRepresentationClassCharBuffer()) {
1233             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1234                 throw new IOException
1235                     ("cannot transfer non-text data as CharBuffer");
1236             }
1237 
1238             CharBuffer buffer = (CharBuffer)obj;
1239             int size = buffer.remaining();
1240             char[] chars = new char[size];
1241             buffer.get(chars, 0, size);
1242 
1243             return translateTransferableString(
1244                 new String(chars),
1245                 format);


1287             } else {
1288                 return bytes;
1289             }
1290         // Source data is Image
1291         } else if (DataFlavor.imageFlavor.equals(flavor)) {
1292             if (!isImageFormat(format)) {
1293                 throw new IOException("Data translation failed: " +
1294                                       "not an image format");
1295             }
1296 
1297             Image image = (Image)obj;
1298             byte[] bytes = imageToPlatformBytes(image, format);
1299 
1300             if (bytes == null) {
1301                 throw new IOException("Data translation failed: " +
1302                     "cannot convert java image to native format");
1303             }
1304             return bytes;
1305         }
1306 
1307         ByteArrayOutputStream bos = new ByteArrayOutputStream();
1308 
1309         // Target data is a file list. Source data must be a
1310         // java.util.List which contains java.io.File or String instances.
1311         if (isFileFormat(format)) {
1312             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1313                 throw new IOException("data translation failed");
1314             }
1315 
1316             final List list = (List)obj;
1317 
1318             final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1319 
1320             final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
1321 
1322             bos = convertFileListToBytes(fileList);
1323 

1324 
1325         // Target data is a URI list. Source data must be a
1326         // java.util.List which contains java.io.File or String instances.
1327         } else if (isURIListFormat(format)) {
1328             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1329                 throw new IOException("data translation failed");
1330             }
1331             String nat = getNativeForFormat(format);
1332             String targetCharset = null;
1333             if (nat != null) {
1334                 try {
1335                     targetCharset = new DataFlavor(nat).getParameter("charset");
1336                 } catch (ClassNotFoundException cnfe) {
1337                     throw new IOException(cnfe);
1338                 }
1339             }
1340             if (targetCharset == null) {
1341                 targetCharset = "UTF-8";
1342             }
1343             final List list = (List)obj;
1344             final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1345             final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
1346             final ArrayList<String> uriList = new ArrayList<String>(fileList.size());
1347             for (String fileObject : fileList) {
1348                 final URI uri = new File(fileObject).toURI();
1349                 // Some implementations are fussy about the number of slashes (file:///path/to/file is best)
1350                 try {
1351                     uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString());
1352                 } catch (URISyntaxException uriSyntaxException) {
1353                     throw new IOException(uriSyntaxException);
1354                   }
1355               }
1356 
1357             byte[] eoln = "\r\n".getBytes(targetCharset);


1358             for (int i = 0; i < uriList.size(); i++) {
1359                 byte[] bytes = uriList.get(i).getBytes(targetCharset);
1360                 bos.write(bytes, 0, bytes.length);
1361                 bos.write(eoln, 0, eoln.length);
1362             }


1363 
1364         // Source data is an InputStream. For arbitrary flavors, just grab the
1365         // bytes and dump them into a byte array. For text flavors, decode back
1366         // to a String and recur to reencode according to the requested format.
1367         } else if (flavor.isRepresentationClassInputStream()) {
1368             InputStream is = (InputStream)obj;

1369             boolean eof = false;
1370             int avail = is.available();
1371             byte[] tmp = new byte[avail > 8192 ? avail : 8192];
1372             do {
1373                 int ret;
1374                 if (!(eof = (ret = is.read(tmp, 0, tmp.length)) == -1)) {
1375                     bos.write(tmp, 0, ret);
1376                 }
1377             } while (!eof);
1378             is.close();
1379 
1380             if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1381                 byte[] bytes = bos.toByteArray();
1382                 bos.close();
1383                 String sourceEncoding = DataTransferer.getTextCharset(flavor);
1384                 return translateTransferableString(
1385                     new String(bytes, sourceEncoding),
1386                     format);
1387             }




1388 
1389         // Source data is an RMI object
1390         } else if (flavor.isRepresentationClassRemote()) {

1391             Object mo = RMI.newMarshalledObject(obj);
1392             ObjectOutputStream oos = new ObjectOutputStream(bos);
1393             oos.writeObject(mo);
1394             oos.close();
1395 
1396         // Source data is Serializable
1397         } else if (flavor.isRepresentationClassSerializable()) {
1398             ObjectOutputStream oos = new ObjectOutputStream(bos);
1399             oos.writeObject(obj);
1400             oos.close();
1401 
1402         } else {
1403             throw new IOException("data translation failed");
1404         }
1405 
1406         byte[] ret = bos.toByteArray();
1407         bos.close();
1408         return ret;









1409     }
1410 
1411     protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException;
1412 
1413     private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str)
1414             throws IOException
1415     {
1416         if (null == System.getSecurityManager()
1417             || !flavor.isMimeTypeEqual("text/uri-list"))
1418         {
1419             return str;
1420         }
1421 
1422 
1423         String ret_val = "";
1424         final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1425 
1426         try {
1427             ret_val = (String) AccessController.doPrivileged(new PrivilegedExceptionAction() {
1428                     public Object run() {


1543                 }
1544             }
1545         }
1546 
1547         for (File deploymentCacheDirectory : deploymentCacheDirectoryList) {
1548             for (File dir = f; dir != null; dir = dir.getParentFile()) {
1549                 if (dir.equals(deploymentCacheDirectory)) {
1550                     return true;
1551                 }
1552             }
1553         }
1554 
1555         return false;
1556     }
1557 
1558 
1559     public Object translateBytes(byte[] bytes, DataFlavor flavor,
1560                                  long format, Transferable localeTransferable)
1561         throws IOException
1562     {
1563         return translateBytesOrStream(null, bytes, flavor, format,
1564                                       localeTransferable);
1565     }
1566 
1567     public Object translateStream(InputStream str, DataFlavor flavor,
1568                                   long format, Transferable localeTransferable)
1569         throws IOException
1570     {
1571         return translateBytesOrStream(str, null, flavor, format,
1572                                       localeTransferable);
1573     }
1574 
1575 
1576     /**
1577      * Primary translation function for translating either a byte array or
1578      * an InputStream into an Object, given a source format and a target
1579      * DataFlavor.
1580      *
1581      * One of str/bytes is non-null; the other is null.
1582      * The conversion from byte[] to InputStream is cheap, so do that
1583      * immediately if necessary. The opposite conversion is expensive,
1584      * so avoid it if possible.
1585      */
1586     protected Object translateBytesOrStream(InputStream str, byte[] bytes,
1587                                             DataFlavor flavor, long format,
1588                                             Transferable localeTransferable)
1589         throws IOException
1590     {
1591 
1592         if (str == null) {
1593             str = new ByteArrayInputStream(bytes);
1594         }
1595 
1596         // Source data is a file list. Use the dragQueryFile native function to
1597         // do most of the decoding. Then wrap File objects around the String
1598         // filenames and return a List.
1599         if (isFileFormat(format)) {
1600             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1601                 throw new IOException("data translation failed");
1602             }
1603             if (bytes == null) {
1604                 bytes = inputStreamToByteArray(str);
1605             }
1606             String[] filenames = dragQueryFile(bytes);
1607             if (filenames == null) {
1608                 str.close();
1609                 return null;
1610             }
1611 
1612             // Convert the strings to File objects
1613             File[] files = new File[filenames.length];
1614             for (int i = 0; i < filenames.length; i++) {
1615                 files[i] = new File(filenames[i]);
1616             }
1617             str.close();
1618 
1619             // Turn the list of Files into a List and return
1620             return Arrays.asList(files);
1621 
1622         // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
1623         // where possible.
1624         } else if (isURIListFormat(format) && DataFlavor.javaFileListFlavor.equals(flavor)) {
1625             try {
1626                 URI uris[] = dragQueryURIs(str, bytes, format, localeTransferable);
1627                 if (uris == null) {
1628                     return null;
1629                 }
1630                 ArrayList files = new ArrayList();
1631                 for (URI uri : uris) {
1632                     try {
1633                         files.add(new File(uri));
1634                     } catch (IllegalArgumentException illegalArg) {
1635                         // When converting from URIs to less generic files,
1636                         // common practice (Wine, SWT) seems to be to
1637                         // silently drop the URIs that aren't local files.
1638                     }
1639                 }
1640                 return files;
1641             } finally {
1642                 str.close();
1643             }
1644 
1645         // Target data is a String. Strip terminating NUL bytes. Decode bytes
1646         // into characters. Search-and-replace EOLN.
1647         } else if (String.class.equals(flavor.getRepresentationClass()) &&
1648                    isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1649 
1650             return translateBytesOrStreamToString(
1651                 str, bytes,
1652                 format, localeTransferable);
1653 
1654         // Special hack to maintain backwards-compatibility with the brokenness
1655         // of StringSelection. Return a StringReader instead of an InputStream.
1656         // Recur to obtain String and encapsulate.
1657         } else if (DataFlavor.plainTextFlavor.equals(flavor)) {
1658             return new StringReader(translateBytesOrStreamToString(
1659                         str, bytes,
1660                         format, localeTransferable));
1661 
1662         // Target data is an InputStream. For arbitrary flavors, just return
1663         // the raw bytes. For text flavors, decode to strip terminators and
1664         // search-and-replace EOLN, then reencode according to the requested
1665         // flavor.
1666         } else if (flavor.isRepresentationClassInputStream()) {
1667             return translateBytesOrStreamToInputStream(str, flavor, format,
1668                                                        localeTransferable);
1669 
1670         // Target data is a Reader. Obtain data in InputStream format, encoded
1671         // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
1672         // back to chars on demand.
1673         } else if (flavor.isRepresentationClassReader()) {
1674             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1675                 throw new IOException
1676                     ("cannot transfer non-text data as Reader");
1677             }
1678 
1679             InputStream is = (InputStream)
1680                 translateBytesOrStreamToInputStream
1681                     (str, DataFlavor.plainTextFlavor, format,
1682                      localeTransferable);
1683             String unicode =
1684                 DataTransferer.getTextCharset(DataFlavor.plainTextFlavor);
1685             Reader reader = new InputStreamReader(is, unicode);
1686 
1687             return constructFlavoredObject(reader, flavor, Reader.class);
1688 
1689         // Target data is a CharBuffer. Recur to obtain String and wrap.
1690         } else if (flavor.isRepresentationClassCharBuffer()) {
1691             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1692                 throw new IOException
1693                     ("cannot transfer non-text data as CharBuffer");
1694             }
1695 
1696             CharBuffer buffer = CharBuffer.wrap(translateBytesOrStreamToString(
1697                 str, bytes,
1698                 format, localeTransferable));
1699 
1700             return constructFlavoredObject(buffer, flavor, CharBuffer.class);
1701 
1702         // Target data is a char array. Recur to obtain String and convert to
1703         // char array.
1704         } else if (charArrayClass.equals(flavor.getRepresentationClass())) {
1705             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1706                 throw new IOException
1707                     ("cannot transfer non-text data as char array");
1708             }
1709 
1710             return translateBytesOrStreamToString(
1711                     str, bytes,
1712                     format, localeTransferable).toCharArray();
1713 
1714         // Target data is a ByteBuffer. For arbitrary flavors, just return
1715         // the raw bytes. For text flavors, convert to a String to strip
1716         // terminators and search-and-replace EOLN, then reencode according to
1717         // the requested flavor.
1718         } else if (flavor.isRepresentationClassByteBuffer()) {
1719             if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1720                 bytes = translateBytesOrStreamToString(
1721                     str, bytes,
1722                     format, localeTransferable
1723                 ).getBytes(
1724                     DataTransferer.getTextCharset(flavor)
1725                 );
1726             } else {
1727                 if (bytes == null) {
1728                     bytes = inputStreamToByteArray(str);
1729                 }
1730             }
1731 
1732             ByteBuffer buffer = ByteBuffer.wrap(bytes);
1733             return constructFlavoredObject(buffer, flavor, ByteBuffer.class);
1734 
1735         // Target data is a byte array. For arbitrary flavors, just return
1736         // the raw bytes. For text flavors, convert to a String to strip
1737         // terminators and search-and-replace EOLN, then reencode according to
1738         // the requested flavor.
1739         } else if (byteArrayClass.equals(flavor.getRepresentationClass())) {
1740             if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1741                 return translateBytesOrStreamToString(
1742                     str, bytes,
1743                     format, localeTransferable
1744                 ).getBytes(
1745                     DataTransferer.getTextCharset(flavor)
1746                 );
1747             } else {
1748                 return (bytes != null) ? bytes : inputStreamToByteArray(str);
1749             }
1750 
1751         // Target data is an RMI object
1752         } else if (flavor.isRepresentationClassRemote()) {
1753             try {
1754                 byte[] ba = inputStreamToByteArray(str);
1755                 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
1756                 Object ret = RMI.getMarshalledObject(ois.readObject());
1757                 ois.close();
1758                 str.close();
1759                 return ret;
1760             } catch (Exception e) {
1761                 throw new IOException(e.getMessage());
1762             }
1763 
1764         // Target data is Serializable
1765         } else if (flavor.isRepresentationClassSerializable()) {
1766             try {
1767                 byte[] ba = inputStreamToByteArray(str);
1768                 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
1769                 Object ret = ois.readObject();
1770                 ois.close();
1771                 str.close();
1772                 return ret;
1773             } catch (Exception e) {
1774                 throw new IOException(e.getMessage());
1775             }
1776 
1777         // Target data is Image
1778         } else if (DataFlavor.imageFlavor.equals(flavor)) {
1779             if (!isImageFormat(format)) {
1780                 throw new IOException("data translation failed");
1781             }
1782 
1783             Image image = platformImageBytesOrStreamToImage(str, bytes, format);
1784             str.close();
1785             return image;
1786         }
1787 

1788         throw new IOException("data translation failed");
1789     }
1790 



































































































1791     /**
1792      * For arbitrary flavors, just use the raw InputStream. For text flavors,
1793      * ReencodingInputStream will decode and reencode the InputStream on demand
1794      * so that we can strip terminators and search-and-replace EOLN.
1795      */
1796     private Object translateBytesOrStreamToInputStream
1797         (InputStream str, DataFlavor flavor, long format,
1798          Transferable localeTransferable) throws IOException
1799     {
1800         if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1801             str = new ReencodingInputStream
1802                 (str, format, DataTransferer.getTextCharset(flavor),
1803                  localeTransferable);
1804         }
1805 
1806         return constructFlavoredObject(str, flavor, InputStream.class);
1807     }
1808 
1809     /**
1810      * We support representations which are exactly of the specified Class,
1811      * and also arbitrary Objects which have a constructor which takes an
1812      * instance of the Class as its sole parameter.
1813      */
1814     private Object constructFlavoredObject(Object arg, DataFlavor flavor,
1815                                            Class clazz)
1816         throws IOException


2032             }
2033 
2034             if (count == array.length) {
2035                 return true;
2036             } else {
2037                 wrapped.reset();
2038                 return false;
2039             }
2040         }
2041     }
2042 
2043     /**
2044      * Decodes a byte array into a set of String filenames.
2045      */
2046     protected abstract String[] dragQueryFile(byte[] bytes);
2047 
2048     /**
2049      * Decodes URIs from either a byte array or a stream.
2050      */
2051     protected URI[] dragQueryURIs(InputStream stream,
2052                                   byte[] bytes,
2053                                   long format,
2054                                   Transferable localeTransferable)
2055       throws IOException
2056     {
2057         throw new IOException(
2058             new UnsupportedOperationException("not implemented on this platform"));
2059     }
2060 
2061     /**
2062      * Translates either a byte array or an input stream which contain
2063      * platform-specific image data in the given format into an Image.
2064      */
2065     protected abstract Image platformImageBytesOrStreamToImage(InputStream str,
2066                                                                byte[] bytes,
2067                                                                long format)
2068       throws IOException;
2069 
2070     /**
2071      * Translates either a byte array or an input stream which contain
2072      * an image data in the given standard format into an Image.
2073      *
2074      * @param mimeType image MIME type, such as: image/png, image/jpeg, image/gif
2075      */
2076     protected Image standardImageBytesOrStreamToImage(InputStream inputStream,
2077                                                       byte[] bytes,
2078                                                       String mimeType)
2079       throws IOException {
2080         if (inputStream == null) {
2081             inputStream = new ByteArrayInputStream(bytes);
2082         }
2083 
2084         Iterator readerIterator = ImageIO.getImageReadersByMIMEType(mimeType);
2085 
2086         if (!readerIterator.hasNext()) {
2087             throw new IOException("No registered service provider can decode " +
2088                                   " an image from " + mimeType);
2089         }
2090 
2091         IOException ioe = null;
2092 
2093         while (readerIterator.hasNext()) {
2094             ImageReader imageReader = (ImageReader)readerIterator.next();
2095             try {
2096                 ImageInputStream imageInputStream =
2097                     ImageIO.createImageInputStream(inputStream);
2098 
2099                 try {
2100                     ImageReadParam param = imageReader.getDefaultReadParam();
2101                     imageReader.setInput(imageInputStream, true, true);
2102                     BufferedImage bufferedImage =
2103                         imageReader.read(imageReader.getMinIndex(), param);
2104                     if (bufferedImage != null) {
2105                         return bufferedImage;
2106                     }
2107                 } finally {
2108                     imageInputStream.close();
2109                     imageReader.dispose();
2110                 }
2111             } catch (IOException e) {
2112                 ioe = e;
2113                 continue;
2114             }
2115         }
2116 
2117         if (ioe == null) {


2407 
2408     /**
2409      * Helper function to convert a Set of DataFlavors to a sorted array.
2410      * The array will be sorted according to <code>DataFlavorComparator</code>.
2411      */
2412     public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) {
2413         DataFlavor[] flavors = new DataFlavor[flavorsSet.size()];
2414         flavorsSet.toArray(flavors);
2415         final Comparator comparator =
2416                 new DataFlavorComparator(IndexedComparator.SELECT_WORST);
2417         Arrays.sort(flavors, comparator);
2418         return flavors;
2419     }
2420 
2421     /**
2422      * Helper function to convert an InputStream to a byte[] array.
2423      */
2424     protected static byte[] inputStreamToByteArray(InputStream str)
2425         throws IOException
2426     {
2427         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2428         int len = 0;
2429         byte[] buf = new byte[8192];
2430 
2431         while ((len = str.read(buf)) != -1) {
2432             baos.write(buf, 0, len);
2433         }
2434 
2435         return baos.toByteArray();

2436     }
2437 
2438     /**
2439      * Returns platform-specific mappings for the specified native.
2440      * If there are no platform-specific mappings for this native, the method
2441      * returns an empty <code>List</code>.
2442      */
2443     public List getPlatformMappingsForNative(String nat) {
2444         return new ArrayList();
2445     }
2446 
2447     /**
2448      * Returns platform-specific mappings for the specified flavor.
2449      * If there are no platform-specific mappings for this flavor, the method
2450      * returns an empty <code>List</code>.
2451      */
2452     public List getPlatformMappingsForFlavor(DataFlavor df) {
2453         return new ArrayList();
2454     }
2455 




 154      *     representationClass = java.lang.String
 155      *     mimeType            = "text/plain; charset=Unicode"
 156      * </pre>
 157      */
 158     public static final DataFlavor plainTextStringFlavor;
 159 
 160     /**
 161      * The <code>DataFlavor</code> representing a Java text encoding String
 162      * encoded in UTF-8, where
 163      * <pre>
 164      *     representationClass = [B
 165      *     mimeType            = "application/x-java-text-encoding"
 166      * </pre>
 167      */
 168     public static final DataFlavor javaTextEncodingFlavor;
 169 
 170     /**
 171      * Lazy initialization of Standard Encodings.
 172      */
 173     private static class StandardEncodingsHolder {
 174         private static final SortedSet<String> standardEncodings = load();
 175 
 176         private static SortedSet<String> load() {
 177             final Comparator comparator =
 178                     new CharsetComparator(IndexedComparator.SELECT_WORST);
 179             final SortedSet<String> tempSet = new TreeSet<String>(comparator);
 180             tempSet.add("US-ASCII");
 181             tempSet.add("ISO-8859-1");
 182             tempSet.add("UTF-8");
 183             tempSet.add("UTF-16BE");
 184             tempSet.add("UTF-16LE");
 185             tempSet.add("UTF-16");
 186             tempSet.add(getDefaultTextCharset());
 187             return Collections.unmodifiableSortedSet(tempSet);
 188         }
 189     }
 190 
 191     /**
 192      * Tracks whether a particular text/* MIME type supports the charset
 193      * parameter. The Map is initialized with all of the standard MIME types
 194      * listed in the DataFlavor.selectBestTextFlavor method comment. Additional
 195      * entries may be added during the life of the JRE for text/<other> types.
 196      */
 197     private static final Map textMIMESubtypeCharsetSupport;
 198 
 199     /**


 506             return Charset.isSupported(encoding);
 507         } catch (IllegalCharsetNameException icne) {
 508             return false;
 509         }
 510     }
 511 
 512     /**
 513      * Returns {@code true} if the given type is a java.rmi.Remote.
 514      */
 515     public static boolean isRemote(Class<?> type) {
 516         return RMI.isRemote(type);
 517     }
 518 
 519     /**
 520      * Returns an Iterator which traverses a SortedSet of Strings which are
 521      * a total order of the standard character sets supported by the JRE. The
 522      * ordering follows the same principles as DataFlavor.selectBestTextFlavor.
 523      * So as to avoid loading all available character converters, optional,
 524      * non-standard, character sets are not included.
 525      */
 526     public static Set <String> standardEncodings() {
 527         return StandardEncodingsHolder.standardEncodings;
 528     }
 529 
 530     /**
 531      * Converts a FlavorMap to a FlavorTable.
 532      */
 533     public static FlavorTable adaptFlavorMap(final FlavorMap map) {
 534         if (map instanceof FlavorTable) {
 535             return (FlavorTable)map;
 536         }
 537 
 538         return new FlavorTable() {
 539                 public Map getNativesForFlavors(DataFlavor[] flavors) {
 540                     return map.getNativesForFlavors(flavors);
 541                 }
 542                 public Map getFlavorsForNatives(String[] natives) {
 543                     return map.getFlavorsForNatives(natives);
 544                 }
 545                 public List getNativesForFlavor(DataFlavor flav) {
 546                     Map natives =
 547                         getNativesForFlavors(new DataFlavor[] { flav } );


1046         Integer terminators = (Integer)nativeTerminators.get(lFormat);
1047         if (terminators != null) {
1048             int numTerminators = terminators.intValue();
1049             byte[] terminatedBytes =
1050                 new byte[bytes.length + numTerminators];
1051             System.arraycopy(bytes, 0, terminatedBytes, 0, bytes.length);
1052             for (int i = bytes.length; i < terminatedBytes.length; i++) {
1053                 terminatedBytes[i] = 0x0;
1054             }
1055             bytes = terminatedBytes;
1056         }
1057         return bytes;
1058     }
1059 
1060     /**
1061      * Translating either a byte array or an InputStream into an String.
1062      * Strip terminators and search-and-replace EOLN.
1063      *
1064      * Native to Java string conversion
1065      */
1066     private String translateBytesToString(byte[] bytes, long format,

1067                                           Transferable localeTransferable)
1068             throws IOException
1069     {






1070 
1071         Long lFormat = Long.valueOf(format);
1072         String charset = getBestCharsetForTextFormat(lFormat, localeTransferable);
1073 
1074         // Locate terminating NUL bytes. Note that if terminators is 0,
1075         // the we never added an entry to nativeTerminators anyway, so
1076         // we'll skip code altogether.
1077 
1078         // In other words: we are doing char alignment here basing on suggestion
1079         // that count of zero-'terminators' is a number of bytes in one symbol
1080         // for selected charset (clipboard format). It is not complitly true for
1081         // multibyte coding like UTF-8, but helps understand the procedure.
1082         // "abcde\0" -> "abcde"
1083 
1084         String eoln = (String)nativeEOLNs.get(lFormat);
1085         Integer terminators = (Integer)nativeTerminators.get(lFormat);
1086         int count;
1087         if (terminators != null) {
1088             int numTerminators = terminators.intValue();
1089 search:


1192         // Source data is a String. Search-and-replace EOLN. Encode into the
1193         // target format. Append terminating NUL bytes.
1194         if (stringSelectionHack ||
1195             (String.class.equals(flavor.getRepresentationClass()) &&
1196              isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1197 
1198             String str = removeSuspectedData(flavor, contents, (String)obj);
1199 
1200             return translateTransferableString(
1201                 str,
1202                 format);
1203 
1204         // Source data is a Reader. Convert to a String and recur. In the
1205         // future, we may want to rewrite this so that we encode on demand.
1206         } else if (flavor.isRepresentationClassReader()) {
1207             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1208                 throw new IOException
1209                     ("cannot transfer non-text data as Reader");
1210             }
1211 

1212             StringBuffer buf = new StringBuffer();
1213             try (Reader r = (Reader)obj) {
1214                 int c;
1215                 while ((c = r.read()) != -1) {
1216                     buf.append((char)c);
1217                 }
1218             }
1219 
1220             return translateTransferableString(
1221                 buf.toString(),
1222                 format);
1223 
1224         // Source data is a CharBuffer. Convert to a String and recur.
1225         } else if (flavor.isRepresentationClassCharBuffer()) {
1226             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1227                 throw new IOException
1228                     ("cannot transfer non-text data as CharBuffer");
1229             }
1230 
1231             CharBuffer buffer = (CharBuffer)obj;
1232             int size = buffer.remaining();
1233             char[] chars = new char[size];
1234             buffer.get(chars, 0, size);
1235 
1236             return translateTransferableString(
1237                 new String(chars),
1238                 format);


1280             } else {
1281                 return bytes;
1282             }
1283         // Source data is Image
1284         } else if (DataFlavor.imageFlavor.equals(flavor)) {
1285             if (!isImageFormat(format)) {
1286                 throw new IOException("Data translation failed: " +
1287                                       "not an image format");
1288             }
1289 
1290             Image image = (Image)obj;
1291             byte[] bytes = imageToPlatformBytes(image, format);
1292 
1293             if (bytes == null) {
1294                 throw new IOException("Data translation failed: " +
1295                     "cannot convert java image to native format");
1296             }
1297             return bytes;
1298         }
1299 
1300         byte[] theByteArray = null;
1301 
1302         // Target data is a file list. Source data must be a
1303         // java.util.List which contains java.io.File or String instances.
1304         if (isFileFormat(format)) {
1305             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1306                 throw new IOException("data translation failed");
1307             }
1308 
1309             final List list = (List)obj;
1310 
1311             final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1312 
1313             final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
1314 
1315             try (ByteArrayOutputStream bos = convertFileListToBytes(fileList)) {
1316                 theByteArray = bos.toByteArray();
1317             }
1318 
1319         // Target data is a URI list. Source data must be a
1320         // java.util.List which contains java.io.File or String instances.
1321         } else if (isURIListFormat(format)) {
1322             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1323                 throw new IOException("data translation failed");
1324             }
1325             String nat = getNativeForFormat(format);
1326             String targetCharset = null;
1327             if (nat != null) {
1328                 try {
1329                     targetCharset = new DataFlavor(nat).getParameter("charset");
1330                 } catch (ClassNotFoundException cnfe) {
1331                     throw new IOException(cnfe);
1332                 }
1333             }
1334             if (targetCharset == null) {
1335                 targetCharset = "UTF-8";
1336             }
1337             final List list = (List)obj;
1338             final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1339             final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
1340             final ArrayList<String> uriList = new ArrayList<String>(fileList.size());
1341             for (String fileObject : fileList) {
1342                 final URI uri = new File(fileObject).toURI();
1343                 // Some implementations are fussy about the number of slashes (file:///path/to/file is best)
1344                 try {
1345                     uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString());
1346                 } catch (URISyntaxException uriSyntaxException) {
1347                     throw new IOException(uriSyntaxException);
1348                   }
1349               }
1350 
1351             byte[] eoln = "\r\n".getBytes(targetCharset);
1352 
1353             try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
1354                 for (int i = 0; i < uriList.size(); i++) {
1355                     byte[] bytes = uriList.get(i).getBytes(targetCharset);
1356                     bos.write(bytes, 0, bytes.length);
1357                     bos.write(eoln, 0, eoln.length);
1358                 }
1359                 theByteArray = bos.toByteArray();
1360             }
1361 
1362         // Source data is an InputStream. For arbitrary flavors, just grab the
1363         // bytes and dump them into a byte array. For text flavors, decode back
1364         // to a String and recur to reencode according to the requested format.
1365         } else if (flavor.isRepresentationClassInputStream()) {
1366             try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
1367                 try (InputStream is = (InputStream)obj) {
1368                     boolean eof = false;
1369                     int avail = is.available();
1370                     byte[] tmp = new byte[avail > 8192 ? avail : 8192];
1371                     do {
1372                         int aValue;
1373                         if (!(eof = (aValue = is.read(tmp, 0, tmp.length)) == -1)) {
1374                             bos.write(tmp, 0, aValue);
1375                         }
1376                     } while (!eof);
1377                 }
1378 
1379                 if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1380                     byte[] bytes = bos.toByteArray();

1381                     String sourceEncoding = DataTransferer.getTextCharset(flavor);
1382                     return translateTransferableString(
1383                                new String(bytes, sourceEncoding),
1384                                format);
1385                 }
1386                 theByteArray = bos.toByteArray();
1387             }
1388 
1389 
1390 
1391         // Source data is an RMI object
1392         } else if (flavor.isRepresentationClassRemote()) {
1393 
1394             Object mo = RMI.newMarshalledObject(obj);
1395             theByteArray = convertObjectToBytes(mo);


1396 
1397             // Source data is Serializable
1398         } else if (flavor.isRepresentationClassSerializable()) {
1399 
1400             theByteArray = convertObjectToBytes(obj);

1401 
1402         } else {
1403             throw new IOException("data translation failed");
1404         }
1405 
1406 
1407 
1408         return theByteArray;
1409     }
1410 
1411     private static byte[] convertObjectToBytes(Object object) throws IOException {
1412         try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
1413              ObjectOutputStream oos = new ObjectOutputStream(bos))
1414         {
1415             oos.writeObject(object);
1416             return bos.toByteArray();
1417         }
1418     }
1419 
1420     protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException;
1421 
1422     private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str)
1423             throws IOException
1424     {
1425         if (null == System.getSecurityManager()
1426             || !flavor.isMimeTypeEqual("text/uri-list"))
1427         {
1428             return str;
1429         }
1430 
1431 
1432         String ret_val = "";
1433         final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents);
1434 
1435         try {
1436             ret_val = (String) AccessController.doPrivileged(new PrivilegedExceptionAction() {
1437                     public Object run() {


1552                 }
1553             }
1554         }
1555 
1556         for (File deploymentCacheDirectory : deploymentCacheDirectoryList) {
1557             for (File dir = f; dir != null; dir = dir.getParentFile()) {
1558                 if (dir.equals(deploymentCacheDirectory)) {
1559                     return true;
1560                 }
1561             }
1562         }
1563 
1564         return false;
1565     }
1566 
1567 
1568     public Object translateBytes(byte[] bytes, DataFlavor flavor,
1569                                  long format, Transferable localeTransferable)
1570         throws IOException
1571     {



1572 
1573         Object theObject = null;



























1574 
1575         // Source data is a file list. Use the dragQueryFile native function to
1576         // do most of the decoding. Then wrap File objects around the String
1577         // filenames and return a List.
1578         if (isFileFormat(format)) {
1579             if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
1580                 throw new IOException("data translation failed");
1581             }



1582             String[] filenames = dragQueryFile(bytes);
1583             if (filenames == null) {

1584                 return null;
1585             }
1586 
1587             // Convert the strings to File objects
1588             File[] files = new File[filenames.length];
1589             for (int i = 0; i < filenames.length; i++) {
1590                 files[i] = new File(filenames[i]);
1591             }

1592 
1593             // Turn the list of Files into a List and return
1594             theObject = Arrays.asList(files);























1595 
1596             // Target data is a String. Strip terminating NUL bytes. Decode bytes
1597             // into characters. Search-and-replace EOLN.
1598         } else if (String.class.equals(flavor.getRepresentationClass()) &&
1599                        isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1600 
1601             theObject = translateBytesToString(bytes, format, localeTransferable);


















1602 
1603             // Target data is a Reader. Obtain data in InputStream format, encoded
1604             // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
1605             // back to chars on demand.
1606         } else if (flavor.isRepresentationClassReader()) {
1607             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
1608                 theObject = translateStream(bais,
1609                         flavor, format, localeTransferable);
1610             }











1611             // Target data is a CharBuffer. Recur to obtain String and wrap.
1612         } else if (flavor.isRepresentationClassCharBuffer()) {
1613             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1614                 throw new IOException
1615                           ("cannot transfer non-text data as CharBuffer");
1616             }
1617 
1618             CharBuffer buffer = CharBuffer.wrap(
1619                 translateBytesToString(bytes,format, localeTransferable));

1620 
1621             theObject = constructFlavoredObject(buffer, flavor, CharBuffer.class);
1622 
1623             // Target data is a char array. Recur to obtain String and convert to
1624             // char array.
1625         } else if (charArrayClass.equals(flavor.getRepresentationClass())) {
1626             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1627                 throw new IOException
1628                           ("cannot transfer non-text data as char array");
1629             }
1630 
1631             theObject = translateBytesToString(
1632                 bytes, format, localeTransferable).toCharArray();

1633 
1634             // Target data is a ByteBuffer. For arbitrary flavors, just return
1635             // the raw bytes. For text flavors, convert to a String to strip
1636             // terminators and search-and-replace EOLN, then reencode according to
1637             // the requested flavor.
1638         } else if (flavor.isRepresentationClassByteBuffer()) {
1639             if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1640                 bytes = translateBytesToString(
1641                     bytes, format, localeTransferable).getBytes(


1642                         DataTransferer.getTextCharset(flavor)
1643                     );




1644             }
1645 
1646             ByteBuffer buffer = ByteBuffer.wrap(bytes);
1647             theObject = constructFlavoredObject(buffer, flavor, ByteBuffer.class);
1648 
1649             // Target data is a byte array. For arbitrary flavors, just return
1650             // the raw bytes. For text flavors, convert to a String to strip
1651             // terminators and search-and-replace EOLN, then reencode according to
1652             // the requested flavor.
1653         } else if (byteArrayClass.equals(flavor.getRepresentationClass())) {
1654             if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1655                 theObject = translateBytesToString(
1656                     bytes, format, localeTransferable
1657                 ).getBytes(DataTransferer.getTextCharset(flavor));



1658             } else {
1659                 theObject = bytes;
1660             }
1661 
1662             // Target data is an InputStream. For arbitrary flavors, just return
1663             // the raw bytes. For text flavors, decode to strip terminators and
1664             // search-and-replace EOLN, then reencode according to the requested
1665             // flavor.
1666         } else if (flavor.isRepresentationClassInputStream()) {
1667 
1668             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
1669                 theObject = translateStream(bais, flavor, format, localeTransferable);



1670             }
1671 
1672             // Target data is Serializable
1673         } else if (flavor.isRepresentationClassSerializable()) {
1674 
1675             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
1676                 theObject = translateStream(bais, flavor, format, localeTransferable);






1677             }
1678 
1679             // Target data is Image
1680         } else if (DataFlavor.imageFlavor.equals(flavor)) {
1681             if (!isImageFormat(format)) {
1682                 throw new IOException("data translation failed");
1683             }
1684 
1685             theObject = platformImageBytesToImage(bytes, format);


1686         }
1687 
1688         if (theObject == null) {
1689             throw new IOException("data translation failed");
1690         }
1691 
1692         return theObject;
1693 
1694     }
1695 
1696     /**
1697      * Primary translation function for translating
1698      * an InputStream into an Object, given a source format and a target
1699      * DataFlavor.
1700      */
1701     public Object translateStream(InputStream str, DataFlavor flavor,
1702                                   long format, Transferable localeTransferable)
1703         throws IOException
1704     {
1705 
1706         Object theObject = null;
1707         // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
1708         // where possible.
1709         if (isURIListFormat(format)
1710                 && DataFlavor.javaFileListFlavor.equals(flavor))
1711         {
1712 
1713             URI uris[] = dragQueryURIs(str, format, localeTransferable);
1714             if (uris == null) {
1715                 return null;
1716             }
1717             ArrayList files = new ArrayList();
1718             for (URI uri : uris) {
1719                 try {
1720                     files.add(new File(uri));
1721                 } catch (IllegalArgumentException illegalArg) {
1722                     // When converting from URIs to less generic files,
1723                     // common practice (Wine, SWT) seems to be to
1724                     // silently drop the URIs that aren't local files.
1725                 }
1726             }
1727             theObject = files;
1728 
1729             // Special hack to maintain backwards-compatibility with the brokenness
1730             // of StringSelection. Return a StringReader instead of an InputStream.
1731             // Recur to obtain String and encapsulate.
1732         } else if (DataFlavor.plainTextFlavor.equals(flavor)) {
1733             theObject = new StringReader(translateBytesToString(
1734                 inputStreamToByteArray(str),
1735                 format, localeTransferable));
1736 
1737             // Target data is an InputStream. For arbitrary flavors, just return
1738             // the raw bytes. For text flavors, decode to strip terminators and
1739             // search-and-replace EOLN, then reencode according to the requested
1740             // flavor.
1741         } else if (flavor.isRepresentationClassInputStream()) {
1742             theObject = translateStreamToInputStream(str, flavor, format,
1743                                                                localeTransferable);
1744 
1745             // Target data is a Reader. Obtain data in InputStream format, encoded
1746             // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
1747             // back to chars on demand.
1748         } else if (flavor.isRepresentationClassReader()) {
1749             if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
1750                 throw new IOException
1751                           ("cannot transfer non-text data as Reader");
1752             }
1753 
1754             InputStream is = (InputStream)translateStreamToInputStream(
1755                     str, DataFlavor.plainTextFlavor,
1756                     format, localeTransferable);
1757 
1758             String unicode = DataTransferer.getTextCharset(DataFlavor.plainTextFlavor);
1759 
1760             Reader reader = new InputStreamReader(is, unicode);
1761 
1762             theObject = constructFlavoredObject(reader, flavor, Reader.class);
1763 
1764             // Target data is an RMI object
1765         } else if (flavor.isRepresentationClassRemote()) {
1766 
1767             try (ObjectInputStream ois =
1768                      new ObjectInputStream(str))
1769             {
1770                 theObject = RMI.getMarshalledObject(ois.readObject());
1771             }catch (Exception e) {
1772                 throw new IOException(e.getMessage());
1773             }
1774 
1775             // Target data is Serializable
1776         } else if (flavor.isRepresentationClassSerializable()) {
1777             try (ObjectInputStream ois =
1778                      new ObjectInputStream(str))
1779             {
1780                 theObject = ois.readObject();
1781             } catch (Exception e) {
1782                 throw new IOException(e.getMessage());
1783             }
1784         }
1785 
1786 
1787         return theObject;
1788 
1789     }
1790 
1791     /**
1792      * For arbitrary flavors, just use the raw InputStream. For text flavors,
1793      * ReencodingInputStream will decode and reencode the InputStream on demand
1794      * so that we can strip terminators and search-and-replace EOLN.
1795      */
1796     private Object translateStreamToInputStream
1797         (InputStream str, DataFlavor flavor, long format,
1798          Transferable localeTransferable) throws IOException
1799     {
1800         if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
1801             str = new ReencodingInputStream
1802                 (str, format, DataTransferer.getTextCharset(flavor),
1803                  localeTransferable);
1804         }
1805 
1806         return constructFlavoredObject(str, flavor, InputStream.class);
1807     }
1808 
1809     /**
1810      * We support representations which are exactly of the specified Class,
1811      * and also arbitrary Objects which have a constructor which takes an
1812      * instance of the Class as its sole parameter.
1813      */
1814     private Object constructFlavoredObject(Object arg, DataFlavor flavor,
1815                                            Class clazz)
1816         throws IOException


2032             }
2033 
2034             if (count == array.length) {
2035                 return true;
2036             } else {
2037                 wrapped.reset();
2038                 return false;
2039             }
2040         }
2041     }
2042 
2043     /**
2044      * Decodes a byte array into a set of String filenames.
2045      */
2046     protected abstract String[] dragQueryFile(byte[] bytes);
2047 
2048     /**
2049      * Decodes URIs from either a byte array or a stream.
2050      */
2051     protected URI[] dragQueryURIs(InputStream stream,

2052                                   long format,
2053                                   Transferable localeTransferable)
2054       throws IOException
2055     {
2056         throw new IOException(
2057             new UnsupportedOperationException("not implemented on this platform"));
2058     }
2059 
2060     /**
2061      * Translates either a byte array or an input stream which contain
2062      * platform-specific image data in the given format into an Image.
2063      */
2064 
2065 
2066     protected abstract Image platformImageBytesToImage(
2067         byte[] bytes,long format) throws IOException;
2068 
2069     /**
2070      * Translates either a byte array or an input stream which contain
2071      * an image data in the given standard format into an Image.
2072      *
2073      * @param mimeType image MIME type, such as: image/png, image/jpeg, image/gif
2074      */
2075     protected Image standardImageBytesToImage(
2076         byte[] bytes, String mimeType) throws IOException
2077     {




2078 
2079         Iterator readerIterator = ImageIO.getImageReadersByMIMEType(mimeType);
2080 
2081         if (!readerIterator.hasNext()) {
2082             throw new IOException("No registered service provider can decode " +
2083                                   " an image from " + mimeType);
2084         }
2085 
2086         IOException ioe = null;
2087 
2088         while (readerIterator.hasNext()) {
2089             ImageReader imageReader = (ImageReader)readerIterator.next();
2090             try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
2091                 ImageInputStream imageInputStream =
2092                     ImageIO.createImageInputStream(bais);
2093 
2094                 try {
2095                     ImageReadParam param = imageReader.getDefaultReadParam();
2096                     imageReader.setInput(imageInputStream, true, true);
2097                     BufferedImage bufferedImage =
2098                         imageReader.read(imageReader.getMinIndex(), param);
2099                     if (bufferedImage != null) {
2100                         return bufferedImage;
2101                     }
2102                 } finally {
2103                     imageInputStream.close();
2104                     imageReader.dispose();
2105                 }
2106             } catch (IOException e) {
2107                 ioe = e;
2108                 continue;
2109             }
2110         }
2111 
2112         if (ioe == null) {


2402 
2403     /**
2404      * Helper function to convert a Set of DataFlavors to a sorted array.
2405      * The array will be sorted according to <code>DataFlavorComparator</code>.
2406      */
2407     public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) {
2408         DataFlavor[] flavors = new DataFlavor[flavorsSet.size()];
2409         flavorsSet.toArray(flavors);
2410         final Comparator comparator =
2411                 new DataFlavorComparator(IndexedComparator.SELECT_WORST);
2412         Arrays.sort(flavors, comparator);
2413         return flavors;
2414     }
2415 
2416     /**
2417      * Helper function to convert an InputStream to a byte[] array.
2418      */
2419     protected static byte[] inputStreamToByteArray(InputStream str)
2420         throws IOException
2421     {
2422         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
2423             int len = 0;
2424             byte[] buf = new byte[8192];
2425 
2426             while ((len = str.read(buf)) != -1) {
2427                 baos.write(buf, 0, len);
2428             }
2429 
2430             return baos.toByteArray();
2431         }
2432     }
2433 
2434     /**
2435      * Returns platform-specific mappings for the specified native.
2436      * If there are no platform-specific mappings for this native, the method
2437      * returns an empty <code>List</code>.
2438      */
2439     public List getPlatformMappingsForNative(String nat) {
2440         return new ArrayList();
2441     }
2442 
2443     /**
2444      * Returns platform-specific mappings for the specified flavor.
2445      * If there are no platform-specific mappings for this flavor, the method
2446      * returns an empty <code>List</code>.
2447      */
2448     public List getPlatformMappingsForFlavor(DataFlavor df) {
2449         return new ArrayList();
2450     }
2451