src/share/classes/java/awt/datatransfer/SystemFlavorMap.java
Print this page
@@ -39,11 +39,11 @@
import java.util.ArrayList;
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;
import sun.awt.AppContext;
@@ -101,10 +101,15 @@
* A String representing text/plain MIME type.
*/
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
* 'flavorToNative' map.
*/
@@ -113,20 +118,20 @@
/**
* Maps native Strings to Lists of DataFlavors (or base type Strings for
* 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
* use this accessor instead of direct access to the field which may not be
* initialized yet. This method will initialize the field if needed.
*
* @return nativeToFlavor
*/
- private Map getNativeToFlavor() {
+ private Map<String, List<DataFlavor>> getNativeToFlavor() {
if (!isMapInitialized) {
initSystemFlavorMap();
}
return nativeToFlavor;
}
@@ -134,11 +139,11 @@
/**
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
* 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
* use this accessor instead of direct access to the field which may not be
* initialized yet. This method will initialize the field if needed.
@@ -409,18 +414,21 @@
ee.printStackTrace();
continue;
}
}
- // 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());
}
}
}
}
}
@@ -518,11 +526,11 @@
* handles the case where 'nat' is not found in 'nativeToFlavor'. In that
* case, a new DataFlavor is synthesized, stored, and returned, if and
* 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();
if (transferer != null) {
List platformFlavors =
@@ -613,11 +621,11 @@
getFlavorToNative().put(flav, natives);
natives.add(encoded);
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);
}
flavors.add(flav);
@@ -669,11 +677,11 @@
return new ArrayList(retval);
}
}
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.
retval = flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
} else if (DataTransferer.isFlavorCharsetTextType(flav)) {
@@ -797,144 +805,166 @@
if (retval != null) {
return (List)retval.clone();
}
}
- 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());
+ final List<DataFlavor> flavorsAndBaseTypes =
+ nativeToFlavorLookup(nat);
+
+ 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();
+ }
+ }
+ }
+
+ }
- List flavorsAndbaseTypes = nativeToFlavorLookup(nat);
+ 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>();
- 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);
+ 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);
}
- if (DataTransferer.doesSubtypeSupportCharset(subType,
- null)) {
- if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
- dups.add(DataFlavor.stringFlavor))
+
+ if (DataTransferer.doesSubtypeSupportCharset(subType, null)) {
+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
{
- retval.add(DataFlavor.stringFlavor);
+ returnValue.add(DataFlavor.stringFlavor);
}
- for (int i = 0; i < UNICODE_TEXT_CLASSES.length; i++) {
+ 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
- (baseType + ";charset=Unicode;class=" +
- UNICODE_TEXT_CLASSES[i]);
+ toAdd = new DataFlavor(mt);
} catch (ClassNotFoundException cannotHappen) {
}
- if (dups.add(toAdd)) {
- retval.add(toAdd);
+ returnValue.add(toAdd);
}
}
- for (Iterator charset_iter =
- DataTransferer.standardEncodings();
- charset_iter.hasNext(); )
- {
- String charset = (String)charset_iter.next();
+ for (String charset : DataTransferer.standardEncodings()) {
- 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) {
- }
+ 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 (toAdd.equals(DataFlavor.plainTextFlavor)) {
- toAdd = DataFlavor.plainTextFlavor;
+ if (df.equals(DataFlavor.plainTextFlavor)) {
+ df = DataFlavor.plainTextFlavor;
+ }
+ } catch (ClassNotFoundException cannotHappen) {
}
- if (dups.add(toAdd)) {
- retval.add(toAdd);
+ returnValue.add(df);
}
}
}
- if (TEXT_PLAIN_BASE_TYPE.equals(baseType) &&
- dups.add(DataFlavor.plainTextFlavor))
+ if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
{
- retval.add(DataFlavor.plainTextFlavor);
+ returnValue.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++) {
+ for (String encodedTextClassName : ENCODED_TEXT_CLASSES) {
DataFlavor toAdd = null;
try {
toAdd = new DataFlavor(baseType +
- ";class=" + ENCODED_TEXT_CLASSES[i]);
+ ";class=" + encodedTextClassName);
} catch (ClassNotFoundException cannotHappen) {
}
-
- if (dups.add(toAdd)) {
- retval.add(toAdd);
- }
+ returnValue.add(toAdd);
}
}
- } else {
- DataFlavor flavor = (DataFlavor)value;
- if (dups.add(flavor)) {
- retval.add(flavor);
- }
+ 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);
}
- ArrayList arrayList = new ArrayList(retval);
- getFlavorsForNativeCache.put(nat, new SoftReference(arrayList));
- return (List)arrayList.clone();
+ return returnValues;
}
/**
* Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
* their most preferred <code>String</code> native. Each native value will