diff --git a/jre_emul/Classes/com/google/j2objc/util/PropertiesXmlLoader.java b/jre_emul/Classes/com/google/j2objc/util/PropertiesXmlLoader.java
deleted file mode 100644
index 1839cc0cf5..0000000000
--- a/jre_emul/Classes/com/google/j2objc/util/PropertiesXmlLoader.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.j2objc.util;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.InvalidPropertiesFormatException;
-import java.util.Properties;
-
-/**
- * Dynamically loaded implementation for Properties.loadFromXML(). Public so that users can add an
- * explicit dependency to force load this class.
- */
-public class PropertiesXmlLoader implements XmlLoader {
-
- public void load(final Properties p, InputStream in) throws IOException,
- InvalidPropertiesFormatException {
- if (in == null) {
- throw new NullPointerException("in == null");
- }
-
- try {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- reader.setContentHandler(new DefaultHandler() {
- private String key;
-
- @Override
- public void startElement(String uri, String localName,
- String qName, Attributes attributes) throws SAXException {
- key = null;
- if (qName.equals("entry")) {
- key = attributes.getValue("key");
- }
- }
-
- @Override
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- if (key != null) {
- String value = new String(ch, start, length);
- p.put(key, value);
- key = null;
- }
- }
- });
- reader.parse(new InputSource(in));
- } catch (SAXException e) {
- throw new InvalidPropertiesFormatException(e);
- }
- }
-}
diff --git a/jre_emul/android/platform/libcore/luni/src/main/java/java/nio/NioUtils.java b/jre_emul/android/platform/libcore/luni/src/main/java/java/nio/NioUtils.java
index 9ab5b0bf4e..7dbb8ccfd0 100644
--- a/jre_emul/android/platform/libcore/luni/src/main/java/java/nio/NioUtils.java
+++ b/jre_emul/android/platform/libcore/luni/src/main/java/java/nio/NioUtils.java
@@ -16,24 +16,15 @@
package java.nio;
-import dalvik.annotation.compat.UnsupportedAppUsage;
+import static libcore.io.OsConstants.O_ACCMODE;
+import static libcore.io.OsConstants.O_RDONLY;
+import static libcore.io.OsConstants.O_WRONLY;
-import com.google.j2objc.LibraryNotLinkedError;
-import java.io.Closeable;
+import dalvik.annotation.compat.UnsupportedAppUsage;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.nio.channels.FileChannel;
-import java.util.Set;
-
-import sun.misc.Cleaner;
-import sun.nio.ch.DirectBuffer;
import sun.nio.ch.FileChannelImpl;
-import static libcore.io.OsConstants.O_ACCMODE;
-import static libcore.io.OsConstants.O_APPEND;
-import static libcore.io.OsConstants.O_RDONLY;
-import static libcore.io.OsConstants.O_WRONLY;
-
/**
* @hide internal use only
*/
@@ -64,43 +55,12 @@ public static FileDescriptor getFD(FileChannel fc) {
}
*/
- /**
- * Helps bridge between io and nio.
- */
- public static FileChannel newFileChannel(Closeable ioObject, FileDescriptor fd, int mode) {
- ChannelFactory factory = ChannelFactory.INSTANCE;
- if (factory == null) {
- throw new LibraryNotLinkedError("Channel support", "jre_channels",
- "JavaNioChannelFactoryImpl");
- }
- return factory.newFileChannel(ioObject, fd, mode);
- }
-
- public static FileChannel newFileChannelSafe(Object stream, FileDescriptor fd, int mode) {
- ChannelFactory factory = ChannelFactory.INSTANCE;
- if (factory != null) {
- return factory.newFileChannel(stream, fd, mode);
- } else {
- return null;
- }
+ public FileChannel newFileChannel(Object ioObject, FileDescriptor fd, int mode) {
+ boolean readable = (mode & O_ACCMODE) != O_WRONLY;
+ boolean writable = (mode & O_ACCMODE) != O_RDONLY;
+ return FileChannelImpl.open(fd, null, readable, writable, ioObject);
}
- static interface ChannelFactory {
- FileChannel newFileChannel(Object stream, FileDescriptor fd, int mode);
-
- static final ChannelFactory INSTANCE = getChannelFactory();
- }
-
- // Native implementation avoids the use of Class.forName(). This code might end up invoked from
- // within the internals of Class.forName(), and re-invoking it causes deadlock.
- private static native ChannelFactory getChannelFactory() /*-[
- Class cls = NSClassFromString(@"JavaNioChannelFactoryImpl");
- if (cls) {
- return AUTORELEASE([[cls alloc] init]);
- }
- return nil;
- ]-*/;
-
/**
* Exposes the array backing a non-direct ByteBuffer, even if the ByteBuffer is read-only.
* Normally, attempting to access the array backing a read-only buffer throws.
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/nio/ChannelFactoryImpl.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/nio/ChannelFactoryImpl.java
deleted file mode 100644
index 31165ebd0a..0000000000
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/nio/ChannelFactoryImpl.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.nio;
-
-import com.google.j2objc.annotations.ReflectionSupport;
-import java.io.FileDescriptor;
-import java.nio.channels.FileChannel;
-import sun.nio.ch.FileChannelImpl;
-
-import static com.google.j2objc.annotations.ReflectionSupport.Level.FULL;
-import static libcore.io.OsConstants.*;
-
-/**
- * J2ObjC split of NioUtils to move method to jre_channels subset library.
- * This class is only referenced by reflection.
- */
-@SuppressWarnings("unused")
-@ReflectionSupport(FULL)
-class ChannelFactoryImpl implements NioUtils.ChannelFactory {
-
- public FileChannel newFileChannel(Object ioObject, FileDescriptor fd, int mode) {
- boolean readable = (mode & O_ACCMODE) != O_WRONLY;
- boolean writable = (mode & O_ACCMODE) != O_RDONLY;
- boolean append = (mode & O_APPEND) != 0;
-
- return new FileChannelImpl(fd, null, readable, writable, append, ioObject);
- }
-}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/Properties.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/Properties.java
index 2f875ba7c7..18081284a2 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/Properties.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/Properties.java
@@ -26,12 +26,8 @@
package java.util;
-import com.google.j2objc.LibraryNotLinkedError;
-import com.google.j2objc.util.XmlLoader;
import java.io.BufferedWriter;
import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -39,9 +35,6 @@
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
-import java.nio.charset.Charset;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
// Android-removed: Dead native2ascii links.
// These links are also gone in OpenJDK 9.
@@ -910,21 +903,16 @@ private void store0(BufferedWriter bw, String comments, boolean escUnicode)
*/
public synchronized void loadFromXML(InputStream in)
throws IOException, InvalidPropertiesFormatException {
- XmlLoader loader = getXmlLoader();
- if (loader == null) {
- throw new LibraryNotLinkedError(
- "XML support", "jre_xml", "ComGoogleJ2objcUtilPropertiesXmlLoader");
- }
- loader.load(this, in);
- }
-
- private static XmlLoader getXmlLoader() {
- try {
- Class> loaderClass = Class.forName("com.google.j2objc.util.PropertiesXmlLoader");
- return (XmlLoader) loaderClass.newInstance();
- } catch (Exception e) {
- return null;
- }
+ // Android-changed: Keep OpenJDK7u40's XmlUtils.
+ // XmlSupport's system property based XmlPropertiesProvider
+ // selection does not make sense on Android and has too many
+ // dependencies on classes that are not available on Android.
+ //
+ // Objects.requireNonNull(in);
+ // PropertiesDefaultHandler handler = new PropertiesDefaultHandler();
+ // handler.load(this, in);
+ XMLUtils.load(this, Objects.requireNonNull(in));
+ in.close();
}
/**
@@ -994,72 +982,23 @@ public void storeToXML(OutputStream os, String comment)
*/
public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException {
- if (os == null) {
- throw new NullPointerException("os == null");
- } else if (encoding == null) {
- throw new NullPointerException("encoding == null");
- }
-
+ // Android-changed: Keep OpenJDK7u40's XmlUtils.
+ // XmlSupport's system property based XmlPropertiesProvider
+ // selection does not make sense on Android and has too many
+ // dependencies on classes that are not available on Android.
/*
- * We can write to XML file using encoding parameter but note that some
- * aliases for encodings are not supported by the XML parser. Thus we
- * have to know canonical name for encoding used to store data in XML
- * since the XML parser must recognize encoding name used to store data.
- */
+ Objects.requireNonNull(os);
+ Objects.requireNonNull(encoding);
- String encodingCanonicalName;
try {
- encodingCanonicalName = Charset.forName(encoding).name();
- } catch (IllegalCharsetNameException e) {
- System.out.println("Warning: encoding name " + encoding
- + " is illegal, using UTF-8 as default encoding");
- encodingCanonicalName = "UTF-8";
- } catch (UnsupportedCharsetException e) {
- System.out.println("Warning: encoding " + encoding
- + " is not supported, using UTF-8 as default encoding");
- encodingCanonicalName = "UTF-8";
- }
-
- PrintStream printStream = new PrintStream(os, false,
- encodingCanonicalName);
-
- printStream.print("");
-
- printStream.print("");
-
- printStream.println("");
-
- if (comment != null) {
- printStream.print("");
- printStream.print(substitutePredefinedEntries(comment));
- printStream.println("");
+ Charset charset = Charset.forName(encoding);
+ storeToXML(os, comment, charset);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+ throw new UnsupportedEncodingException(encoding);
}
-
- for (Map.Entry");
- printStream.flush();
- }
-
- private String substitutePredefinedEntries(String s) {
- // substitution for predefined character entities to use them safely in XML.
- s = s.replaceAll("&", "&");
- s = s.replaceAll("<", "<");
- s = s.replaceAll(">", ">");
- s = s.replaceAll("'", "'");
- s = s.replaceAll("\"", """);
- return s;
+ */
+ XMLUtils.save(this, Objects.requireNonNull(os), comment,
+ Objects.requireNonNull(encoding));
}
/**
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/XMLUtils.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/XMLUtils.java
new file mode 100644
index 0000000000..8f061e5b7f
--- /dev/null
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/util/XMLUtils.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util;
+
+import java.io.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+import org.w3c.dom.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+
+/**
+ * A class used to aid in Properties load and save in XML. Keeping this
+ * code outside of Properties helps reduce the number of classes loaded
+ * when Properties is loaded.
+ *
+ * @author Michael McCloskey
+ * @since 1.3
+ */
+class XMLUtils {
+
+ // XML loading and saving methods for Properties
+
+ // The required DTD URI for exported properties
+ private static final String PROPS_DTD_URI =
+ "http://java.sun.com/dtd/properties.dtd";
+
+ private static final String PROPS_DTD =
+ "" +
+ "" +
+ ""+
+ "" +
+ "" +
+ "" +
+ "";
+
+ /**
+ * Version number for the format of exported properties files.
+ */
+ private static final String EXTERNAL_XML_VERSION = "1.0";
+
+ static void load(Properties props, InputStream in)
+ throws IOException, InvalidPropertiesFormatException
+ {
+ Document doc = null;
+ try {
+ doc = getLoadingDoc(in);
+ } catch (SAXException saxe) {
+ throw new InvalidPropertiesFormatException(saxe);
+ }
+ Element propertiesElement = doc.getDocumentElement();
+ String xmlVersion = propertiesElement.getAttribute("version");
+ if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0)
+ throw new InvalidPropertiesFormatException(
+ "Exported Properties file format version " + xmlVersion +
+ " is not supported. This java installation can read" +
+ " versions " + EXTERNAL_XML_VERSION + " or older. You" +
+ " may need to install a newer version of JDK.");
+ importProperties(props, propertiesElement);
+ }
+
+ static Document getLoadingDoc(InputStream in)
+ throws SAXException, IOException
+ {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setIgnoringElementContentWhitespace(true);
+ // Android-changed: We don't currently have a validating document builder.
+ // Revert this if the situation changes.
+ //
+ // dbf.setValidating(true);
+ dbf.setCoalescing(true);
+ dbf.setIgnoringComments(true);
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ db.setEntityResolver(new Resolver());
+ db.setErrorHandler(new EH());
+ InputSource is = new InputSource(in);
+ return db.parse(is);
+ } catch (ParserConfigurationException x) {
+ throw new Error(x);
+ }
+ }
+
+ static void importProperties(Properties props, Element propertiesElement) {
+ NodeList entries = propertiesElement.getChildNodes();
+ int numEntries = entries.getLength();
+ int start = numEntries > 0 &&
+ entries.item(0).getNodeName().equals("comment") ? 1 : 0;
+ for (int i=start; i