/** * 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 */ private byte[] translateTransferableString(String str, long format) throws IOException { Long lFormat = Long.valueOf(format); String charset = getBestCharsetForTextFormat(lFormat, null); // 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" String eoln = (String)nativeEOLNs.get(lFormat); if (eoln != null) { int length = str.length(); StringBuffer buffer = new StringBuffer(length * 2); // 2 is a heuristic for (int i = 0; i < length; i++) { // Fix for 4914613 - skip native EOLN if (str.startsWith(eoln, i)) { buffer.append(eoln); i += eoln.length() - 1; continue; } char c = str.charAt(i); if (c == '\n') { buffer.append(eoln); } else { buffer.append(c); } } str = buffer.toString(); } // Encode text in target format. byte[] bytes = str.getBytes(charset); // 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" Integer terminators = (Integer)nativeTerminators.get(lFormat); if (terminators != null) { int numTerminators = terminators.intValue(); byte[] terminatedBytes = new byte[bytes.length + numTerminators]; System.arraycopy(bytes, 0, terminatedBytes, 0, bytes.length); for (int i = bytes.length; i < terminatedBytes.length; i++) { terminatedBytes[i] = 0x0; } bytes = terminatedBytes; } 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 */ private String translateBytesOrStreamToString(InputStream str, byte[] bytes, long format, Transferable localeTransferable) 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. if (bytes == null) { bytes = inputStreamToByteArray(str); } str.close(); Long lFormat = Long.valueOf(format); String charset = getBestCharsetForTextFormat(lFormat, localeTransferable); // 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" String eoln = (String)nativeEOLNs.get(lFormat); Integer terminators = (Integer)nativeTerminators.get(lFormat); int count; if (terminators != null) { int numTerminators = terminators.intValue();search: for (count = 0; count < (bytes.length - numTerminators + 1); count += numTerminators) { for (int i = count; i < count + numTerminators; i++) { if (bytes[i] != 0x0) { continue search; } } // found terminators break search; } } else { count = bytes.length; } // Decode text to chars. Don't include any terminators. String converted = new String(bytes, 0, count, charset); // 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" if (eoln != null) { /* Fix for 4463560: replace EOLNs symbol-by-symbol instead * of using buf.replace() */ char[] buf = converted.toCharArray(); char[] eoln_arr = eoln.toCharArray(); converted = null; int j = 0; boolean match; for (int i = 0; i < buf.length; ) { // Catch last few bytes if (i + eoln_arr.length > buf.length) { buf[j++] = buf[i++]; continue; } match = true; for (int k = 0, l = i; k < eoln_arr.length; k++, l++) { if (eoln_arr[k] != buf[l]) { match = false; break; } } if (match) { buf[j++] = '\n'; i += eoln_arr.length; } else { buf[j++] = buf[i++]; } } converted = new String(buf, 0, j); } return converted; } /** * Primary translation function for translating a Transferable into * a byte array, given a source DataFlavor and target format. */ public byte[] translateTransferable(Transferable contents, DataFlavor flavor, 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. Object obj; boolean stringSelectionHack; try { obj = contents.getTransferData(flavor); if (obj == null) { return null; } if (flavor.equals(DataFlavor.plainTextFlavor) && !(obj instanceof InputStream)) { obj = contents.getTransferData(DataFlavor.stringFlavor); if (obj == null) { 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 || (String.class.equals(flavor.getRepresentationClass()) && isFlavorCharsetTextType(flavor) && isTextFormat(format))) { String str = removeSuspectedData(flavor, contents, (String)obj); 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()) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as Reader"); } Reader r = (Reader)obj; StringBuffer buf = new StringBuffer(); int c; while ((c = r.read()) != -1) { buf.append((char)c); } r.close(); return translateTransferableString( buf.toString(), format); // Source data is a CharBuffer. Convert to a String and recur. } else if (flavor.isRepresentationClassCharBuffer()) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as CharBuffer"); } CharBuffer buffer = (CharBuffer)obj; int size = buffer.remaining(); char[] chars = new char[size]; buffer.get(chars, 0, size); return translateTransferableString( new String(chars), format); // Source data is a char array. Convert to a String and recur. } else if (charArrayClass.equals(flavor.getRepresentationClass())) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as char array"); } return translateTransferableString( new String((char[])obj), 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()) { ByteBuffer buffer = (ByteBuffer)obj; int size = buffer.remaining(); byte[] bytes = new byte[size]; buffer.get(bytes, 0, size); if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), 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. } else if (byteArrayClass.equals(flavor.getRepresentationClass())) { byte[] bytes = (byte[])obj; if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), format); } else { return bytes; } // Source data is Image } else if (DataFlavor.imageFlavor.equals(flavor)) { if (!isImageFormat(format)) { throw new IOException("Data translation failed: " + "not an image format"); } Image image = (Image)obj; byte[] bytes = imageToPlatformBytes(image, format); if (bytes == null) { throw new IOException("Data translation failed: " + "cannot convert java image to native format"); } return bytes; } ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 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)) { if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } final List list = (List)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); bos = convertFileListToBytes(fileList); // 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)) { if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } String nat = getNativeForFormat(format); String targetCharset = null; if (nat != null) { try { targetCharset = new DataFlavor(nat).getParameter("charset"); } catch (ClassNotFoundException cnfe) { throw new IOException(cnfe); } } if (targetCharset == null) { targetCharset = "UTF-8"; } final List list = (List)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); final ArrayList<String> uriList = new ArrayList<String>(fileList.size()); for (String fileObject : fileList) { final URI uri = new File(fileObject).toURI(); // Some implementations are fussy about the number of slashes (file:///path/to/file is best) try { uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString()); } catch (URISyntaxException uriSyntaxException) { throw new IOException(uriSyntaxException); } } byte[] eoln = "\r\n".getBytes(targetCharset); for (int i = 0; i < uriList.size(); i++) { byte[] bytes = uriList.get(i).getBytes(targetCharset); bos.write(bytes, 0, bytes.length); bos.write(eoln, 0, eoln.length); } // 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()) { InputStream is = (InputStream)obj; boolean eof = false; int avail = is.available(); byte[] tmp = new byte[avail > 8192 ? avail : 8192]; do { int ret; if (!(eof = (ret = is.read(tmp, 0, tmp.length)) == -1)) { bos.write(tmp, 0, ret); } } while (!eof); is.close(); if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { byte[] bytes = bos.toByteArray(); bos.close(); String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), format); } // Source data is an RMI object } else if (flavor.isRepresentationClassRemote()) { Object mo = RMI.newMarshalledObject(obj); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(mo); oos.close(); // Source data is Serializable } else if (flavor.isRepresentationClassSerializable()) { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.close(); } else { throw new IOException("data translation failed"); } byte[] ret = bos.toByteArray(); bos.close(); return ret; } protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException; private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str) throws IOException { if (null == System.getSecurityManager() || !flavor.isMimeTypeEqual("text/uri-list")) { return str; } String ret_val = ""; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); try { ret_val = (String) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() { StringBuffer allowedFiles = new StringBuffer(str.length()); String [] uriArray = str.split("(\\s)+"); for (String fileName : uriArray) { File file = new File(fileName); if (file.exists() && !(isFileInWebstartedCache(file) || isForbiddenToRead(file, userProtectionDomain))) { if (0 != allowedFiles.length()) { allowedFiles.append("\\r\\n"); } allowedFiles.append(fileName); } } return allowedFiles.toString(); } }); } catch (PrivilegedActionException pae) { throw new IOException(pae.getMessage(), pae); } return ret_val; } private static ProtectionDomain getUserProtectionDomain(Transferable contents) { return contents.getClass().getProtectionDomain(); } private boolean isForbiddenToRead (File file, ProtectionDomain protectionDomain) { if (null == protectionDomain) { return false; } try { FilePermission filePermission = new FilePermission(file.getCanonicalPath(), "read, delete"); if (protectionDomain.implies(filePermission)) { return false; } } catch (IOException e) {} return true; } private ArrayList<String> castToFiles(final List files, final ProtectionDomain userProtectionDomain) throws IOException { final ArrayList<String> fileList = new ArrayList<String>(); try { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws IOException { for (Object fileObject : files) { File file = castToFile(fileObject); if (file != null && (null == System.getSecurityManager() || !(isFileInWebstartedCache(file) || isForbiddenToRead(file, userProtectionDomain)))) { fileList.add(file.getCanonicalPath()); } } return null; } });Lines 1001–1500 of 3090. Previous lines Load more
/** * 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 */ private byte[] translateTransferableString(String str, long format) throws IOException { Long lFormat = Long.valueOf(format); String charset = getBestCharsetForTextFormat(lFormat, null); // 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" String eoln = (String)nativeEOLNs.get(lFormat); if (eoln != null) { int length = str.length(); StringBuffer buffer = new StringBuffer(length * 2); // 2 is a heuristic for (int i = 0; i < length; i++) { // Fix for 4914613 - skip native EOLN if (str.startsWith(eoln, i)) { buffer.append(eoln); i += eoln.length() - 1; continue; } char c = str.charAt(i); if (c == '\n') { buffer.append(eoln); } else { buffer.append(c); } } str = buffer.toString(); } // Encode text in target format. byte[] bytes = str.getBytes(charset); // 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" Integer terminators = (Integer)nativeTerminators.get(lFormat); if (terminators != null) { int numTerminators = terminators.intValue(); byte[] terminatedBytes = new byte[bytes.length + numTerminators]; System.arraycopy(bytes, 0, terminatedBytes, 0, bytes.length); for (int i = bytes.length; i < terminatedBytes.length; i++) { terminatedBytes[i] = 0x0; } bytes = terminatedBytes; } 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 */ private String translateBytesOrStreamToString(InputStream str, byte[] bytes, long format, Transferable localeTransferable) 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. if (bytes == null) { bytes = inputStreamToByteArray(str); } str.close(); Long lFormat = Long.valueOf(format); String charset = getBestCharsetForTextFormat(lFormat, localeTransferable); // 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" String eoln = (String)nativeEOLNs.get(lFormat); Integer terminators = (Integer)nativeTerminators.get(lFormat); int count; if (terminators != null) { int numTerminators = terminators.intValue(); search: for (count = 0; count < (bytes.length - numTerminators + 1); count += numTerminators) { for (int i = count; i < count + numTerminators; i++) { if (bytes[i] != 0x0) { continue search; } } // found terminators break search; } } else { count = bytes.length; } // Decode text to chars. Don't include any terminators. String converted = new String(bytes, 0, count, charset); // 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" if (eoln != null) { /* Fix for 4463560: replace EOLNs symbol-by-symbol instead * of using buf.replace() */ char[] buf = converted.toCharArray(); char[] eoln_arr = eoln.toCharArray(); converted = null; int j = 0; boolean match; for (int i = 0; i < buf.length; ) { // Catch last few bytes if (i + eoln_arr.length > buf.length) { buf[j++] = buf[i++]; continue; } match = true; for (int k = 0, l = i; k < eoln_arr.length; k++, l++) { if (eoln_arr[k] != buf[l]) { match = false; break; } } if (match) { buf[j++] = '\n'; i += eoln_arr.length; } else { buf[j++] = buf[i++]; } } converted = new String(buf, 0, j); } return converted; } /** * Primary translation function for translating a Transferable into * a byte array, given a source DataFlavor and target format. */ public byte[] translateTransferable(Transferable contents, DataFlavor flavor, 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. Object obj; boolean stringSelectionHack; try { obj = contents.getTransferData(flavor); if (obj == null) { return null; } if (flavor.equals(DataFlavor.plainTextFlavor) && !(obj instanceof InputStream)) { obj = contents.getTransferData(DataFlavor.stringFlavor); if (obj == null) { 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 || (String.class.equals(flavor.getRepresentationClass()) && isFlavorCharsetTextType(flavor) && isTextFormat(format))) { String str = removeSuspectedData(flavor, contents, (String)obj); 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()) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as Reader"); } Reader r = (Reader)obj; StringBuffer buf = new StringBuffer(); int c; while ((c = r.read()) != -1) { buf.append((char)c); } r.close(); return translateTransferableString( buf.toString(), format); // Source data is a CharBuffer. Convert to a String and recur. } else if (flavor.isRepresentationClassCharBuffer()) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as CharBuffer"); } CharBuffer buffer = (CharBuffer)obj; int size = buffer.remaining(); char[] chars = new char[size]; buffer.get(chars, 0, size); return translateTransferableString( new String(chars), format); // Source data is a char array. Convert to a String and recur. } else if (charArrayClass.equals(flavor.getRepresentationClass())) { if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) { throw new IOException ("cannot transfer non-text data as char array"); } return translateTransferableString( new String((char[])obj), 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()) { ByteBuffer buffer = (ByteBuffer)obj; int size = buffer.remaining(); byte[] bytes = new byte[size]; buffer.get(bytes, 0, size); if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), 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. } else if (byteArrayClass.equals(flavor.getRepresentationClass())) { byte[] bytes = (byte[])obj; if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), format); } else { return bytes; } // Source data is Image } else if (DataFlavor.imageFlavor.equals(flavor)) { if (!isImageFormat(format)) { throw new IOException("Data translation failed: " + "not an image format"); } Image image = (Image)obj; byte[] bytes = imageToPlatformBytes(image, format); if (bytes == null) { throw new IOException("Data translation failed: " + "cannot convert java image to native format"); } return bytes; } ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 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)) { if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } final List list = (List)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); bos = convertFileListToBytes(fileList); // 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)) { if (!DataFlavor.javaFileListFlavor.equals(flavor)) { throw new IOException("data translation failed"); } String nat = getNativeForFormat(format); String targetCharset = null; if (nat != null) { try { targetCharset = new DataFlavor(nat).getParameter("charset"); } catch (ClassNotFoundException cnfe) { throw new IOException(cnfe); } } if (targetCharset == null) { targetCharset = "UTF-8"; } final List list = (List)obj; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); final ArrayList<String> uriList = new ArrayList<String>(fileList.size()); for (String fileObject : fileList) { final URI uri = new File(fileObject).toURI(); // Some implementations are fussy about the number of slashes (file:///path/to/file is best) try { uriList.add(new URI(uri.getScheme(), "", uri.getPath(), uri.getFragment()).toString()); } catch (URISyntaxException uriSyntaxException) { throw new IOException(uriSyntaxException); } } byte[] eoln = "\r\n".getBytes(targetCharset); for (int i = 0; i < uriList.size(); i++) { byte[] bytes = uriList.get(i).getBytes(targetCharset); bos.write(bytes, 0, bytes.length); bos.write(eoln, 0, eoln.length); } // 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()) { InputStream is = (InputStream)obj; boolean eof = false; int avail = is.available(); byte[] tmp = new byte[avail > 8192 ? avail : 8192]; do { int ret; if (!(eof = (ret = is.read(tmp, 0, tmp.length)) == -1)) { bos.write(tmp, 0, ret); } } while (!eof); is.close(); if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) { byte[] bytes = bos.toByteArray(); bos.close(); String sourceEncoding = DataTransferer.getTextCharset(flavor); return translateTransferableString( new String(bytes, sourceEncoding), format); } // Source data is an RMI object } else if (flavor.isRepresentationClassRemote()) { Object mo = RMI.newMarshalledObject(obj); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(mo); oos.close(); // Source data is Serializable } else if (flavor.isRepresentationClassSerializable()) { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.close(); } else { throw new IOException("data translation failed"); } byte[] ret = bos.toByteArray(); bos.close(); return ret; } protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException; private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str) throws IOException { if (null == System.getSecurityManager() || !flavor.isMimeTypeEqual("text/uri-list")) { return str; } String ret_val = ""; final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); try { ret_val = (String) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() { StringBuffer allowedFiles = new StringBuffer(str.length()); String [] uriArray = str.split("(\\s)+"); for (String fileName : uriArray) { File file = new File(fileName); if (file.exists() && !(isFileInWebstartedCache(file) || isForbiddenToRead(file, userProtectionDomain))) { if (0 != allowedFiles.length()) { allowedFiles.append("\\r\\n"); } allowedFiles.append(fileName); } } return allowedFiles.toString(); } }); } catch (PrivilegedActionException pae) { throw new IOException(pae.getMessage(), pae); } return ret_val; } private static ProtectionDomain getUserProtectionDomain(Transferable contents) { return contents.getClass().getProtectionDomain(); } private boolean isForbiddenToRead (File file, ProtectionDomain protectionDomain) { if (null == protectionDomain) { return false; } try { FilePermission filePermission = new FilePermission(file.getCanonicalPath(), "read, delete"); if (protectionDomain.implies(filePermission)) { return false; } } catch (IOException e) {} return true; } private ArrayList<String> castToFiles(final List files, final ProtectionDomain userProtectionDomain) throws IOException { final ArrayList<String> fileList = new ArrayList<String>(); try { AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws IOException { for (Object fileObject : files) { File file = castToFile(fileObject); if (file != null && (null == System.getSecurityManager() || !(isFileInWebstartedCache(file) || isForbiddenToRead(file, userProtectionDomain)))) { fileList.add(file.getCanonicalPath()); } } return null; } });