--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDataTransferer.java Wed Mar 27 16:19:51 2013 +0400
@@ -174,7 +174,7 @@
bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8");
}
- return super.translateBytesOrStream(stream, bytes, flavor, format, transferable);
+ return super.translateBytes(bytes, flavor, format, transferable);
}
@@ -257,16 +257,13 @@
private native byte[] imageDataToPlatformImageBytes(int[] rData, int nW, int nH);
/**
- * Translates either a byte array or an input stream which contain
+ * Translates a byte array which contains
* platform-specific image data in the given format into an Image.
*/
- protected Image platformImageBytesOrStreamToImage(InputStream stream, byte[] bytes, long format) throws IOException {
- byte[] imageData = bytes;
-
- if (imageData == null)
- imageData = inputStreamToByteArray(stream);
-
- return getImageForByteStream(imageData);
+ protected Image platformImageBytesToImage(byte[] bytes, long format)
+ throws IOException
+ {
+ return getImageForByteStream(bytes);
}
private native Image getImageForByteStream(byte[] bytes);
--- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Wed Mar 27 16:19:51 2013 +0400
@@ -25,7 +25,6 @@
package java.awt.datatransfer;
-import java.awt.Toolkit;
import java.io.*;
import java.nio.*;
import java.util.*;
@@ -162,6 +161,18 @@
}
}
+ /*
+ * private initializer
+ */
+ static private DataFlavor initHtmlDataFlavor(String htmlFlavorType) {
+ try {
+ return new DataFlavor ("text/html; class=java.lang.String;document=" +
+ htmlFlavorType + ";charset=Unicode");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
/**
* The <code>DataFlavor</code> representing a Java Unicode String class,
* where:
@@ -246,6 +257,46 @@
public static final String javaRemoteObjectMimeType = "application/x-java-remote-object";
/**
+ * Represents a piece of an HTML markup. The markup consists of the part
+ * selected on the source side. Therefore some tags in the markup may be
+ * unpaired. If the flavor is used to represent the data in
+ * a {@link Transferable} instance, no additional changes will be made.
+ * This DataFlavor instance represents the same HTML markup as DataFlavor
+ * instances which content MIME type does not contain document parameter
+ * and representation class is the String class.
+ * <pre>
+ * representationClass = String
+ * mimeType = "text/html"
+ * </pre>
+ */
+ public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection");
+
+ /**
+ * Represents a piece of an HTML markup. If possible, the markup received
+ * from a native system is supplemented with pair tags to be
+ * a well-formed HTML markup. If the flavor is used to represent the data in
+ * a {@link Transferable} instance, no additional changes will be made.
+ * <pre>
+ * representationClass = String
+ * mimeType = "text/html"
+ * </pre>
+ */
+ public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment");
+
+ /**
+ * Represents a piece of an HTML markup. If possible, the markup
+ * received from a native system is supplemented with additional
+ * tags to make up a well-formed HTML document. If the flavor is used to
+ * represent the data in a {@link Transferable} instance,
+ * no additional changes will be made.
+ * <pre>
+ * representationClass = String
+ * mimeType = "text/html"
+ * </pre>
+ */
+ public static DataFlavor allHtmlFlavor = initHtmlDataFlavor("all");
+
+ /**
* Constructs a new <code>DataFlavor</code>. This constructor is
* provided only for the purpose of supporting the
* <code>Externalizable</code> interface. It is not
@@ -949,24 +1000,35 @@
return false;
}
- if ("text".equals(getPrimaryType()) &&
- DataTransferer.doesSubtypeSupportCharset(this) &&
- representationClass != null &&
- !(isRepresentationClassReader() ||
- String.class.equals(representationClass) ||
- isRepresentationClassCharBuffer() ||
- DataTransferer.charArrayClass.equals(representationClass)))
- {
- String thisCharset =
- DataTransferer.canonicalName(getParameter("charset"));
- String thatCharset =
- DataTransferer.canonicalName(that.getParameter("charset"));
- if (thisCharset == null) {
- if (thatCharset != null) {
- return false;
+ if ("text".equals(getPrimaryType())) {
+ if (DataTransferer.doesSubtypeSupportCharset(this) &&
+ representationClass != null &&
+ !(isRepresentationClassReader() ||
+ String.class.equals(representationClass) ||
+ isRepresentationClassCharBuffer() ||
+ DataTransferer.charArrayClass.equals(representationClass)))
+ {
+ String thisCharset =
+ DataTransferer.canonicalName(getParameter("charset"));
+ String thatCharset =
+ DataTransferer.canonicalName(that.getParameter("charset"));
+ if (thisCharset == null) {
+ if (thatCharset != null) {
+ return false;
+ }
+ } else {
+ if (!thisCharset.equals(thatCharset)) {
+ return false;
+ }
}
- } else {
- if (!thisCharset.equals(thatCharset)) {
+ }
+
+ if ("html".equals(getSubType()) &&
+ this.getParameter("document") != null )
+ {
+ if (!this.getParameter("document").
+ equals(that.getParameter("document")))
+ {
return false;
}
}
--- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Wed Mar 27 16:19:51 2013 +0400
@@ -41,7 +41,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -101,6 +101,11 @@
private static final String TEXT_PLAIN_BASE_TYPE = "text/plain";
/**
+ * A String representing text/html MIME type.
+ */
+ private static final String HTML_TEXT_BASE_TYPE = "text/html";
+
+ /**
* This constant is passed to flavorToNativeLookup() to indicate that a
* a native should be synthesized, stored, and returned by encoding the
* DataFlavor's MIME type in case if the DataFlavor is not found in
@@ -113,7 +118,7 @@
* text DataFlavors).
* Do not use the field directly, use getNativeToFlavor() instead.
*/
- private Map nativeToFlavor = new HashMap();
+ private final Map<String, List<DataFlavor>> nativeToFlavor = new HashMap<>();
/**
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
@@ -122,7 +127,7 @@
*
* @return nativeToFlavor
*/
- private Map getNativeToFlavor() {
+ private Map<String, List<DataFlavor>> getNativeToFlavor() {
if (!isMapInitialized) {
initSystemFlavorMap();
}
@@ -134,7 +139,7 @@
* native Strings.
* Do not use the field directly, use getFlavorToNative() instead.
*/
- private Map flavorToNative = new HashMap();
+ private final Map flavorToNative = new HashMap();
/**
* Accessor to flavorToNative map. Since we use lazy initialization we must
@@ -421,14 +426,17 @@
}
}
- // For text/* flavors, store mappings in separate maps to
- // enable dynamic mapping generation at a run-time.
+ final LinkedHashSet<DataFlavor> dfs = new LinkedHashSet<>();
+
+ dfs.add(flavor);
+
if ("text".equals(flavor.getPrimaryType())) {
- store(value, key, getFlavorToNative());
- store(key, value, getNativeToFlavor());
- } else {
- store(flavor, key, getFlavorToNative());
- store(key, flavor, getNativeToFlavor());
+ dfs.addAll(convertMimeTypeToDataFlavors(value));
+ }
+
+ for (DataFlavor df : dfs) {
+ store(df, key, getFlavorToNative());
+ store(key, df, getNativeToFlavor());
}
}
}
@@ -530,7 +538,7 @@
* only if the specified native is encoded as a Java MIME type.
*/
private List nativeToFlavorLookup(String nat) {
- List flavors = (List)getNativeToFlavor().get(nat);
+ List<DataFlavor> flavors = getNativeToFlavor().get(nat);
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
DataTransferer transferer = DataTransferer.getInstance();
@@ -625,7 +633,7 @@
getNativesForFlavorCache.remove(flav);
getNativesForFlavorCache.remove(null);
- List flavors = (List)getNativeToFlavor().get(encoded);
+ List<DataFlavor> flavors = getNativeToFlavor().get(encoded);
if (flavors == null) {
flavors = new ArrayList(1);
getNativeToFlavor().put(encoded, flavors);
@@ -681,7 +689,7 @@
}
if (flav == null) {
- retval = new ArrayList(getNativeToFlavor().keySet());
+ retval = new ArrayList<String>(getNativeToFlavor().keySet());
} else if (disabledMappingGenerationKeys.contains(flav)) {
// In this case we shouldn't synthesize a native for this flavor,
// since its mappings were explicitly specified.
@@ -809,140 +817,162 @@
}
}
- LinkedList retval = new LinkedList();
+ final LinkedHashSet <DataFlavor> returnValue =
+ new LinkedHashSet<>();
if (nat == null) {
- List natives = getNativesForFlavor(null);
- HashSet dups = new HashSet(natives.size());
+ final List<String> natives = getNativesForFlavor(null);
- for (Iterator natives_iter = natives.iterator();
- natives_iter.hasNext(); )
+ for (String n : natives)
{
- List flavors =
- getFlavorsForNative((String)natives_iter.next());
- for (Iterator flavors_iter = flavors.iterator();
- flavors_iter.hasNext(); )
+ final List<DataFlavor> flavors = getFlavorsForNative(n);
+
+ for (DataFlavor df : flavors)
{
- Object flavor = flavors_iter.next();
- if (dups.add(flavor)) {
- retval.add(flavor);
- }
+ returnValue.add(df);
}
}
} else {
- List flavors = nativeToFlavorLookup(nat);
+
+ final List<DataFlavor> flavors = nativeToFlavorLookup(nat);
if (disabledMappingGenerationKeys.contains(nat)) {
return flavors;
}
- HashSet dups = new HashSet(flavors.size());
-
- List flavorsAndbaseTypes = nativeToFlavorLookup(nat);
-
- for (Iterator flavorsAndbaseTypes_iter =
- flavorsAndbaseTypes.iterator();
- flavorsAndbaseTypes_iter.hasNext(); )
- {
- Object value = flavorsAndbaseTypes_iter.next();
- if (value instanceof String) {
- String baseType = (String)value;
- String subType = null;
- try {
- MimeType mimeType = new MimeType(baseType);
- subType = mimeType.getSubType();
- } catch (MimeTypeParseException mtpe) {
- // Cannot happen, since we checked all mappings
- // on load from flavormap.properties.
- assert(false);
- }
- if (DataTransferer.doesSubtypeSupportCharset(subType,
- null)) {
- if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
- dups.add(DataFlavor.stringFlavor))
- {
- retval.add(DataFlavor.stringFlavor);
- }
-
- for (int i = 0; i < UNICODE_TEXT_CLASSES.length; i++) {
- DataFlavor toAdd = null;
- try {
- toAdd = new DataFlavor
- (baseType + ";charset=Unicode;class=" +
- UNICODE_TEXT_CLASSES[i]);
- } catch (ClassNotFoundException cannotHappen) {
- }
- if (dups.add(toAdd)) {
- retval.add(toAdd);
- }
- }
-
- for (Iterator charset_iter =
- DataTransferer.standardEncodings();
- charset_iter.hasNext(); )
- {
- String charset = (String)charset_iter.next();
+ final List<DataFlavor> flavorsAndBaseTypes =
+ nativeToFlavorLookup(nat);
- for (int i = 0; i < ENCODED_TEXT_CLASSES.length;
- i++)
- {
- DataFlavor toAdd = null;
- try {
- toAdd = new DataFlavor
- (baseType + ";charset=" + charset +
- ";class=" + ENCODED_TEXT_CLASSES[i]);
- } catch (ClassNotFoundException cannotHappen) {
- }
-
- // Check for equality to plainTextFlavor so
- // that we can ensure that the exact charset of
- // plainTextFlavor, not the canonical charset
- // or another equivalent charset with a
- // different name, is used.
- if (toAdd.equals(DataFlavor.plainTextFlavor)) {
- toAdd = DataFlavor.plainTextFlavor;
- }
-
- if (dups.add(toAdd)) {
- retval.add(toAdd);
- }
- }
- }
-
- if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
- dups.add(DataFlavor.plainTextFlavor))
- {
- retval.add(DataFlavor.plainTextFlavor);
- }
- } else {
- // Non-charset text natives should be treated as
- // opaque, 8-bit data in any of its various
- // representations.
- for (int i = 0; i < ENCODED_TEXT_CLASSES.length; i++) {
- DataFlavor toAdd = null;
- try {
- toAdd = new DataFlavor(baseType +
- ";class=" + ENCODED_TEXT_CLASSES[i]);
- } catch (ClassNotFoundException cannotHappen) {
- }
-
- if (dups.add(toAdd)) {
- retval.add(toAdd);
- }
- }
- }
- } else {
- DataFlavor flavor = (DataFlavor)value;
- if (dups.add(flavor)) {
- retval.add(flavor);
+ for (DataFlavor df : flavorsAndBaseTypes) {
+ returnValue.add(df);
+ if ("text".equals(df.getPrimaryType())) {
+ try {
+ returnValue.addAll(
+ convertMimeTypeToDataFlavors(
+ new MimeType(df.getMimeType()
+ ).getBaseType()));
+ } catch (MimeTypeParseException e) {
+ e.printStackTrace();
}
}
}
+
+ }
+
+ final ArrayList arrayList = new ArrayList(returnValue);
+ getFlavorsForNativeCache.put(nat, new SoftReference(arrayList));
+ return (List)arrayList.clone();
+ }
+
+ private static LinkedHashSet<DataFlavor> convertMimeTypeToDataFlavors(
+ final String baseType) {
+
+ final LinkedHashSet<DataFlavor> returnValue =
+ new LinkedHashSet<DataFlavor>();
+
+ String subType = null;
+
+ try {
+ final MimeType mimeType = new MimeType(baseType);
+ subType = mimeType.getSubType();
+ } catch (MimeTypeParseException mtpe) {
+ // Cannot happen, since we checked all mappings
+ // on load from flavormap.properties.
+ assert(false);
}
- ArrayList arrayList = new ArrayList(retval);
- getFlavorsForNativeCache.put(nat, new SoftReference(arrayList));
- return (List)arrayList.clone();
+ if (DataTransferer.doesSubtypeSupportCharset(subType, null)) {
+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
+ {
+ returnValue.add(DataFlavor.stringFlavor);
+ }
+
+ for (String unicodeClassName : UNICODE_TEXT_CLASSES) {
+ final String mimeType = baseType + ";charset=Unicode;class=" +
+ unicodeClassName;
+
+ final LinkedHashSet<String> mimeTypes =
+ handleHtmlMimeTypes(baseType, mimeType);
+ for (String mt : mimeTypes) {
+ DataFlavor toAdd = null;
+ try {
+ toAdd = new DataFlavor(mt);
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+ returnValue.add(toAdd);
+ }
+ }
+
+ for (String charset : DataTransferer.standardEncodings()) {
+
+ for (String encodedTextClass : ENCODED_TEXT_CLASSES) {
+ final String mimeType =
+ baseType + ";charset=" + charset +
+ ";class=" + encodedTextClass;
+
+ final LinkedHashSet<String> mimeTypes =
+ handleHtmlMimeTypes(baseType, mimeType);
+
+ for (String mt : mimeTypes) {
+
+ DataFlavor df = null;
+
+ try {
+ df = new DataFlavor(mt);
+ // Check for equality to plainTextFlavor so
+ // that we can ensure that the exact charset of
+ // plainTextFlavor, not the canonical charset
+ // or another equivalent charset with a
+ // different name, is used.
+ if (df.equals(DataFlavor.plainTextFlavor)) {
+ df = DataFlavor.plainTextFlavor;
+ }
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+
+ returnValue.add(df);
+ }
+ }
+ }
+
+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
+ {
+ returnValue.add(DataFlavor.plainTextFlavor);
+ }
+ } else {
+ // Non-charset text natives should be treated as
+ // opaque, 8-bit data in any of its various
+ // representations.
+ for (String encodedTextClassName : ENCODED_TEXT_CLASSES) {
+ DataFlavor toAdd = null;
+ try {
+ toAdd = new DataFlavor(baseType +
+ ";class=" + encodedTextClassName);
+ } catch (ClassNotFoundException cannotHappen) {
+ }
+ returnValue.add(toAdd);
+ }
+ }
+ return returnValue;
+ }
+
+ private static final String [] htmlDocumntTypes =
+ new String [] {"all", "selection", "fragment"};
+
+ private static LinkedHashSet<String> handleHtmlMimeTypes(
+ String baseType, String mimeType) {
+
+ LinkedHashSet<String> returnValues = new LinkedHashSet<>();
+
+ if (HTML_TEXT_BASE_TYPE.equals(baseType)) {
+ for (String documentType : htmlDocumntTypes) {
+ returnValues.add(mimeType + ";document=" + documentType);
+ }
+ } else {
+ returnValues.add(mimeType);
+ }
+
+ return returnValues;
}
/**
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Wed Mar 27 16:19:51 2013 +0400
@@ -171,12 +171,12 @@
* Lazy initialization of Standard Encodings.
*/
private static class StandardEncodingsHolder {
- private static final SortedSet standardEncodings = load();
-
- private static SortedSet load() {
+ private static final SortedSet<String> standardEncodings = load();
+
+ private static SortedSet<String> load() {
final Comparator comparator =
new CharsetComparator(IndexedComparator.SELECT_WORST);
- final SortedSet tempSet = new TreeSet(comparator);
+ final SortedSet<String> tempSet = new TreeSet<String>(comparator);
tempSet.add("US-ASCII");
tempSet.add("ISO-8859-1");
tempSet.add("UTF-8");
@@ -523,8 +523,8 @@
* So as to avoid loading all available character converters, optional,
* non-standard, character sets are not included.
*/
- public static Iterator standardEncodings() {
- return StandardEncodingsHolder.standardEncodings.iterator();
+ public static Set <String> standardEncodings() {
+ return StandardEncodingsHolder.standardEncodings;
}
/**
@@ -1068,17 +1068,10 @@
*
* Native to Java string conversion
*/
- private String translateBytesOrStreamToString(InputStream str, byte[] bytes,
- long format,
- Transferable localeTransferable)
+ private String translateBytesToString(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);
@@ -1221,13 +1214,13 @@
("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);
+ try (Reader r = (Reader)obj) {
+ int c;
+ while ((c = r.read()) != -1) {
+ buf.append((char)c);
+ }
}
- r.close();
return translateTransferableString(
buf.toString(),
@@ -1309,7 +1302,7 @@
return bytes;
}
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] theByteArray = null;
// Target data is a file list. Source data must be a
// java.util.List which contains java.io.File or String instances.
@@ -1324,8 +1317,9 @@
final ArrayList<String> fileList = castToFiles(list, userProtectionDomain);
- bos = convertFileListToBytes(fileList);
-
+ try (ByteArrayOutputStream bos = convertFileListToBytes(fileList)) {
+ theByteArray = bos.toByteArray();
+ }
// Target data is a URI list. Source data must be a
// java.util.List which contains java.io.File or String instances.
@@ -1360,57 +1354,72 @@
}
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);
+
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+ 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);
+ }
+ theByteArray = bos.toByteArray();
}
// 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);
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+ try (InputStream is = (InputStream)obj) {
+ boolean eof = false;
+ int avail = is.available();
+ byte[] tmp = new byte[avail > 8192 ? avail : 8192];
+ do {
+ int aValue;
+ if (!(eof = (aValue = is.read(tmp, 0, tmp.length)) == -1)) {
+ bos.write(tmp, 0, aValue);
+ }
+ } while (!eof);
}
- } 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);
+
+ if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
+ byte[] bytes = bos.toByteArray();
+ String sourceEncoding = DataTransferer.getTextCharset(flavor);
+ return translateTransferableString(
+ new String(bytes, sourceEncoding),
+ format);
+ }
+ theByteArray = bos.toByteArray();
}
+
+
// 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
+ theByteArray = convertObjectToBytes(mo);
+
+ // Source data is Serializable
} else if (flavor.isRepresentationClassSerializable()) {
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(obj);
- oos.close();
+
+ theByteArray = convertObjectToBytes(obj);
} else {
throw new IOException("data translation failed");
}
- byte[] ret = bos.toByteArray();
- bos.close();
- return ret;
+
+
+ return theByteArray;
+ }
+
+ private static byte[] convertObjectToBytes(Object object) throws IOException {
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos))
+ {
+ oos.writeObject(object);
+ return bos.toByteArray();
+ }
}
protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException;
@@ -1565,38 +1574,8 @@
long format, Transferable localeTransferable)
throws IOException
{
- return translateBytesOrStream(null, bytes, flavor, format,
- localeTransferable);
- }
-
- public Object translateStream(InputStream str, DataFlavor flavor,
- long format, Transferable localeTransferable)
- throws IOException
- {
- return translateBytesOrStream(str, null, flavor, format,
- localeTransferable);
- }
-
-
- /**
- * Primary translation function for translating either a byte array or
- * an InputStream into an Object, given a source format and a target
- * DataFlavor.
- *
- * One of str/bytes is non-null; the other is null.
- * The conversion from byte[] to InputStream is cheap, so do that
- * immediately if necessary. The opposite conversion is expensive,
- * so avoid it if possible.
- */
- protected Object translateBytesOrStream(InputStream str, byte[] bytes,
- DataFlavor flavor, long format,
- Transferable localeTransferable)
- throws IOException
- {
-
- if (str == null) {
- str = new ByteArrayInputStream(bytes);
- }
+
+ Object theObject = null;
// Source data is a file list. Use the dragQueryFile native function to
// do most of the decoding. Then wrap File objects around the String
@@ -1605,12 +1584,8 @@
if (!DataFlavor.javaFileListFlavor.equals(flavor)) {
throw new IOException("data translation failed");
}
- if (bytes == null) {
- bytes = inputStreamToByteArray(str);
- }
String[] filenames = dragQueryFile(bytes);
if (filenames == null) {
- str.close();
return null;
}
@@ -1619,178 +1594,203 @@
for (int i = 0; i < filenames.length; i++) {
files[i] = new File(filenames[i]);
}
- str.close();
// Turn the list of Files into a List and return
- return Arrays.asList(files);
-
- // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
- // where possible.
- } else if (isURIListFormat(format) && DataFlavor.javaFileListFlavor.equals(flavor)) {
- try {
- URI uris[] = dragQueryURIs(str, bytes, format, localeTransferable);
- if (uris == null) {
- return null;
- }
- ArrayList files = new ArrayList();
- for (URI uri : uris) {
- try {
- files.add(new File(uri));
- } catch (IllegalArgumentException illegalArg) {
- // When converting from URIs to less generic files,
- // common practice (Wine, SWT) seems to be to
- // silently drop the URIs that aren't local files.
- }
- }
- return files;
- } finally {
- str.close();
- }
-
- // Target data is a String. Strip terminating NUL bytes. Decode bytes
- // into characters. Search-and-replace EOLN.
+ theObject = Arrays.asList(files);
+
+ // Target data is a String. Strip terminating NUL bytes. Decode bytes
+ // into characters. Search-and-replace EOLN.
} else if (String.class.equals(flavor.getRepresentationClass()) &&
- isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
-
- return translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable);
-
- // Special hack to maintain backwards-compatibility with the brokenness
- // of StringSelection. Return a StringReader instead of an InputStream.
- // Recur to obtain String and encapsulate.
- } else if (DataFlavor.plainTextFlavor.equals(flavor)) {
- return new StringReader(translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable));
-
- // Target data is an InputStream. For arbitrary flavors, just return
- // the raw bytes. For text flavors, decode to strip terminators and
- // search-and-replace EOLN, then reencode according to the requested
- // flavor.
- } else if (flavor.isRepresentationClassInputStream()) {
- return translateBytesOrStreamToInputStream(str, flavor, format,
- localeTransferable);
-
- // Target data is a Reader. Obtain data in InputStream format, encoded
- // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
- // back to chars on demand.
+ isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
+
+ theObject = translateBytesToString(bytes, format, localeTransferable);
+
+ // Target data is a Reader. Obtain data in InputStream format, encoded
+ // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
+ // back to chars on demand.
} else if (flavor.isRepresentationClassReader()) {
- if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
- throw new IOException
- ("cannot transfer non-text data as Reader");
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+ theObject = translateStream(bais,
+ flavor, format, localeTransferable);
}
-
- InputStream is = (InputStream)
- translateBytesOrStreamToInputStream
- (str, DataFlavor.plainTextFlavor, format,
- localeTransferable);
- String unicode =
- DataTransferer.getTextCharset(DataFlavor.plainTextFlavor);
- Reader reader = new InputStreamReader(is, unicode);
-
- return constructFlavoredObject(reader, flavor, Reader.class);
-
- // Target data is a CharBuffer. Recur to obtain String and wrap.
+ // Target data is a CharBuffer. Recur to obtain String and wrap.
} else if (flavor.isRepresentationClassCharBuffer()) {
if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
throw new IOException
- ("cannot transfer non-text data as CharBuffer");
+ ("cannot transfer non-text data as CharBuffer");
}
- CharBuffer buffer = CharBuffer.wrap(translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable));
-
- return constructFlavoredObject(buffer, flavor, CharBuffer.class);
-
- // Target data is a char array. Recur to obtain String and convert to
- // char array.
+ CharBuffer buffer = CharBuffer.wrap(
+ translateBytesToString(bytes,format, localeTransferable));
+
+ theObject = constructFlavoredObject(buffer, flavor, CharBuffer.class);
+
+ // Target data is a char array. Recur to obtain String and convert to
+ // char array.
} else if (charArrayClass.equals(flavor.getRepresentationClass())) {
if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
throw new IOException
- ("cannot transfer non-text data as char array");
+ ("cannot transfer non-text data as char array");
}
- return translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable).toCharArray();
-
- // Target data is a ByteBuffer. For arbitrary flavors, just return
- // the raw bytes. For text flavors, convert to a String to strip
- // terminators and search-and-replace EOLN, then reencode according to
- // the requested flavor.
+ theObject = translateBytesToString(
+ bytes, format, localeTransferable).toCharArray();
+
+ // Target data is a ByteBuffer. For arbitrary flavors, just return
+ // the raw bytes. For text flavors, convert to a String to strip
+ // terminators and search-and-replace EOLN, then reencode according to
+ // the requested flavor.
} else if (flavor.isRepresentationClassByteBuffer()) {
if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
- bytes = translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable
- ).getBytes(
- DataTransferer.getTextCharset(flavor)
- );
- } else {
- if (bytes == null) {
- bytes = inputStreamToByteArray(str);
- }
+ bytes = translateBytesToString(
+ bytes, format, localeTransferable).getBytes(
+ DataTransferer.getTextCharset(flavor)
+ );
}
ByteBuffer buffer = ByteBuffer.wrap(bytes);
- return constructFlavoredObject(buffer, flavor, ByteBuffer.class);
-
- // Target data is a byte array. For arbitrary flavors, just return
- // the raw bytes. For text flavors, convert to a String to strip
- // terminators and search-and-replace EOLN, then reencode according to
- // the requested flavor.
+ theObject = constructFlavoredObject(buffer, flavor, ByteBuffer.class);
+
+ // Target data is a byte array. For arbitrary flavors, just return
+ // the raw bytes. For text flavors, convert to a String to strip
+ // terminators and search-and-replace EOLN, then reencode according to
+ // the requested flavor.
} else if (byteArrayClass.equals(flavor.getRepresentationClass())) {
if (isFlavorCharsetTextType(flavor) && isTextFormat(format)) {
- return translateBytesOrStreamToString(
- str, bytes,
- format, localeTransferable
- ).getBytes(
- DataTransferer.getTextCharset(flavor)
- );
+ theObject = translateBytesToString(
+ bytes, format, localeTransferable
+ ).getBytes(DataTransferer.getTextCharset(flavor));
} else {
- return (bytes != null) ? bytes : inputStreamToByteArray(str);
+ theObject = bytes;
}
- // Target data is an RMI object
- } else if (flavor.isRepresentationClassRemote()) {
- try {
- byte[] ba = inputStreamToByteArray(str);
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
- Object ret = RMI.getMarshalledObject(ois.readObject());
- ois.close();
- str.close();
- return ret;
- } catch (Exception e) {
- throw new IOException(e.getMessage());
+ // Target data is an InputStream. For arbitrary flavors, just return
+ // the raw bytes. For text flavors, decode to strip terminators and
+ // search-and-replace EOLN, then reencode according to the requested
+ // flavor.
+ } else if (flavor.isRepresentationClassInputStream()) {
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+ theObject = translateStream(bais, flavor, format, localeTransferable);
}
- // Target data is Serializable
+ // Target data is Serializable
} else if (flavor.isRepresentationClassSerializable()) {
- try {
- byte[] ba = inputStreamToByteArray(str);
- ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(ba));
- Object ret = ois.readObject();
- ois.close();
- str.close();
- return ret;
- } catch (Exception e) {
- throw new IOException(e.getMessage());
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
+ theObject = translateStream(bais, flavor, format, localeTransferable);
}
- // Target data is Image
+ // Target data is Image
} else if (DataFlavor.imageFlavor.equals(flavor)) {
if (!isImageFormat(format)) {
throw new IOException("data translation failed");
}
- Image image = platformImageBytesOrStreamToImage(str, bytes, format);
- str.close();
- return image;
+ theObject = platformImageBytesToImage(bytes, format);
+ }
+
+ if (theObject == null) {
+ throw new IOException("data translation failed");
}
- throw new IOException("data translation failed");
+ return theObject;
+
+ }
+
+ /**
+ * Primary translation function for translating
+ * an InputStream into an Object, given a source format and a target
+ * DataFlavor.
+ */
+ public Object translateStream(InputStream str, DataFlavor flavor,
+ long format, Transferable localeTransferable)
+ throws IOException
+ {
+
+ Object theObject = null;
+ // Source data is a URI list. Convert to DataFlavor.javaFileListFlavor
+ // where possible.
+ if (isURIListFormat(format)
+ && DataFlavor.javaFileListFlavor.equals(flavor))
+ {
+
+ URI uris[] = dragQueryURIs(str, format, localeTransferable);
+ if (uris == null) {
+ return null;
+ }
+ ArrayList files = new ArrayList();
+ for (URI uri : uris) {
+ try {
+ files.add(new File(uri));
+ } catch (IllegalArgumentException illegalArg) {
+ // When converting from URIs to less generic files,
+ // common practice (Wine, SWT) seems to be to
+ // silently drop the URIs that aren't local files.
+ }
+ }
+ theObject = files;
+
+ // Special hack to maintain backwards-compatibility with the brokenness
+ // of StringSelection. Return a StringReader instead of an InputStream.
+ // Recur to obtain String and encapsulate.
+ } else if (DataFlavor.plainTextFlavor.equals(flavor)) {
+ theObject = new StringReader(translateBytesToString(
+ inputStreamToByteArray(str),
+ format, localeTransferable));
+
+ // Target data is an InputStream. For arbitrary flavors, just return
+ // the raw bytes. For text flavors, decode to strip terminators and
+ // search-and-replace EOLN, then reencode according to the requested
+ // flavor.
+ } else if (flavor.isRepresentationClassInputStream()) {
+ theObject = translateStreamToInputStream(str, flavor, format,
+ localeTransferable);
+
+ // Target data is a Reader. Obtain data in InputStream format, encoded
+ // as "Unicode" (utf-16be). Then use an InputStreamReader to decode
+ // back to chars on demand.
+ } else if (flavor.isRepresentationClassReader()) {
+ if (!(isFlavorCharsetTextType(flavor) && isTextFormat(format))) {
+ throw new IOException
+ ("cannot transfer non-text data as Reader");
+ }
+
+ InputStream is = (InputStream)translateStreamToInputStream(
+ str, DataFlavor.plainTextFlavor,
+ format, localeTransferable);
+
+ String unicode = DataTransferer.getTextCharset(DataFlavor.plainTextFlavor);
+
+ Reader reader = new InputStreamReader(is, unicode);
+
+ theObject = constructFlavoredObject(reader, flavor, Reader.class);
+
+ // Target data is an RMI object
+ } else if (flavor.isRepresentationClassRemote()) {
+
+ try (ObjectInputStream ois =
+ new ObjectInputStream(str))
+ {
+ theObject = RMI.getMarshalledObject(ois.readObject());
+ }catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+
+ // Target data is Serializable
+ } else if (flavor.isRepresentationClassSerializable()) {
+ try (ObjectInputStream ois =
+ new ObjectInputStream(str))
+ {
+ theObject = ois.readObject();
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+
+ return theObject;
+
}
/**
@@ -1798,7 +1798,7 @@
* ReencodingInputStream will decode and reencode the InputStream on demand
* so that we can strip terminators and search-and-replace EOLN.
*/
- private Object translateBytesOrStreamToInputStream
+ private Object translateStreamToInputStream
(InputStream str, DataFlavor flavor, long format,
Transferable localeTransferable) throws IOException
{
@@ -2054,7 +2054,6 @@
* Decodes URIs from either a byte array or a stream.
*/
protected URI[] dragQueryURIs(InputStream stream,
- byte[] bytes,
long format,
Transferable localeTransferable)
throws IOException
@@ -2067,10 +2066,10 @@
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
*/
- protected abstract Image platformImageBytesOrStreamToImage(InputStream str,
- byte[] bytes,
- long format)
- throws IOException;
+
+
+ protected abstract Image platformImageBytesToImage(
+ byte[] bytes,long format) throws IOException;
/**
* Translates either a byte array or an input stream which contain
@@ -2078,13 +2077,9 @@
*
* @param mimeType image MIME type, such as: image/png, image/jpeg, image/gif
*/
- protected Image standardImageBytesOrStreamToImage(InputStream inputStream,
- byte[] bytes,
- String mimeType)
- throws IOException {
- if (inputStream == null) {
- inputStream = new ByteArrayInputStream(bytes);
- }
+ protected Image standardImageBytesToImage(
+ byte[] bytes, String mimeType) throws IOException
+ {
Iterator readerIterator = ImageIO.getImageReadersByMIMEType(mimeType);
@@ -2097,9 +2092,9 @@
while (readerIterator.hasNext()) {
ImageReader imageReader = (ImageReader)readerIterator.next();
- try {
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes)) {
ImageInputStream imageInputStream =
- ImageIO.createImageInputStream(inputStream);
+ ImageIO.createImageInputStream(bais);
try {
ImageReadParam param = imageReader.getDefaultReadParam();
@@ -2456,15 +2451,16 @@
protected static byte[] inputStreamToByteArray(InputStream str)
throws IOException
{
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int len = 0;
- byte[] buf = new byte[8192];
-
- while ((len = str.read(buf)) != -1) {
- baos.write(buf, 0, len);
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ int len = 0;
+ byte[] buf = new byte[8192];
+
+ while ((len = str.read(buf)) != -1) {
+ baos.write(buf, 0, len);
+ }
+
+ return baos.toByteArray();
}
-
- return baos.toByteArray();
}
/**
--- a/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java Wed Mar 27 16:19:51 2013 +0400
@@ -57,7 +57,6 @@
import sun.awt.SunToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
-import sun.security.util.SecurityConstants;
/**
* <p>
@@ -260,6 +259,7 @@
}
final long format = lFormat.longValue();
+
Object ret = getNativeData(format);
if (ret instanceof byte[]) {
@@ -270,11 +270,14 @@
throw new InvalidDnDOperationException(e.getMessage());
}
} else if (ret instanceof InputStream) {
+ InputStream inputStream = (InputStream)ret;
try {
return DataTransferer.getInstance().
- translateStream((InputStream)ret, df, format, this);
+ translateStream(inputStream, df, format, this);
} catch (IOException e) {
throw new InvalidDnDOperationException(e.getMessage());
+ } finally {
+ inputStream.close();
}
} else {
throw new IOException("no native data was transfered");
--- a/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDataTransferer.java Wed Mar 27 16:19:51 2013 +0400
@@ -212,10 +212,9 @@
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
*/
- protected Image platformImageBytesOrStreamToImage(InputStream inputStream,
- byte[] bytes,
- long format)
- throws IOException {
+ protected Image platformImageBytesToImage(
+ byte[] bytes, long format) throws IOException
+ {
String mimeType = null;
if (format == PNG_ATOM.getAtom()) {
mimeType = "image/png";
@@ -235,7 +234,7 @@
}
}
if (mimeType != null) {
- return standardImageBytesOrStreamToImage(inputStream, bytes, mimeType);
+ return standardImageBytesToImage(bytes, mimeType);
} else {
String nativeFormat = getNativeForFormat(format);
throw new IOException("Translation from " + nativeFormat +
@@ -330,8 +329,8 @@
* a valid MIME and return a list of flavors to which the data in this MIME
* type can be translated by the Data Transfer subsystem.
*/
- public List getPlatformMappingsForNative(String nat) {
- List flavors = new ArrayList();
+ public List <DataFlavor> getPlatformMappingsForNative(String nat) {
+ List <DataFlavor> flavors = new ArrayList();
if (nat == null) {
return flavors;
@@ -346,16 +345,14 @@
return flavors;
}
- Object value = df;
+ DataFlavor value = df;
final String primaryType = df.getPrimaryType();
final String baseType = primaryType + "/" + df.getSubType();
// For text formats we map natives to MIME strings instead of data
// flavors to enable dynamic text native-to-flavor mapping generation.
// See SystemFlavorMap.getFlavorsForNative() for details.
- if ("text".equals(primaryType)) {
- value = primaryType + "/" + df.getSubType();
- } else if ("image".equals(primaryType)) {
+ if ("image".equals(primaryType)) {
Iterator readers = ImageIO.getImageReadersByMIMEType(baseType);
if (readers.hasNext()) {
flavors.add(DataFlavor.imageFlavor);
@@ -438,16 +435,13 @@
}
}
} else if (DataTransferer.isFlavorCharsetTextType(df)) {
- final Iterator iter = DataTransferer.standardEncodings();
-
// stringFlavor is semantically equivalent to the standard
// "text/plain" MIME type.
if (DataFlavor.stringFlavor.equals(df)) {
baseType = "text/plain";
}
- while (iter.hasNext()) {
- String encoding = (String)iter.next();
+ for (String encoding : DataTransferer.standardEncodings()) {
if (!encoding.equals(charset)) {
natives.add(baseType + ";charset=" + encoding);
}
--- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Fri Mar 22 19:56:20 2013 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java Wed Mar 27 16:19:51 2013 +0400
@@ -87,35 +87,35 @@
*/
public class WDataTransferer extends DataTransferer {
private static final String[] predefinedClipboardNames = {
- "",
- "TEXT",
- "BITMAP",
- "METAFILEPICT",
- "SYLK",
- "DIF",
- "TIFF",
- "OEM TEXT",
- "DIB",
- "PALETTE",
- "PENDATA",
- "RIFF",
- "WAVE",
- "UNICODE TEXT",
- "ENHMETAFILE",
- "HDROP",
- "LOCALE",
- "DIBV5"
+ "",
+ "TEXT",
+ "BITMAP",
+ "METAFILEPICT",
+ "SYLK",
+ "DIF",
+ "TIFF",
+ "OEM TEXT",
+ "DIB",
+ "PALETTE",
+ "PENDATA",
+ "RIFF",
+ "WAVE",
+ "UNICODE TEXT",
+ "ENHMETAFILE",
+ "HDROP",
+ "LOCALE",
+ "DIBV5"
};
private static final Map <String, Long> predefinedClipboardNameMap;
static {
Map <String,Long> tempMap =
- new HashMap <> (predefinedClipboardNames.length, 1.0f);
+ new HashMap <> (predefinedClipboardNames.length, 1.0f);
for (int i = 1; i < predefinedClipboardNames.length; i++) {
tempMap.put(predefinedClipboardNames[i], Long.valueOf(i));
}
predefinedClipboardNameMap =
- Collections.synchronizedMap(tempMap);
+ Collections.synchronizedMap(tempMap);
}
/**
@@ -138,18 +138,18 @@
//CF_FILECONTENTS supported as mandatory associated clipboard
private static final Long L_CF_LOCALE =
- predefinedClipboardNameMap.get(predefinedClipboardNames[CF_LOCALE]);
+ predefinedClipboardNameMap.get(predefinedClipboardNames[CF_LOCALE]);
private static final DirectColorModel directColorModel =
- new DirectColorModel(24,
- 0x00FF0000, /* red mask */
- 0x0000FF00, /* green mask */
- 0x000000FF); /* blue mask */
+ new DirectColorModel(24,
+ 0x00FF0000, /* red mask */
+ 0x0000FF00, /* green mask */
+ 0x000000FF); /* blue mask */
private static final int[] bandmasks = new int[] {
- directColorModel.getRedMask(),
- directColorModel.getGreenMask(),
- directColorModel.getBlueMask() };
+ directColorModel.getRedMask(),
+ directColorModel.getGreenMask(),
+ directColorModel.getBlueMask() };
/**
* Singleton constructor
@@ -171,10 +171,10 @@
}
public SortedMap <Long, DataFlavor> getFormatsForFlavors(
- DataFlavor[] flavors, FlavorTable map)
+ DataFlavor[] flavors, FlavorTable map)
{
SortedMap <Long, DataFlavor> retval =
- super.getFormatsForFlavors(flavors, map);
+ super.getFormatsForFlavors(flavors, map);
// The Win32 native code does not support exporting LOCALE data, nor
// should it.
@@ -191,32 +191,60 @@
DataFlavor flavor,
long format) throws IOException
{
- byte[] bytes = super.translateTransferable(contents, flavor, format);
-
+ byte[] bytes = null;
if (format == CF_HTML) {
- bytes = HTMLCodec.convertToHTMLFormat(bytes);
+ if (contents.isDataFlavorSupported(DataFlavor.selectionHtmlFlavor)) {
+ // if a user provides data represented by
+ // DataFlavor.selectionHtmlFlavor format, we use this
+ // type to store the data in the native clipboard
+ bytes = super.translateTransferable(contents,
+ DataFlavor.selectionHtmlFlavor,
+ format);
+ } else if (contents.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) {
+ // if we cannot get data represented by the
+ // DataFlavor.selectionHtmlFlavor format
+ // but the DataFlavor.allHtmlFlavor format is avialable
+ // we belive that the user knows how to represent
+ // the data and how to mark up selection in a
+ // system specific manner. Therefor, we use this data
+ bytes = super.translateTransferable(contents,
+ DataFlavor.allHtmlFlavor,
+ format);
+ } else {
+ // handel other html flavor types, including custom and
+ // fragment ones
+ bytes = HTMLCodec.convertToHTMLFormat(bytes);
+ }
+ } else {
+ // we handle non-html types basing on their
+ // flavors
+ bytes = super.translateTransferable(contents, flavor, format);
}
return bytes;
}
- protected Object translateBytesOrStream(InputStream str, byte[] bytes,
- DataFlavor flavor, long format,
- Transferable localeTransferable)
+ // The stream is closed as a closable object
+ public Object translateStream(InputStream str,
+ DataFlavor flavor, long format,
+ Transferable localeTransferable)
throws IOException
{
if (format == CF_HTML && flavor.isFlavorTextType()) {
- if (str == null) {
- str = new ByteArrayInputStream(bytes);
- bytes = null;
- }
+ str = new HTMLCodec(str,
+ EHTMLReadMode.getEHTMLReadMode(flavor));
+
+ }
+ return super.translateStream(str, flavor, format,
+ localeTransferable);
- str = new HTMLCodec(str, EHTMLReadMode.HTML_READ_SELECTION);
- }
+ }
+
+ public Object translateBytes(byte[] bytes, DataFlavor flavor, long format,
+ Transferable localeTransferable) throws IOException
+ {
+
if (format == CF_FILEGROUPDESCRIPTORA || format == CF_FILEGROUPDESCRIPTORW) {
- if (null != str ) {
- str.close();
- }
if (bytes == null || !DataFlavor.javaFileListFlavor.equals(flavor)) {
throw new IOException("data translation failed");
}
@@ -238,28 +266,24 @@
}
if (format == CFSTR_INETURL &&
- URL.class.equals(flavor.getRepresentationClass()))
+ URL.class.equals(flavor.getRepresentationClass()))
{
- if (bytes == null) {
- bytes = inputStreamToByteArray(str);
- str = null;
- }
String charset = getDefaultTextCharset();
if (localeTransferable != null && localeTransferable.
- isDataFlavorSupported(javaTextEncodingFlavor))
+ isDataFlavorSupported(javaTextEncodingFlavor))
{
try {
charset = new String((byte[])localeTransferable.
- getTransferData(javaTextEncodingFlavor),
- "UTF-8");
+ getTransferData(javaTextEncodingFlavor), "UTF-8");
} catch (UnsupportedFlavorException cannotHappen) {
}
}
return new URL(new String(bytes, charset));
}
- return super.translateBytesOrStream(str, bytes, flavor, format,
- localeTransferable);
+ return super.translateBytes(bytes , flavor, format,
+ localeTransferable);
+
}
public boolean isLocaleDependentTextFormat(long format) {
@@ -280,18 +304,18 @@
protected String getNativeForFormat(long format) {
return (format < predefinedClipboardNames.length)
- ? predefinedClipboardNames[(int)format]
- : getClipboardFormatName(format);
+ ? predefinedClipboardNames[(int)format]
+ : getClipboardFormatName(format);
}
private final ToolkitThreadBlockedHandler handler =
- new WToolkitThreadBlockedHandler();
+ new WToolkitThreadBlockedHandler();
public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
return handler;
}
- /**
+ /**
* Calls the Win32 RegisterClipboardFormat function to register
* a non-standard format.
*/
@@ -305,12 +329,12 @@
public boolean isImageFormat(long format) {
return format == CF_DIB || format == CF_ENHMETAFILE ||
- format == CF_METAFILEPICT || format == CF_PNG ||
- format == CF_JFIF;
+ format == CF_METAFILEPICT || format == CF_PNG ||
+ format == CF_JFIF;
}
protected byte[] imageToPlatformBytes(Image image, long format)
- throws IOException {
+ throws IOException {
String mimeType = null;
if (format == CF_PNG) {
mimeType = "image/png";
@@ -352,11 +376,11 @@
int[] nBits = {8, 8, 8};
int[] bOffs = {2, 1, 0};
ColorModel colorModel =
- new ComponentColorModel(cs, nBits, false, false,
- Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+ new ComponentColorModel(cs, nBits, false, false,
+ Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
WritableRaster raster =
- Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
- width * 3 + pad, 3, bOffs, null);
+ Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
+ width * 3 + pad, 3, bOffs, null);
BufferedImage bimage = new BufferedImage(colorModel, raster, false, null);
@@ -364,7 +388,7 @@
// top-down DIBs.
// So we flip the image vertically and create a bottom-up DIB.
AffineTransform imageFlipTransform =
- new AffineTransform(1, 0, 0, -1, 0, height);
+ new AffineTransform(1, 0, 0, -1, 0, height);
Graphics2D g2d = bimage.createGraphics();
@@ -383,7 +407,7 @@
private static final byte [] UNICODE_NULL_TERMINATOR = new byte [] {0,0};
protected ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList)
- throws IOException
+ throws IOException
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -407,10 +431,10 @@
return bos;
}
- /**
- * Returns a byte array which contains data special for the given format
- * and for the given image data.
- */
+ /**
+ * Returns a byte array which contains data special for the given format
+ * and for the given image data.
+ */
private native byte[] imageDataToPlatformImageBytes(byte[] imageData,
int width, int height,
long format);
@@ -419,10 +443,8 @@
* Translates either a byte array or an input stream which contain
* platform-specific image data in the given format into an Image.
*/
- protected Image platformImageBytesOrStreamToImage(InputStream str,
- byte[] bytes,
- long format)
- throws IOException {
+ protected Image platformImageBytesToImage(byte[] bytes, long format)
+ throws IOException {
String mimeType = null;
if (format == CF_PNG) {
mimeType = "image/png";
@@ -430,11 +452,7 @@
mimeType = "image/jpeg";
}
if (mimeType != null) {
- return standardImageBytesOrStreamToImage(str, bytes, mimeType);
- }
-
- if (bytes == null) {
- bytes = inputStreamToByteArray(str);
+ return standardImageBytesToImage(bytes, mimeType);
}
int[] imageData = platformImageBytesToImageData(bytes, format);
@@ -448,8 +466,8 @@
DataBufferInt buffer = new DataBufferInt(imageData, len);
WritableRaster raster = Raster.createPackedRaster(buffer, width,
- height, width,
- bandmasks, null);
+ height, width,
+ bandmasks, null);
return new BufferedImage(directColorModel, raster, false, null);
}
@@ -462,13 +480,13 @@
*/
private native int[] platformImageBytesToImageData(byte[] bytes,
long format)
- throws IOException;
+ throws IOException;
protected native String[] dragQueryFile(byte[] bytes);
}
final class WToolkitThreadBlockedHandler extends Mutex
- implements ToolkitThreadBlockedHandler {
+ implements ToolkitThreadBlockedHandler {
public void enter() {
if (!isOwned()) {
@@ -492,7 +510,22 @@
enum EHTMLReadMode {
HTML_READ_ALL,
HTML_READ_FRAGMENT,
- HTML_READ_SELECTION
+ HTML_READ_SELECTION;
+
+ public static EHTMLReadMode getEHTMLReadMode (DataFlavor df) {
+
+ EHTMLReadMode mode = HTML_READ_SELECTION;
+
+ String parameter = df.getParameter("document");
+
+ if ("all".equals(parameter)) {
+ mode = HTML_READ_ALL;
+ } else if ("fragment".equals(parameter)) {
+ mode = HTML_READ_FRAGMENT;
+ }
+
+ return mode;
+ }
}
/**
@@ -581,26 +614,24 @@
htmlSuffix = "</BODY>" + htmlSuffix;
};
};
- htmlPrefix = htmlPrefix + START_FRAGMENT_CMT;
- htmlSuffix = END_FRAGMENT_CMT + htmlSuffix;
}
String stBaseUrl = DEF_SOURCE_URL;
int nStartHTML =
- VERSION.length() + VERSION_NUM.length() + EOLN.length()
- + START_HTML.length() + PADDED_WIDTH + EOLN.length()
- + END_HTML.length() + PADDED_WIDTH + EOLN.length()
- + START_FRAGMENT.length() + PADDED_WIDTH + EOLN.length()
- + END_FRAGMENT.length() + PADDED_WIDTH + EOLN.length()
- + SOURCE_URL.length() + stBaseUrl.length() + EOLN.length()
- ;
+ VERSION.length() + VERSION_NUM.length() + EOLN.length()
+ + START_HTML.length() + PADDED_WIDTH + EOLN.length()
+ + END_HTML.length() + PADDED_WIDTH + EOLN.length()
+ + START_FRAGMENT.length() + PADDED_WIDTH + EOLN.length()
+ + END_FRAGMENT.length() + PADDED_WIDTH + EOLN.length()
+ + SOURCE_URL.length() + stBaseUrl.length() + EOLN.length()
+ ;
int nStartFragment = nStartHTML + htmlPrefix.length();
int nEndFragment = nStartFragment + bytes.length - 1;
int nEndHTML = nEndFragment + htmlSuffix.length();
StringBuilder header = new StringBuilder(
- nStartFragment
- + START_FRAGMENT_CMT.length()
+ nStartFragment
+ + START_FRAGMENT_CMT.length()
);
//header
header.append(VERSION);
@@ -639,14 +670,14 @@
}
byte[] retval = new byte[headerBytes.length + bytes.length +
- trailerBytes.length];
+ trailerBytes.length];
System.arraycopy(headerBytes, 0, retval, 0, headerBytes.length);
System.arraycopy(bytes, 0, retval, headerBytes.length,
- bytes.length - 1);
+ bytes.length - 1);
System.arraycopy(trailerBytes, 0, retval,
- headerBytes.length + bytes.length - 1,
- trailerBytes.length);
+ headerBytes.length + bytes.length - 1,
+ trailerBytes.length);
retval[retval.length-1] = 0;
return retval;
@@ -659,7 +690,7 @@
private boolean descriptionParsed = false;
private boolean closed = false;
- // InputStreamReader uses an 8K buffer. The size is not customizable.
+ // InputStreamReader uses an 8K buffer. The size is not customizable.
public static final int BYTE_BUFFER_LEN = 8192;
// CharToByteUTF8.getMaxBytesPerChar returns 3, so we should not buffer
@@ -667,30 +698,30 @@
public static final int CHAR_BUFFER_LEN = BYTE_BUFFER_LEN / 3;
private static final String FAILURE_MSG =
- "Unable to parse HTML description: ";
+ "Unable to parse HTML description: ";
private static final String INVALID_MSG =
- " invalid";
+ " invalid";
//HTML header mapping:
private long iHTMLStart,// StartHTML -- shift in array to the first byte after the header
- iHTMLEnd, // EndHTML -- shift in array of last byte for HTML syntax analysis
- iFragStart,// StartFragment -- shift in array jast after <!--StartFragment-->
- iFragEnd, // EndFragment -- shift in array before start <!--EndFragment-->
- iSelStart, // StartSelection -- shift in array of the first char in copied selection
- iSelEnd; // EndSelection -- shift in array of the last char in copied selection
+ iHTMLEnd, // EndHTML -- shift in array of last byte for HTML syntax analysis
+ iFragStart,// StartFragment -- shift in array jast after <!--StartFragment-->
+ iFragEnd, // EndFragment -- shift in array before start <!--EndFragment-->
+ iSelStart, // StartSelection -- shift in array of the first char in copied selection
+ iSelEnd; // EndSelection -- shift in array of the last char in copied selection
private String stBaseURL; // SourceURL -- base URL for related referenses
private String stVersion; // Version -- current supported version
//Stream reader markers:
private long iStartOffset,
- iEndOffset,
- iReadCount;
+ iEndOffset,
+ iReadCount;
private EHTMLReadMode readMode;
public HTMLCodec(
- InputStream _bytestream,
- EHTMLReadMode _readMode) throws IOException
+ InputStream _bytestream,
+ EHTMLReadMode _readMode) throws IOException
{
bufferedStream = new BufferedInputStream(_bytestream, BYTE_BUFFER_LEN);
readMode = _readMode;
@@ -723,31 +754,31 @@
// initialization of array offset pointers
// to the same "uninitialized" state.
iHTMLEnd =
- iHTMLStart =
- iFragEnd =
- iFragStart =
- iSelEnd =
- iSelStart = -1;
+ iHTMLStart =
+ iFragEnd =
+ iFragStart =
+ iSelEnd =
+ iSelStart = -1;
bufferedStream.mark(BYTE_BUFFER_LEN);
String astEntries[] = new String[] {
- //common
- VERSION,
- START_HTML,
- END_HTML,
- START_FRAGMENT,
- END_FRAGMENT,
- //ver 1.0
- START_SELECTION,
- END_SELECTION,
- SOURCE_URL
+ //common
+ VERSION,
+ START_HTML,
+ END_HTML,
+ START_FRAGMENT,
+ END_FRAGMENT,
+ //ver 1.0
+ START_SELECTION,
+ END_SELECTION,
+ SOURCE_URL
};
BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(
- bufferedStream,
- ENCODING
- ),
- CHAR_BUFFER_LEN
+ new InputStreamReader(
+ bufferedStream,
+ ENCODING
+ ),
+ CHAR_BUFFER_LEN
);
long iHeadSize = 0;
long iCRSize = EOLN.length();
@@ -769,30 +800,30 @@
if( null!=stValue ) {
try{
switch( iEntry ){
- case 0:
- stVersion = stValue;
- break;
- case 1:
- iHTMLStart = Integer.parseInt(stValue);
- break;
- case 2:
- iHTMLEnd = Integer.parseInt(stValue);
- break;
- case 3:
- iFragStart = Integer.parseInt(stValue);
- break;
- case 4:
- iFragEnd = Integer.parseInt(stValue);
- break;
- case 5:
- iSelStart = Integer.parseInt(stValue);
- break;
- case 6:
- iSelEnd = Integer.parseInt(stValue);
- break;
- case 7:
- stBaseURL = stValue;
- break;
+ case 0:
+ stVersion = stValue;
+ break;
+ case 1:
+ iHTMLStart = Integer.parseInt(stValue);
+ break;
+ case 2:
+ iHTMLEnd = Integer.parseInt(stValue);
+ break;
+ case 3:
+ iFragStart = Integer.parseInt(stValue);
+ break;
+ case 4:
+ iFragEnd = Integer.parseInt(stValue);
+ break;
+ case 5:
+ iSelStart = Integer.parseInt(stValue);
+ break;
+ case 6:
+ iSelEnd = Integer.parseInt(stValue);
+ break;
+ case 7:
+ stBaseURL = stValue;
+ break;
};
} catch ( NumberFormatException e ) {
throw new IOException(FAILURE_MSG + astEntries[iEntry]+ " value " + e + INVALID_MSG);
@@ -816,19 +847,19 @@
//one of possible modes
switch( readMode ){
- case HTML_READ_ALL:
- iStartOffset = iHTMLStart;
- iEndOffset = iHTMLEnd;
- break;
- case HTML_READ_FRAGMENT:
- iStartOffset = iFragStart;
- iEndOffset = iFragEnd;
- break;
- case HTML_READ_SELECTION:
- default:
- iStartOffset = iSelStart;
- iEndOffset = iSelEnd;
- break;
+ case HTML_READ_ALL:
+ iStartOffset = iHTMLStart;
+ iEndOffset = iHTMLEnd;
+ break;
+ case HTML_READ_FRAGMENT:
+ iStartOffset = iFragStart;
+ iEndOffset = iFragEnd;
+ break;
+ case HTML_READ_SELECTION:
+ default:
+ iStartOffset = iSelStart;
+ iEndOffset = iSelEnd;
+ break;
}
bufferedStream.reset();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HTMLDataFlavorTest.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 7075105
+ @summary WIN: Provide a way to format HTML on drop
+ @author Denis Fokin: area=datatransfer
+ @build HtmlTransferable PutAllHtmlFlavorsOnClipboard
+ @build PutOnlyAllHtmlFlavorOnClipboard PutSelectionAndFragmentHtmlFlavorsOnClipboard
+ @run main HTMLDataFlavorTest
+*/
+
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.io.*;
+import java.util.HashMap;
+
+public class HTMLDataFlavorTest {
+
+ private static HashMap<DataFlavor, String> dataFlavors = new HashMap<DataFlavor, String>();
+
+
+ public static void main(String[] args) throws IOException, UnsupportedFlavorException {
+
+ dataFlavors.put(DataFlavor.allHtmlFlavor, HtmlTransferable.ALL_HTML_AS_STRING);
+ dataFlavors.put(DataFlavor.fragmentHtmlFlavor, HtmlTransferable.FRAGMENT_HTML_AS_STRING);
+ dataFlavors.put(DataFlavor.selectionHtmlFlavor, HtmlTransferable.SELECTION_HTML_AS_STRING);
+
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ resetClipboardContent(clipboard);
+
+ // 1. Put all three html flavors on clipboard.
+ // Get the data within the same JVM
+ // Expect that the resulted html is the selection
+ // wrapped in all three types
+
+ clipboard.setContents(new HtmlTransferable(HtmlTransferable.htmlDataFlavors),null);
+
+ // Test local transfer
+ testClipboardContent(clipboard, HtmlTransferable.htmlDataFlavors);
+
+ resetClipboardContent(clipboard);
+
+ // 2. Put only DataFlavor.allHtmlFlavor on clipboard.
+ // Expect that the resulted html is the all
+ // wrapped in all three types
+
+ putHtmlInAnotherProcess("PutOnlyAllHtmlFlavorOnClipboard");
+
+ for (DataFlavor df : HtmlTransferable.htmlDataFlavors) {
+ if (!clipboard.isDataFlavorAvailable(df)) {
+ throw new RuntimeException("The data should be available.");
+ }
+ }
+
+ if (!clipboard.getData(DataFlavor.allHtmlFlavor).toString().
+ equals(dataFlavors.get(DataFlavor.allHtmlFlavor).toString()))
+ {
+ throw new RuntimeException("DataFlavor.allHtmlFlavor data " +
+ "should be identical to the data put on the source side.");
+ }
+
+ resetClipboardContent(clipboard);
+
+ // 3. Put all three html flavors on clipboard.
+ // Expect that the resulted html is the selection
+ // wrapped in all three types
+
+ putHtmlInAnotherProcess("PutAllHtmlFlavorsOnClipboard");
+
+ for (DataFlavor df : HtmlTransferable.htmlDataFlavors) {
+ if (!clipboard.isDataFlavorAvailable(df)) {
+ throw new RuntimeException("The data should be available.");
+ }
+ }
+
+ if (!clipboard.getData(DataFlavor.selectionHtmlFlavor).toString().
+ equals(dataFlavors.get(DataFlavor.selectionHtmlFlavor)))
+ {
+ throw new RuntimeException("DataFlavor.allHtmlFlavor data " +
+ "should be identical to the data put on the source side.");
+ }
+
+ }
+
+ private static void resetClipboardContent(Clipboard clipboard) {
+ clipboard.setContents(
+ new StringSelection("The data is used to empty the clipboard content"
+ ),null);
+ }
+
+
+ private static void putHtmlInAnotherProcess(String putterCommand) {
+ try {
+
+ String command = System.getProperty("java.home") + "/bin/java -cp " +
+ System.getProperty("test.classes", ".") + " " +
+ putterCommand;
+
+ System.out.println("Execute process : " + command);
+
+ Process p = Runtime.getRuntime().exec(command);
+
+ try {
+ p.waitFor();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("The data has been set remotely");
+
+ try (BufferedReader stdstr = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+ String s;
+ while ((s = stdstr.readLine()) != null) {
+ s = stdstr.readLine();
+ System.out.println(s);
+ }
+ }
+
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()))) {
+ String s;
+ while ((s = br.readLine()) != null) {
+ s = br.readLine();
+ System.err.println(s);
+ }
+ }
+
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void testClipboardContent(Clipboard clipboard,
+ DataFlavor [] expectedDataFlavors)
+ throws UnsupportedFlavorException, IOException {
+
+ for (DataFlavor df : clipboard.getAvailableDataFlavors()) {
+ System.out.println("available df: " + df.getMimeType());
+ }
+
+ for (DataFlavor df : expectedDataFlavors) {
+
+ if (!clipboard.isDataFlavorAvailable(df)) {
+ throw new RuntimeException("The data should be available.");
+ }
+
+
+ System.out.println("Checking \"" + df.getParameter("document") + "\" for correspondence");
+
+ if (!dataFlavors.get(df).toString().equals(clipboard.getData(df).toString())) {
+
+ System.err.println("Expected data: " + dataFlavors.get(df).toString());
+ System.err.println("Actual data: " + clipboard.getData(df).toString());
+
+
+ throw new RuntimeException("An html flavor with parameter \"" +
+ df.getParameter("document") + "\" does not correspond to the transferred data.");
+
+
+ }
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/HtmlTransferable.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+
+/**
+ * A transferable that mimic ie html data
+ */
+class HtmlTransferable implements Transferable {
+
+ final static String SOURCE_HTML = "<html><head><title>Simple html content</title></head>" +
+ "<body><ol><li>Dasha</li><li>Masha</li><li>Lida</li></ol></body></html>";
+
+ // Data identical to ie output for the next html without end of lines,
+ // that is gotten by java system clipboard
+ // <html>
+ // <head>
+ // <title>Simple html content</title>
+ // </head>
+ // <body>
+ // <ol>
+ // <li>Dasha</li>
+ // <li>Masha</li>
+ // <li>Lida</li>
+ // </ol>
+ // </body>
+ // </html>
+
+ final static String ALL_HTML_AS_STRING = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" +
+ "\n" +
+ "<HTML><HEAD><TITLE>Simple html content</TITLE></HEAD>\n" +
+ "\n" +
+ "<BODY>\n" +
+ "\n" +
+ "<OL><!--StartFragment--><LI>Masha\n" +
+ "<LI>Lida</LI><!--EndFragment--></OL>\n" +
+ "</BODY>\n" +
+ "</HTML>";
+
+ final static String FRAGMENT_HTML_AS_STRING = "<LI>Masha\n" +
+ "<LI>Lida</LI>";
+
+ final static String SELECTION_HTML_AS_STRING = "<LI>Masha" +
+ "<LI>Lida</LI>";
+
+ private DataFlavor[] supportedDataFlavors;
+
+ final static DataFlavor[] htmlDataFlavors = new DataFlavor [] {
+ DataFlavor.allHtmlFlavor,
+ DataFlavor.fragmentHtmlFlavor,
+ DataFlavor.selectionHtmlFlavor
+ };
+
+ @Override
+ public DataFlavor[] getTransferDataFlavors() {
+ return supportedDataFlavors;
+ }
+
+ @Override
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ for (DataFlavor supportedDataFlavor : supportedDataFlavors) {
+ if (supportedDataFlavor.equals(flavor)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ HtmlTransferable(DataFlavor[] supportedDataFlavors) {
+ this.supportedDataFlavors = supportedDataFlavors;
+ }
+
+ @Override
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException {
+
+ if (isDataFlavorSupported(flavor)) {
+ if (flavor.equals(DataFlavor.allHtmlFlavor)) {
+ return ALL_HTML_AS_STRING;
+ } else if (flavor.equals(DataFlavor.fragmentHtmlFlavor)) {
+ return FRAGMENT_HTML_AS_STRING;
+ } else if (flavor.equals(DataFlavor.selectionHtmlFlavor)) {
+ return SELECTION_HTML_AS_STRING;
+ }
+ }
+
+ throw new UnsupportedFlavorException(flavor);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.html Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,20 @@
+<html>
+<!--
+ @test
+ @bug 7075105
+ @summary WIN: Provide a way to format HTML on drop
+ @author Denis Fokin area=datatransfer
+ @run applet/manual=yesno ManualHTMLDataFlavorTest.html
+ -->
+<head>
+<title>ManualHTMLDataFlavorTest</title>
+</head>
+<body>
+
+<h1>ManualHTMLDataFlavorTest<br>Bug ID: 7075105</h1>
+
+<p> See the dialog box (usually in upper left corner) for instructions</p>
+
+<APPLET CODE="ManualHTMLDataFlavorTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/ManualHTMLDataFlavorTest.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ test
+ @bug 7075105
+ @summary WIN: Provide a way to format HTML on drop
+ @author Denis Fokin: area=datatransfer
+ @run applet/manual=yesno ManualHTMLDataFlavorTest
+*/
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.*;
+import java.io.IOException;
+
+public class ManualHTMLDataFlavorTest extends Applet {
+
+ class DropPane extends Panel implements DropTargetListener {
+
+ DropPane() {
+ requestFocus();
+ setBackground(Color.red);
+ setDropTarget(new DropTarget(this, DnDConstants.ACTION_COPY, this));
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(200,200);
+ }
+
+ @Override
+ public void dragEnter(DropTargetDragEvent dtde) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+
+ @Override
+ public void dragOver(DropTargetDragEvent dtde) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+
+ @Override
+ public void dropActionChanged(DropTargetDragEvent dtde) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+
+ @Override
+ public void dragExit(DropTargetEvent dte) {}
+
+ @Override
+ public void drop(DropTargetDropEvent dtde) {
+ if (!dtde.isDataFlavorSupported(DataFlavor.allHtmlFlavor)) {
+ Sysout.println("DataFlavor.allHtmlFlavor is not present in the system clipboard");
+ dtde.rejectDrop();
+ return;
+ } else if (!dtde.isDataFlavorSupported(DataFlavor.fragmentHtmlFlavor)) {
+ Sysout.println("DataFlavor.fragmentHtmlFlavor is not present in the system clipboard");
+ dtde.rejectDrop();
+ return;
+ } else if (!dtde.isDataFlavorSupported(DataFlavor.selectionHtmlFlavor)) {
+ Sysout.println("DataFlavor.selectionHtmlFlavor is not present in the system clipboard");
+ dtde.rejectDrop();
+ return;
+ }
+
+ dtde.acceptDrop(DnDConstants.ACTION_COPY);
+
+ Transferable t = dtde.getTransferable();
+ try {
+ Sysout.println("ALL:");
+ Sysout.println(t.getTransferData(DataFlavor.allHtmlFlavor).toString());
+ Sysout.println("FRAGMENT:");
+ Sysout.println(t.getTransferData(DataFlavor.fragmentHtmlFlavor).toString());
+ Sysout.println("SELECTION:");
+ Sysout.println(t.getTransferData(DataFlavor.selectionHtmlFlavor).toString());
+ } catch (UnsupportedFlavorException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ public void init() {
+
+ String[] instructions =
+ {
+ "1) The test contains a drop-aware panel with a red background",
+ "2) Open some page in a browser, select some text",
+ " Drag and drop it on the red panel",
+ " IMPORTANT NOTE: the page should be stored locally.",
+ " otherwise for instance iexplore can prohibit drag and drop from",
+ " the browser to other applications because of",
+ " the protected mode restrictions.",
+ "3) Check the data in the output area of this dialog",
+ "5) The output should not contain information that any of",
+ " flavors is not present in the system clipboard",
+ "6) The output should contain data in three different formats",
+ " provided by the system clipboard",
+ " - Data after the \"ALL:\" marker should include the data",
+ " from the the \"SELECTION:\" marker",
+ " - Data after the \"FRAGMENT\" marker should include the data",
+ " from the \"SELECTION:\" marker and may be some closing",
+ " tags could be added to the mark-up",
+ " - Data after the \"SELECTION:\" marker should correspond",
+ " to the data selected in the browser",
+ "7) If the above requirements are met, the test is passed"
+ };
+
+ add(new DropPane());
+ Sysout.createDialogWithInstructions( instructions );
+
+ new ManualHTMLDataFlavorTest();
+ }
+
+ public void start ()
+ {
+ setSize (200,200);
+ setVisible(true);
+ validate();
+
+ }// start()
+
+}
+
+
+/* Place other classes related to the test after this line */
+
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/PutAllHtmlFlavorsOnClipboard.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.awt.*;
+
+public class PutAllHtmlFlavorsOnClipboard {
+ public static void main(String[] args) {
+ System.out.println("PutAllHtmlFlavorsOnClipboard has been started.");
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
+ new HtmlTransferable(HtmlTransferable.htmlDataFlavors), null);
+ System.out.println("Data has been put on clipboard in a separate process");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/PutOnlyAllHtmlFlavorOnClipboard.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+
+public class PutOnlyAllHtmlFlavorOnClipboard {
+ public static void main(String[] args) {
+ System.out.println("PutOnlyAllHtmlFlavorOnClipboard has been started.");
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
+ new HtmlTransferable(new DataFlavor[]{DataFlavor.allHtmlFlavor}), null);
+ System.out.println("Data has been put on clipboard in a separate process");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/datatransfer/HTMLDataFlavors/PutSelectionAndFragmentHtmlFlavorsOnClipboard.java Wed Mar 27 16:19:51 2013 +0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+
+public class PutSelectionAndFragmentHtmlFlavorsOnClipboard {
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
+ new HtmlTransferable(new DataFlavor[]{DataFlavor.selectionHtmlFlavor,
+ DataFlavor.fragmentHtmlFlavor}), null);
+ }
+}