src/share/classes/java/awt/datatransfer/SystemFlavorMap.java

Print this page

        

*** 39,49 **** import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; ! import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import sun.awt.AppContext; --- 39,49 ---- import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; ! import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import sun.awt.AppContext;
*** 101,110 **** --- 101,115 ---- * 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,132 **** /** * 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(); /** * 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() { if (!isMapInitialized) { initSystemFlavorMap(); } return nativeToFlavor; } --- 118,137 ---- /** * Maps native Strings to Lists of DataFlavors (or base type Strings for * text DataFlavors). * Do not use the field directly, use getNativeToFlavor() instead. */ ! 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<String, List<DataFlavor>> getNativeToFlavor() { if (!isMapInitialized) { initSystemFlavorMap(); } return nativeToFlavor; }
*** 134,144 **** /** * 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(); /** * 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. --- 139,149 ---- /** * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of * native Strings. * Do not use the field directly, use getFlavorToNative() instead. */ ! 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,426 **** ee.printStackTrace(); continue; } } ! // For text/* flavors, store mappings in separate maps to ! // enable dynamic mapping generation at a run-time. if ("text".equals(flavor.getPrimaryType())) { ! store(value, key, getFlavorToNative()); ! store(key, value, getNativeToFlavor()); ! } else { ! store(flavor, key, getFlavorToNative()); ! store(key, flavor, getNativeToFlavor()); } } } } } --- 414,434 ---- ee.printStackTrace(); continue; } } ! final LinkedHashSet<DataFlavor> dfs = new LinkedHashSet<>(); ! ! dfs.add(flavor); ! if ("text".equals(flavor.getPrimaryType())) { ! dfs.addAll(convertMimeTypeToDataFlavors(value)); ! } ! ! for (DataFlavor df : dfs) { ! store(df, key, getFlavorToNative()); ! store(key, df, getNativeToFlavor()); } } } } }
*** 518,528 **** * 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); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { List platformFlavors = --- 526,536 ---- * 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<DataFlavor> flavors = getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); if (transferer != null) { List platformFlavors =
*** 613,623 **** getFlavorToNative().put(flav, natives); natives.add(encoded); getNativesForFlavorCache.remove(flav); getNativesForFlavorCache.remove(null); ! List flavors = (List)getNativeToFlavor().get(encoded); if (flavors == null) { flavors = new ArrayList(1); getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); --- 621,631 ---- getFlavorToNative().put(flav, natives); natives.add(encoded); getNativesForFlavorCache.remove(flav); getNativesForFlavorCache.remove(null); ! List<DataFlavor> flavors = getNativeToFlavor().get(encoded); if (flavors == null) { flavors = new ArrayList(1); getNativeToFlavor().put(encoded, flavors); } flavors.add(flav);
*** 669,679 **** return new ArrayList(retval); } } if (flav == null) { ! retval = new ArrayList(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)) { --- 677,687 ---- return new ArrayList(retval); } } if (flav == null) { ! 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,940 **** if (retval != null) { return (List)retval.clone(); } } ! LinkedList retval = new LinkedList(); if (nat == null) { ! List natives = getNativesForFlavor(null); ! HashSet dups = new HashSet(natives.size()); ! for (Iterator natives_iter = natives.iterator(); ! natives_iter.hasNext(); ) { ! List flavors = ! getFlavorsForNative((String)natives_iter.next()); ! for (Iterator flavors_iter = flavors.iterator(); ! flavors_iter.hasNext(); ) { ! Object flavor = flavors_iter.next(); ! if (dups.add(flavor)) { ! retval.add(flavor); ! } } } } else { ! List 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(); ! 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); ! } } } } ! ArrayList arrayList = new ArrayList(retval); ! getFlavorsForNativeCache.put(nat, new SoftReference(arrayList)); ! return (List)arrayList.clone(); } /** * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to * their most preferred <code>String</code> native. Each native value will --- 805,970 ---- if (retval != null) { return (List)retval.clone(); } } ! final LinkedHashSet <DataFlavor> returnValue = ! new LinkedHashSet<>(); if (nat == null) { ! final List<String> natives = getNativesForFlavor(null); ! for (String n : natives) { ! final List<DataFlavor> flavors = getFlavorsForNative(n); ! ! for (DataFlavor df : flavors) { ! returnValue.add(df); } } } else { ! ! final List<DataFlavor> flavors = nativeToFlavorLookup(nat); if (disabledMappingGenerationKeys.contains(nat)) { return flavors; } ! 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(); ! } ! } ! } ! ! } ! 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); } ! ! 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; } /** * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to * their most preferred <code>String</code> native. Each native value will