8047336: Read flavormap.properties as resource

Reviewed-by: anthony, serb, alanb, mduigou
This commit is contained in:
Petr Pchelko 2014-07-16 16:02:51 +04:00
parent 08c190cdd6
commit 78d9ad5339
8 changed files with 63 additions and 289 deletions
jdk
make
src
macosx/classes/sun/awt/datatransfer
share/classes/java/awt
solaris/classes/sun/awt/datatransfer
windows/classes/sun/awt/datatransfer

@ -122,7 +122,7 @@ COPY_FILES += $(PSFONTPROPFILE_TARGET_FILES)
##########################################################################################
#
# Copy flavormap.properties, cursor.properties and cursors gif files to LIBDIR
# Copy cursor.properties and cursors gif files to LIBDIR
#
ifneq ($(OPENJDK_TARGET_OS), macosx)
OPENJDK_TARGET_OS_LIB_SRC = $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/lib
@ -130,11 +130,6 @@ else
OPENJDK_TARGET_OS_LIB_SRC = $(JDK_TOPDIR)/src/macosx/lib
endif
$(LIBDIR)/flavormap.properties: $(OPENJDK_TARGET_OS_LIB_SRC)/flavormap.properties
$(call install-file)
COPY_FILES += $(LIBDIR)/flavormap.properties
CURSORS_DEST_DIR = $(LIBDIR)/images/cursors
CURSORS_OPENJDK_TARGET_OS_LIB_SRC = $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/lib/images/cursors

