6603256: Startup: Defer initialization of DropTarget's flavorMap
SystemFlavorMap is lazily initialized now. Reviewed-by: uta
This commit is contained in:
parent
16b0d38feb
commit
c02f0bd9b7
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,7 +49,6 @@ import java.util.WeakHashMap;
|
|||||||
|
|
||||||
import sun.awt.datatransfer.DataTransferer;
|
import sun.awt.datatransfer.DataTransferer;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
||||||
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
||||||
@ -117,15 +116,50 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
/**
|
/**
|
||||||
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
||||||
* text DataFlavors).
|
* text DataFlavors).
|
||||||
|
* Do not use the field directly, use getNativeToFlavor() instead.
|
||||||
*/
|
*/
|
||||||
private Map nativeToFlavor = new HashMap();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
||||||
* native Strings.
|
* native Strings.
|
||||||
|
* Do not use the field directly, use getFlavorToNative() instead.
|
||||||
*/
|
*/
|
||||||
private Map flavorToNative = new HashMap();
|
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.
|
||||||
|
*
|
||||||
|
* @return flavorToNative
|
||||||
|
*/
|
||||||
|
private synchronized Map getFlavorToNative() {
|
||||||
|
if (!isMapInitialized) {
|
||||||
|
initSystemFlavorMap();
|
||||||
|
}
|
||||||
|
return flavorToNative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows if the object has been initialized.
|
||||||
|
*/
|
||||||
|
private boolean isMapInitialized = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
|
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
|
||||||
* SoftReferences which reference Lists of String natives.
|
* SoftReferences which reference Lists of String natives.
|
||||||
@ -169,15 +203,24 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
return fm;
|
return fm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a SystemFlavorMap by reading flavormap.properties and
|
|
||||||
* AWT.DnD.flavorMapFileURL.
|
|
||||||
*/
|
|
||||||
private SystemFlavorMap() {
|
private SystemFlavorMap() {
|
||||||
BufferedReader flavormapDotProperties = (BufferedReader)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a SystemFlavorMap by reading flavormap.properties and
|
||||||
|
* AWT.DnD.flavorMapFileURL.
|
||||||
|
* For thread-safety must be called under lock on this.
|
||||||
|
*/
|
||||||
|
private void initSystemFlavorMap() {
|
||||||
|
if (isMapInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isMapInitialized = true;
|
||||||
|
BufferedReader flavormapDotProperties =
|
||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction<BufferedReader>() {
|
||||||
public Object run() {
|
public BufferedReader run() {
|
||||||
String fileName =
|
String fileName =
|
||||||
System.getProperty("java.home") +
|
System.getProperty("java.home") +
|
||||||
File.separator +
|
File.separator +
|
||||||
@ -197,12 +240,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
BufferedReader flavormapURL = (BufferedReader)
|
BufferedReader flavormapURL =
|
||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction<BufferedReader>() {
|
||||||
public Object run() {
|
public BufferedReader run() {
|
||||||
String url = Toolkit.getDefaultToolkit().getProperty
|
String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
|
||||||
("AWT.DnD.flavorMapFileURL", null);
|
|
||||||
|
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -237,7 +279,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copied code from java.util.Properties. Parsing the data ourselves is the
|
* Copied code from java.util.Properties. Parsing the data ourselves is the
|
||||||
* only way to handle duplicate keys and values.
|
* only way to handle duplicate keys and values.
|
||||||
@ -388,11 +429,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
// For text/* flavors, store mappings in separate maps to
|
// For text/* flavors, store mappings in separate maps to
|
||||||
// enable dynamic mapping generation at a run-time.
|
// enable dynamic mapping generation at a run-time.
|
||||||
if ("text".equals(flavor.getPrimaryType())) {
|
if ("text".equals(flavor.getPrimaryType())) {
|
||||||
store(value, key, flavorToNative);
|
store(value, key, getFlavorToNative());
|
||||||
store(key, value, nativeToFlavor);
|
store(key, value, getNativeToFlavor());
|
||||||
} else {
|
} else {
|
||||||
store(flavor, key, flavorToNative);
|
store(flavor, key, getFlavorToNative());
|
||||||
store(key, flavor, nativeToFlavor);
|
store(key, flavor, getNativeToFlavor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,7 +535,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
* only if the specified native is encoded as a Java MIME type.
|
* only if the specified native is encoded as a Java MIME type.
|
||||||
*/
|
*/
|
||||||
private List nativeToFlavorLookup(String nat) {
|
private List nativeToFlavorLookup(String nat) {
|
||||||
List flavors = (List)nativeToFlavor.get(nat);
|
List flavors = (List)getNativeToFlavor().get(nat);
|
||||||
|
|
||||||
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
|
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
|
||||||
DataTransferer transferer = DataTransferer.getInstance();
|
DataTransferer transferer = DataTransferer.getInstance();
|
||||||
@ -530,15 +571,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
|
|
||||||
if (flavor != null) {
|
if (flavor != null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(nat, flavors);
|
getNativeToFlavor().put(nat, flavors);
|
||||||
flavors.add(flavor);
|
flavors.add(flavor);
|
||||||
getFlavorsForNativeCache.remove(nat);
|
getFlavorsForNativeCache.remove(nat);
|
||||||
getFlavorsForNativeCache.remove(null);
|
getFlavorsForNativeCache.remove(null);
|
||||||
|
|
||||||
List natives = (List)flavorToNative.get(flavor);
|
List natives = (List)getFlavorToNative().get(flavor);
|
||||||
if (natives == null) {
|
if (natives == null) {
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flavor, natives);
|
getFlavorToNative().put(flavor, natives);
|
||||||
}
|
}
|
||||||
natives.add(nat);
|
natives.add(nat);
|
||||||
getNativesForFlavorCache.remove(flavor);
|
getNativesForFlavorCache.remove(flavor);
|
||||||
@ -559,7 +600,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
*/
|
*/
|
||||||
private List flavorToNativeLookup(final DataFlavor flav,
|
private List flavorToNativeLookup(final DataFlavor flav,
|
||||||
final boolean synthesize) {
|
final boolean synthesize) {
|
||||||
List natives = (List)flavorToNative.get(flav);
|
List natives = (List)getFlavorToNative().get(flav);
|
||||||
|
|
||||||
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
|
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
|
||||||
DataTransferer transferer = DataTransferer.getInstance();
|
DataTransferer transferer = DataTransferer.getInstance();
|
||||||
@ -584,15 +625,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
if (synthesize) {
|
if (synthesize) {
|
||||||
String encoded = encodeDataFlavor(flav);
|
String encoded = encodeDataFlavor(flav);
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flav, natives);
|
getFlavorToNative().put(flav, natives);
|
||||||
natives.add(encoded);
|
natives.add(encoded);
|
||||||
getNativesForFlavorCache.remove(flav);
|
getNativesForFlavorCache.remove(flav);
|
||||||
getNativesForFlavorCache.remove(null);
|
getNativesForFlavorCache.remove(null);
|
||||||
|
|
||||||
List flavors = (List)nativeToFlavor.get(encoded);
|
List flavors = (List)getNativeToFlavor().get(encoded);
|
||||||
if (flavors == null) {
|
if (flavors == null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(encoded, flavors);
|
getNativeToFlavor().put(encoded, flavors);
|
||||||
}
|
}
|
||||||
flavors.add(flav);
|
flavors.add(flav);
|
||||||
getFlavorsForNativeCache.remove(encoded);
|
getFlavorsForNativeCache.remove(encoded);
|
||||||
@ -645,7 +686,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flav == null) {
|
if (flav == null) {
|
||||||
retval = new ArrayList(nativeToFlavor.keySet());
|
retval = new ArrayList(getNativeToFlavor().keySet());
|
||||||
} else if (disabledMappingGenerationKeys.contains(flav)) {
|
} else if (disabledMappingGenerationKeys.contains(flav)) {
|
||||||
// In this case we shouldn't synthesize a native for this flavor,
|
// In this case we shouldn't synthesize a native for this flavor,
|
||||||
// since its mappings were explicitly specified.
|
// since its mappings were explicitly specified.
|
||||||
@ -655,7 +696,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
// For text/* flavors, flavor-to-native mappings specified in
|
// For text/* flavors, flavor-to-native mappings specified in
|
||||||
// flavormap.properties are stored per flavor's base type.
|
// flavormap.properties are stored per flavor's base type.
|
||||||
if ("text".equals(flav.getPrimaryType())) {
|
if ("text".equals(flav.getPrimaryType())) {
|
||||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||||
if (retval != null) {
|
if (retval != null) {
|
||||||
// To prevent the List stored in the map from modification.
|
// To prevent the List stored in the map from modification.
|
||||||
retval = new ArrayList(retval);
|
retval = new ArrayList(retval);
|
||||||
@ -663,7 +704,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Also include text/plain natives, but don't duplicate Strings
|
// Also include text/plain natives, but don't duplicate Strings
|
||||||
List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
|
List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
|
||||||
|
|
||||||
if (textPlainList != null && !textPlainList.isEmpty()) {
|
if (textPlainList != null && !textPlainList.isEmpty()) {
|
||||||
// To prevent the List stored in the map from modification.
|
// To prevent the List stored in the map from modification.
|
||||||
@ -699,7 +740,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
|
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
|
||||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||||
|
|
||||||
if (retval == null || retval.isEmpty()) {
|
if (retval == null || retval.isEmpty()) {
|
||||||
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
|
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
|
||||||
@ -1025,10 +1066,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
List natives = (List)flavorToNative.get(flav);
|
List natives = (List)getFlavorToNative().get(flav);
|
||||||
if (natives == null) {
|
if (natives == null) {
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flav, natives);
|
getFlavorToNative().put(flav, natives);
|
||||||
} else if (natives.contains(nat)) {
|
} else if (natives.contains(nat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1071,7 +1112,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorToNative.remove(flav);
|
getFlavorToNative().remove(flav);
|
||||||
for (int i = 0; i < natives.length; i++) {
|
for (int i = 0; i < natives.length; i++) {
|
||||||
addUnencodedNativeForFlavor(flav, natives[i]);
|
addUnencodedNativeForFlavor(flav, natives[i]);
|
||||||
}
|
}
|
||||||
@ -1105,10 +1146,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
List flavors = (List)nativeToFlavor.get(nat);
|
List flavors = (List)getNativeToFlavor().get(nat);
|
||||||
if (flavors == null) {
|
if (flavors == null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(nat, flavors);
|
getNativeToFlavor().put(nat, flavors);
|
||||||
} else if (flavors.contains(flav)) {
|
} else if (flavors.contains(flav)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1150,7 +1191,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
nativeToFlavor.remove(nat);
|
getNativeToFlavor().remove(nat);
|
||||||
for (int i = 0; i < flavors.length; i++) {
|
for (int i = 0; i < flavors.length; i++) {
|
||||||
addFlavorForUnencodedNative(nat, flavors[i]);
|
addFlavorForUnencodedNative(nat, flavors[i]);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -110,7 +110,11 @@ public class DropTarget implements DropTargetListener, Serializable {
|
|||||||
setActive(act);
|
setActive(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fm != null) flavorMap = fm;
|
if (fm != null) {
|
||||||
|
flavorMap = fm;
|
||||||
|
} else {
|
||||||
|
flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -850,5 +854,5 @@ public class DropTarget implements DropTargetListener, Serializable {
|
|||||||
* The FlavorMap
|
* The FlavorMap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
private transient FlavorMap flavorMap;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user