*/
public synchronized List<String> getNativesForFlavor(DataFlavor flav) {
List retval = null;
// Check cache, even for null flav
SoftReference ref = (SoftReference)getNativesForFlavorCache.get(flav);
if (ref != null) {
retval = (List)ref.get();
if (retval != null) {
// Create a copy, because client code can modify the returned
// list.
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)) {
// For text/* flavors, flavor-to-native mappings specified in
// flavormap.properties are stored per flavor's base type.
if ("text".equals(flav.getPrimaryType())) {
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
if (retval != null) {
// To prevent the List stored in the map from modification.
retval = new ArrayList(retval);
}
}
// Also include text/plain natives, but don't duplicate Strings
List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
if (textPlainList != null && !textPlainList.isEmpty()) {
// To prevent the List stored in the map from modification.
// This also guarantees that removeAll() is supported.
textPlainList = new ArrayList(textPlainList);
if (retval != null && !retval.isEmpty()) {
// Use HashSet to get constant-time performance for search.
textPlainList.removeAll(new HashSet(retval));
retval.addAll(textPlainList);
} else {
retval = textPlainList;
}
}
if (retval == null || retval.isEmpty()) {
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
} else {
// In this branch it is guaranteed that natives explicitly
// listed for flav's MIME type were added with
// addUnencodedNativeForFlavor(), so they have lower priority.
List explicitList =
flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
// flavorToNativeLookup() never returns null.
// It can return an empty List, however.
if (!explicitList.isEmpty()) {
// To prevent the List stored in the map from modification.
// This also guarantees that removeAll() is supported.
explicitList = new ArrayList(explicitList);
// Use HashSet to get constant-time performance for search.
explicitList.removeAll(new HashSet(retval));
retval.addAll(explicitList);
}
}
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
if (retval == null || retval.isEmpty()) {
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
} else {
// In this branch it is guaranteed that natives explicitly
// listed for flav's MIME type were added with
// addUnencodedNativeForFlavor(), so they have lower priority.
List explicitList =
flavorToNativeLookup(flav, !SYNTHESIZE_IF_NOT_FOUND);
// flavorToNativeLookup() never returns null.
// It can return an empty List, however.
if (!explicitList.isEmpty()) {
// To prevent the List stored in the map from modification.
// This also guarantees that add/removeAll() are supported.
retval = new ArrayList(retval);
explicitList = new ArrayList(explicitList);
// Use HashSet to get constant-time performance for search.
explicitList.removeAll(new HashSet(retval));
retval.addAll(explicitList);
}
}
} else {
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
}
getNativesForFlavorCache.put(flav, new SoftReference(retval));
// Create a copy, because client code can modify the returned list.
return new ArrayList(retval);
}