@ -163,6 +163,19 @@ $(foreach R, $(JAVAX_SOUND_RULES), $(eval $(call addto_meta-inf_services, $R)))
################################################################################
ifneq ($(OPENJDK_TARGET_OS), macosx)
OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes/sun/awt/datatransfer/flavormap.properties
else
OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/macosx/classes/sun/awt/datatransfer/flavormap.properties
endif
$(JDK_OUTPUTDIR)/classes/sun/awt/datatransfer/flavormap.properties: $(OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES)
$(install-file)
COPY_EXTRA += $(JDK_OUTPUTDIR)/classes/sun/awt/datatransfer/flavormap.properties
################################################################################
CLEAN_FILES := $(wildcard \
$(JDK_TOPDIR)/src/share/classes/com/sun/imageio/plugins/common/*.properties \
$(JDK_TOPDIR)/src/share/classes/com/sun/java/util/jar/pack/*.properties \

@ -176,7 +176,6 @@ FULL_JRE_LIB_FILES := \
ext/dnsns.jar \
ext/nashorn.jar \
ext/zipfs.jar \
flavormap.properties \
fontconfig.RedHat.5.bfc \
fontconfig.RedHat.5.properties.src \
fontconfig.RedHat.6.bfc \

@ -2,19 +2,12 @@
# This properties file is used to initialize the default
# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
# default mappings between common Mac OS X selection atoms and platform-independent
# MIME type strings, which will be converted into
# MIME type strings, which will be converted into
# java.awt.datatransfer.DataFlavors.
#
# These default mappings may be augmented by specifying the
#
# AWT.DnD.flavorMapFileURL
#
# property in the appropriate awt.properties file. The specified properties URL
# will be loaded into the SystemFlavorMap.
#
# The standard format is:
#
# <native>=<MIME type>
# <native>=<MIME type>,<MIME type>, ...
#
# <native> should be a string identifier that the native platform will
# recognize as a valid data format. <MIME type> should specify both a MIME
@ -23,9 +16,9 @@
# where each parameter to the MIME type is separated by a ';'.
#
# Because SystemFlavorMap implements FlavorTable, developers are free to
# duplicate both native keys and DataFlavor values. If a mapping contains a
# duplicate key or value, earlier mappings which included this key or value
# will be preferred.
# duplicate DataFlavor values and set multiple values for a single native by
# separating them with ",". If a mapping contains a duplicate key or value,
# earlier mappings which included this key or value will be preferred.
#
# Mappings whose values specify DataFlavors with primary MIME types of
# "text", and which support the charset parameter, should specify the exact
@ -79,5 +72,5 @@ JFIF=image/x-java-image;class=java.awt.Image
TIFF=image/x-java-image;class=java.awt.Image
RICH_TEXT=text/rtf
HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
URL=application/x-java-url;class=java.net.URL
URL=text/uri-list;eoln="\r\n";terminators=1
URL=application/x-java-url;class=java.net.URL,\
text/uri-list;eoln="\r\n";terminators=1

@ -1241,10 +1241,9 @@ public abstract class Toolkit {
* clipboard enables data transfer between Java programs and native
* applications which use native clipboard facilities.
* <p>
* In addition to any and all formats specified in the flavormap.properties
* file, or other file specified by the <code>AWT.DnD.flavorMapFileURL
* </code> Toolkit property, text returned by the system Clipboard's <code>
* getTransferData()</code> method is available in the following flavors:
* In addition to any and all default formats text returned by the system
* Clipboard's <code>getTransferData()</code> method is available in the
* following flavors:
* <ul>
* <li>DataFlavor.stringFlavor</li>
* <li>DataFlavor.plainTextFlavor (<b>deprecated</b>)</li>

@ -27,6 +27,8 @@ package java.awt.datatransfer;
import java.awt.Toolkit;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.io.BufferedReader;
@ -38,6 +40,7 @@ import java.net.URL;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -45,6 +48,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import sun.awt.AppContext;
@ -210,193 +214,48 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Initializes a SystemFlavorMap by reading flavormap.properties and
* AWT.DnD.flavorMapFileURL.
* Initializes a SystemFlavorMap by reading flavormap.properties
* For thread-safety must be called under lock on this.
*/
private void initSystemFlavorMap() {
if (isMapInitialized) {
return;
}
isMapInitialized = true;
BufferedReader flavormapDotProperties =
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<BufferedReader>() {
public BufferedReader run() {
String fileName =
System.getProperty("java.home") +
File.separator +
"lib" +
File.separator +
"flavormap.properties";
try {
return new BufferedReader
(new InputStreamReader
(new File(fileName).toURI().toURL().openStream(), "ISO-8859-1"));
} catch (MalformedURLException e) {
System.err.println("MalformedURLException:" + e + " while loading default flavormap.properties file:" + fileName);
} catch (IOException e) {
System.err.println("IOException:" + e + " while loading default flavormap.properties file:" + fileName);
}
return null;
}
});
String url =
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<String>() {
public String run() {
return Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
}
});
if (flavormapDotProperties != null) {
try {
parseAndStoreReader(flavormapDotProperties);
} catch (IOException e) {
System.err.println("IOException:" + e + " while parsing default flavormap.properties file");
}
InputStream is = SystemFlavorMap.class.getResourceAsStream("/sun/awt/datatransfer/flavormap.properties");
if (is == null) {
throw new InternalError("Default flavor mapping not found");
}
BufferedReader flavormapURL = null;
if (url != null) {
try {
flavormapURL = new BufferedReader(new InputStreamReader(new URL(url).openStream(), "ISO-8859-1"));
} catch (MalformedURLException e) {
System.err.println("MalformedURLException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
} catch (IOException e) {
System.err.println("IOException:" + e + " while reading AWT.DnD.flavorMapFileURL:" + url);
} catch (SecurityException e) {
// ignored
}
}
if (flavormapURL != null) {
try {
parseAndStoreReader(flavormapURL);
} catch (IOException e) {
System.err.println("IOException:" + e + " while parsing AWT.DnD.flavorMapFileURL");
}
}
}
/**
* Copied code from java.util.Properties. Parsing the data ourselves is the
* only way to handle duplicate keys and values.
*/
private void parseAndStoreReader(BufferedReader in) throws IOException {
while (true) {
// Get next line
String line = in.readLine();
if (line == null) {
return;
}
if (line.length() > 0) {
// Continue lines that end in slashes if they are not comments
char firstChar = line.charAt(0);
if (firstChar != '#' && firstChar != '!') {
while (continueLine(line)) {
String nextLine = in.readLine();
if (nextLine == null) {
nextLine = "";
}
String loppedLine =
line.substring(0, line.length() - 1);
// Advance beyond whitespace on new line
int startIndex = 0;
for(; startIndex < nextLine.length(); startIndex++) {
if (whiteSpaceChars.
indexOf(nextLine.charAt(startIndex)) == -1)
{
break;
}
}
nextLine = nextLine.substring(startIndex,
nextLine.length());
line = loppedLine+nextLine;
}
// Find start of key
int len = line.length();
int keyStart = 0;
for(; keyStart < len; keyStart++) {
if(whiteSpaceChars.
indexOf(line.charAt(keyStart)) == -1) {
break;
}
}
// Blank lines are ignored
if (keyStart == len) {
continue;
}
// Find separation between key and value
int separatorIndex = keyStart;
for(; separatorIndex < len; separatorIndex++) {
char currentChar = line.charAt(separatorIndex);
if (currentChar == '\\') {
separatorIndex++;
} else if (keyValueSeparators.
indexOf(currentChar) != -1) {
break;
}
}
// Skip over whitespace after key if any
int valueIndex = separatorIndex;
for (; valueIndex < len; valueIndex++) {
if (whiteSpaceChars.
indexOf(line.charAt(valueIndex)) == -1) {
break;
}
}
// Skip over one non whitespace key value separators if any
if (valueIndex < len) {
if (strictKeyValueSeparators.
indexOf(line.charAt(valueIndex)) != -1) {
valueIndex++;
}
}
// Skip over white space after other separators if any
while (valueIndex < len) {
if (whiteSpaceChars.
indexOf(line.charAt(valueIndex)) == -1) {
break;
}
valueIndex++;
}
String key = line.substring(keyStart, separatorIndex);
String value = (separatorIndex < len)
? line.substring(valueIndex, len)
: "";
// Convert then store key and value
key = loadConvert(key);
value = loadConvert(value);
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("#") || line.isEmpty()) continue;
while (line.endsWith("\\")) {
line = line.substring(0, line.length() - 1) + reader.readLine().trim();
}
int delimiterPosition = line.indexOf('=');
String key = line.substring(0, delimiterPosition).replace("\\ ", " ");
String[] values = line.substring(delimiterPosition + 1, line.length()).split(",");
for (String value : values) {
try {
MimeType mime = new MimeType(value);
if ("text".equals(mime.getPrimaryType())) {
String charset = mime.getParameter("charset");
if (DataTransferer.doesSubtypeSupportCharset
(mime.getSubType(), charset))
if (DataTransferer.doesSubtypeSupportCharset(mime.getSubType(), charset))
{
// We need to store the charset and eoln
// parameters, if any, so that the
// DataTransferer will have this information
// for conversion into the native format.
DataTransferer transferer =
DataTransferer.getInstance();
DataTransferer transferer = DataTransferer.getInstance();
if (transferer != null) {
transferer.registerTextFlavorProperties
(key, charset,
mime.getParameter("eoln"),
mime.getParameter("terminators"));
transferer.registerTextFlavorProperties(key, charset,
mime.getParameter("eoln"),
mime.getParameter("terminators"));
}
}
@ -441,80 +300,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
}
}
} catch (IOException e) {
throw new InternalError("Error reading default flavor mapping", e);
}
}
/**
* Copied from java.util.Properties.
*/
private boolean continueLine (String line) {
int slashCount = 0;
int index = line.length() - 1;
while((index >= 0) && (line.charAt(index--) == '\\')) {
slashCount++;
}
return (slashCount % 2 == 1);
}
/**
* Copied from java.util.Properties.
*/
private String loadConvert(String theString) {
char aChar;
int len = theString.length();
StringBuilder outBuffer = new StringBuilder(len);
for (int x = 0; x < len; ) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// Read the xxxx
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
value = (value << 4) + aChar - '0';
break;
}
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f': {
value = (value << 4) + 10 + aChar - 'a';
break;
}
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F': {
value = (value << 4) + 10 + aChar - 'A';
break;
}
default: {
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding.");
}
}
}
outBuffer.append((char)value);
} else {
if (aChar == 't') {
aChar = '\t';
} else if (aChar == 'r') {
aChar = '\r';
} else if (aChar == 'n') {
aChar = '\n';
} else if (aChar == 'f') {
aChar = '\f';
}
outBuffer.append(aChar);
}
} else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}
/**
* Stores the listed object under the specified hash key in map. Unlike a
* standard map, the listed object will not replace any object already at

@ -5,16 +5,9 @@
# MIME type strings, which will be converted into
# java.awt.datatransfer.DataFlavors.
#
# These default mappings may be augmented by specifying the
#
# AWT.DnD.flavorMapFileURL
#
# property in the appropriate awt.properties file. The specified properties URL
# will be loaded into the SystemFlavorMap.
#
# The standard format is:
#
# <native>=<MIME type>
# <native>=<MIME type>,<MIME type>, ...
#
# <native> should be a string identifier that the native platform will
# recognize as a valid data format. <MIME type> should specify both a MIME
@ -23,9 +16,9 @@
# where each parameter to the MIME type is separated by a ';'.
#
# Because SystemFlavorMap implements FlavorTable, developers are free to
# duplicate both native keys and DataFlavor values. If a mapping contains a
# duplicate key or value, earlier mappings which included this key or value
# will be preferred.
# duplicate DataFlavor values and set multiple values for a single native by
# separating them with ",". If a mapping contains a duplicate key or value,
# earlier mappings which included this key or value will be preferred.
#
# Mappings whose values specify DataFlavors with primary MIME types of
# "text", and which support the charset parameter, should specify the exact

@ -5,16 +5,9 @@
# independent MIME type strings, which will be converted into
# java.awt.datatransfer.DataFlavors.
#
# These default mappings may be augmented by specifying the
#
# AWT.DnD.flavorMapFileURL
#
# property in the appropriate awt.properties file. The specified properties URL
# will be loaded into the SystemFlavorMap.
#
# The standard format is:
#
# <native>=<MIME type>
# <native>=<MIME type>,<MIME type>, ...
#
# <native> should be a string identifier that the native platform will
# recognize as a valid data format. <MIME type> should specify both a MIME
@ -23,10 +16,9 @@
# where each parameter to the MIME type is separated by a ';'.
#
# Because SystemFlavorMap implements FlavorTable, developers are free to
# duplicate both native keys and DataFlavor values. If a mapping contains a
# duplicate key or value, earlier mappings which included this key or value
# will be preferred.
#
# duplicate DataFlavor values and set multiple values for a single native by
# separating them with ",". If a mapping contains a duplicate key or value,
# earlier mappings which included this key or value will be preferred.#
# Mappings whose values specify DataFlavors with primary MIME types of
# "text", and which support the charset parameter, should specify the exact
# format in which the native platform expects the data. The "charset"
@ -70,8 +62,8 @@ DIB=image/x-java-image;class=java.awt.Image
ENHMETAFILE=image/x-java-image;class=java.awt.Image
METAFILEPICT=image/x-java-image;class=java.awt.Image
LOCALE=application/x-java-text-encoding;class="[B"
UniformResourceLocator=application/x-java-url;class=java.net.URL
UniformResourceLocator=text/uri-list;eoln="\r\n";terminators=1
UniformResourceLocator=text/plain;eoln="\r\n";terminators=1
UniformResourceLocator=application/x-java-url;class=java.net.URL,\
text/uri-list;eoln="\r\n";terminators=1,\
text/plain;eoln="\r\n";terminators=1
FileGroupDescriptorW=application/x-java-file-list;class=java.util.List
FileGroupDescriptor=application/x-java-file-list;class=java.util.List