commits@javamail.java.net

[javamail~mercurial:758] correct javadoc errors (but not warnings) when using JDK 1.8

From: <shannon_at_java.net>
Date: Wed, 2 Sep 2015 23:34:21 +0000

Project: javamail
Repository: mercurial
Revision: 758
Author: shannon
Date: 2015-09-02 23:34:00 UTC
Link:

Log Message:
------------
First attempt at making a version of JavaMail for Android.
Includes a custom version of JAF that should work on Android.
IMAP should support a mail.imap.auth.mechanisms property like SMTP - bug 6964
setting mail.<protocol>.auth.mechanisms should override
mail.<protocol>.auth.<mechanism>.disable - bug 6965
add support for OAuth 2.0 without SASL - bug 6966
The mailapi jar needs to include the authenticators so protocol providers
can use them.
Make tests time insensitive
Oops, connect Android modules into the build.
add FindBugs exclude file for JAF
exclude some more classes for Android
move javax.activation dependency to mail subproject so that
android-mail doesn't depend on it
correct javadoc errors (but not warnings) when using JDK 1.8


Revisions:
----------
750
751
752
753
754
755
756
757
758


Modified Paths:
---------------
mail/src/main/java/com/sun/mail/handlers/image_gif.java
mail/src/main/java/com/sun/mail/handlers/image_jpeg.java
mail/src/main/java/com/sun/mail/handlers/message_rfc822.java
mail/src/main/java/com/sun/mail/handlers/multipart_mixed.java
mail/src/main/java/com/sun/mail/handlers/text_html.java
mail/src/main/java/com/sun/mail/handlers/text_plain.java
mail/src/main/java/com/sun/mail/handlers/text_xml.java
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/imap/IMAPStore.java
mail/src/main/java/com/sun/mail/imap/package.html
mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java
mail/src/main/java/com/sun/mail/smtp/package.html
mailapi/pom.xml
mail/src/test/java/javax/mail/internet/MailDateFormatTest.java
android/pom.xml
pom.xml
android/mail/pom.xml
mail/pom.xml
android/activation/src/main/java/com/sun/activation/registries/MailcapFile.java
android/activation/src/main/java/com/sun/activation/registries/MailcapTokenizer.java
android/activation/src/main/java/javax/activation/DataContentHandler.java
android/activation/src/main/java/javax/activation/DataHandler.java
android/activation/src/main/java/javax/activation/MailcapCommandMap.java
android/activation/src/main/java/javax/activation/MimetypesFileTypeMap.java


Added Paths:
------------
android/activation/pom.xml
android/activation/src/main/java/com/sun/activation/registries/LogSupport.java
android/activation/src/main/java/com/sun/activation/registries/MailcapFile.java
android/activation/src/main/java/com/sun/activation/registries/MailcapParseException.java
android/activation/src/main/java/com/sun/activation/registries/MailcapTokenizer.java
android/activation/src/main/java/com/sun/activation/registries/MimeTypeEntry.java
android/activation/src/main/java/com/sun/activation/registries/MimeTypeFile.java
android/activation/src/main/java/javax/activation/ActivationDataFlavor.java
android/activation/src/main/java/javax/activation/CommandInfo.java
android/activation/src/main/java/javax/activation/CommandMap.java
android/activation/src/main/java/javax/activation/CommandObject.java
android/activation/src/main/java/javax/activation/DataContentHandler.java
android/activation/src/main/java/javax/activation/DataContentHandlerFactory.java
android/activation/src/main/java/javax/activation/DataHandler.java
android/activation/src/main/java/javax/activation/DataSource.java
android/activation/src/main/java/javax/activation/FileDataSource.java
android/activation/src/main/java/javax/activation/FileTypeMap.java
android/activation/src/main/java/javax/activation/MailcapCommandMap.java
android/activation/src/main/java/javax/activation/MimeType.java
android/activation/src/main/java/javax/activation/MimeTypeParameterList.java
android/activation/src/main/java/javax/activation/MimeTypeParseException.java
android/activation/src/main/java/javax/activation/MimetypesFileTypeMap.java
android/activation/src/main/java/javax/activation/SecuritySupport.java
android/activation/src/main/java/javax/activation/URLDataSource.java
android/activation/src/main/java/javax/activation/UnsupportedDataTypeException.java
android/activation/src/main/java/javax/activation/package.html
android/activation/src/main/resources/META-INF/mailcap.default
android/activation/src/main/resources/META-INF/mimetypes.default
android/mail/pom.xml
android/mail/src/main/java/com/sun/mail/handlers/handler_base.java
android/pom.xml
mail/src/main/java/com/sun/mail/handlers/handler_base.java
android/activation/exclude.xml


Diffs:
------
diff -r b074be087fab -r 80a182f23183 android/activation/pom.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/pom.xml Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>android</artifactId>
+ <version>1.5.5-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>android-activation</artifactId>
+ <packaging>jar</packaging>
+ <name>JavaBeans Activation Framework fork for Android</name>
+
+ <!--
+ This is a fork of the JavaBeans Activation Framework (JAF) that
+ is sufficient for use by JavaMail when running on Android.
+ Android is not Java Compatible, and is missing the java.awt.datatransfer
+ classes. This fork of JAF breaks the dependency on the
+ java.awt.datatransfer classes and thus isn't compatible with
+ the JAF specification. It should not be used by anything other
+ than this Android-specific version of JavaMail.
+ -->
+
+ <properties>
+ <activation.spec.version>1.2</activation.spec.version>
+ <activation.extensionName>
+ javax.activation
+ </activation.extensionName>
+ <activation.specificationTitle>
+ JavaBeans(TM) Activation Framework Specification
+ </activation.specificationTitle>
+ <activation.implementationTitle>
+ javax.activation
+ </activation.implementationTitle>
+ <activation.packages.export>
+ javax.activation.*; version=${activation.spec.version},
+ com.sun.activation.*; version=${activation.osgiversion}
+ </activation.packages.export>
+ <findbugs.skip>
+ false
+ </findbugs.skip>
+ <findbugs.exclude>
+ ${project.basedir}/exclude.xml
+ </findbugs.exclude>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <plugins>
+ <!--
+ Configure compiler plugin to print lint warnings.
+ -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ <fork>true</fork>
+ <!--
+ ignore some of the errors that are
+ too hard to fix for now
+ -->
+ <!--
+ <compilerArguments>
+ <Xlint:all/>
+ <Xlint:-rawtypes/>
+ <Xlint:-unchecked/>
+ <Xlint:-finally/>
+ </compilerArguments>
+ <showWarnings>true</showWarnings>
+ -->
+ </configuration>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!--
+ Configure test plugin to find *TestSuite classes.
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Test.java</include>
+ <include>**/*TestSuite.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>
+ ${activation.bundle.symbolicName}
+ </Bundle-SymbolicName>
+ <Export-Package>
+ ${activation.packages.export}
+ </Export-Package>
+ <Import-Package>
+ ${activation.packages.import}
+ </Import-Package>
+ <Private-Package>
+ ${activation.packages.private}
+ </Private-Package>
+ <DynamicImport-Package>
+ *
+ </DynamicImport-Package>
+ </instructions>
+ </configuration>
+ <!--
+ Since we don't change the packaging type to bundle, we
+ need to configure the plugin to execute the manifest goal
+ during the process-classes phase of the build life cycle.
+ -->
+ <executions>
+ <execution>
+ <id>osgi-manifest</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!--
+ Since we don't want a qualifier like b05 or SNAPSHOT to
+ appear in the OSGi package version attribute, we use
+ the following plugin to populate a project property
+ with an OSGi version that is equivalent to the maven
+ version without the qualifier.
+ -->
+ <plugin>
+ <groupId>org.glassfish.hk2</groupId>
+ <artifactId>osgiversion-maven-plugin</artifactId>
+ <version>${hk2.plugin.version}</version>
+ <configuration>
+ <dropVersionComponent>qualifier</dropVersionComponent>
+ <versionPropertyName>activation.osgiversion</versionPropertyName>
+ </configuration>
+ <executions>
+ <execution>
+ <id>compute-osgi-version</id>
+ <goals>
+ <goal>compute-osgi-version</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project>

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/LogSupport.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/LogSupport.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+import java.io.*;
+import java.util.logging.*;
+
+/**
+ * Logging related methods.
+ */
+public class LogSupport {
+ private static boolean debug = false;
+ private static Logger logger;
+ private static final Level level = Level.FINE;
+
+ static {
+ try {
+ debug = Boolean.getBoolean("javax.activation.debug");
+ } catch (Throwable t) {
+ // ignore any errors
+ }
+ logger = Logger.getLogger("javax.activation");
+ }
+
+ /**
+ * Constructor.
+ */
+ private LogSupport() {
+ // private constructor, can't create instances
+ }
+
+ public static void log(String msg) {
+ if (debug)
+ System.out.println(msg);
+ logger.log(level, msg);
+ }
+
+ public static void log(String msg, Throwable t) {
+ if (debug)
+ System.out.println(msg + "; Exception: " + t);
+ logger.log(level, msg, t);
+ }
+
+ public static boolean isLoggable() {
+ return debug || logger.isLoggable(level);
+ }
+}

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/MailcapFile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/MailcapFile.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,578 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+import java.io.*;
+import java.util.*;
+
+public class MailcapFile {
+
+ /**
+ * A Map indexed by MIME type (string) that references
+ * a Map of commands for each type. The comand Map
+ * is indexed by the command name and references a List of
+ * class names (strings) for each command.
+ */
+ private Map type_hash = new HashMap();
+
+ /**
+ * Another Map like above, but for fallback entries.
+ */
+ private Map fallback_hash = new HashMap();
+
+ /**
+ * A Map indexed by MIME type (string) that references
+ * a List of native commands (string) corresponding to the type.
+ */
+ private Map native_commands = new HashMap();
+
+ private static boolean addReverse = false;
+
+ static {
+ try {
+ addReverse = Boolean.getBoolean("javax.activation.addreverse");
+ } catch (Throwable t) {
+ // ignore any errors
+ }
+ }
+
+ /**
+ * The constructor that takes a filename as an argument.
+ *
+ * @param new_fname The file name of the mailcap file.
+ */
+ public MailcapFile(String new_fname) throws IOException {
+ if (LogSupport.isLoggable())
+ LogSupport.log("new MailcapFile: file " + new_fname);
+ FileReader reader = null;
+ try {
+ reader = new FileReader(new_fname);
+ parse(new BufferedReader(reader));
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ex) { }
+ }
+ }
+ }
+
+ /**
+ * The constructor that takes an input stream as an argument.
+ *
+ * @param is the input stream
+ */
+ public MailcapFile(InputStream is) throws IOException {
+ if (LogSupport.isLoggable())
+ LogSupport.log("new MailcapFile: InputStream");
+ parse(new BufferedReader(new InputStreamReader(is, "iso-8859-1")));
+ }
+
+ /**
+ * Mailcap file default constructor.
+ */
+ public MailcapFile() {
+ if (LogSupport.isLoggable())
+ LogSupport.log("new MailcapFile: default");
+ }
+
+ /**
+ * Get the Map of MailcapEntries based on the MIME type.
+ *
+ * <p>
+ * <strong>Semantics:</strong> First check for the literal mime type,
+ * if that fails looks for wildcard <type>/\* and return that. Return the
+ * list of all that hit.
+ */
+ public Map getMailcapList(String mime_type) {
+ Map search_result = null;
+ Map wildcard_result = null;
+
+ // first try the literal
+ search_result = (Map)type_hash.get(mime_type);
+
+ // ok, now try the wildcard
+ int separator = mime_type.indexOf('/');
+ String subtype = mime_type.substring(separator + 1);
+ if (!subtype.equals("*")) {
+ String type = mime_type.substring(0, separator + 1) + "*";
+ wildcard_result = (Map)type_hash.get(type);
+
+ if (wildcard_result != null) { // damn, we have to merge!!!
+ if (search_result != null)
+ search_result =
+ mergeResults(search_result, wildcard_result);
+ else
+ search_result = wildcard_result;
+ }
+ }
+ return search_result;
+ }
+
+ /**
+ * Get the Map of fallback MailcapEntries based on the MIME type.
+ *
+ * <p>
+ * <strong>Semantics:</strong> First check for the literal mime type,
+ * if that fails looks for wildcard <type>/\* and return that. Return the
+ * list of all that hit.
+ */
+ public Map getMailcapFallbackList(String mime_type) {
+ Map search_result = null;
+ Map wildcard_result = null;
+
+ // first try the literal
+ search_result = (Map)fallback_hash.get(mime_type);
+
+ // ok, now try the wildcard
+ int separator = mime_type.indexOf('/');
+ String subtype = mime_type.substring(separator + 1);
+ if (!subtype.equals("*")) {
+ String type = mime_type.substring(0, separator + 1) + "*";
+ wildcard_result = (Map)fallback_hash.get(type);
+
+ if (wildcard_result != null) { // damn, we have to merge!!!
+ if (search_result != null)
+ search_result =
+ mergeResults(search_result, wildcard_result);
+ else
+ search_result = wildcard_result;
+ }
+ }
+ return search_result;
+ }
+
+ /**
+ * Return all the MIME types known to this mailcap file.
+ */
+ public String[] getMimeTypes() {
+ Set types = new HashSet(type_hash.keySet());
+ types.addAll(fallback_hash.keySet());
+ types.addAll(native_commands.keySet());
+ String[] mts = new String[types.size()];
+ mts = (String[])types.toArray(mts);
+ return mts;
+ }
+
+ /**
+ * Return all the native comands for the given MIME type.
+ */
+ public String[] getNativeCommands(String mime_type) {
+ String[] cmds = null;
+ List v =
+ (List)native_commands.get(mime_type.toLowerCase(Locale.ENGLISH));
+ if (v != null) {
+ cmds = new String[v.size()];
+ cmds = (String[])v.toArray(cmds);
+ }
+ return cmds;
+ }
+
+ /**
+ * Merge the first hash into the second.
+ * This merge will only effect the hashtable that is
+ * returned, we don't want to touch the one passed in since
+ * its integrity must be maintained.
+ */
+ private Map mergeResults(Map first, Map second) {
+ Iterator verb_enum = second.keySet().iterator();
+ Map clonedHash = new HashMap(first);
+
+ // iterate through the verbs in the second map
+ while (verb_enum.hasNext()) {
+ String verb = (String)verb_enum.next();
+ List cmdVector = (List)clonedHash.get(verb);
+ if (cmdVector == null) {
+ clonedHash.put(verb, second.get(verb));
+ } else {
+ // merge the two
+ List oldV = (List)second.get(verb);
+ cmdVector = new ArrayList(cmdVector);
+ cmdVector.addAll(oldV);
+ clonedHash.put(verb, cmdVector);
+ }
+ }
+ return clonedHash;
+ }
+
+ /**
+ * appendToMailcap: Append to this Mailcap DB, use the mailcap
+ * format:
+ * Comment == "# <i>comment string</i>
+ * Entry == "mimetype; javabeanclass<nl>
+ *
+ * Example:
+ * # this is a comment
+ * image/gif jaf.viewers.ImageViewer
+ */
+ public void appendToMailcap(String mail_cap) {
+ if (LogSupport.isLoggable())
+ LogSupport.log("appendToMailcap: " + mail_cap);
+ try {
+ parse(new StringReader(mail_cap));
+ } catch (IOException ex) {
+ // can't happen
+ }
+ }
+
+ /**
+ * parse file into a hash table of MC Type Entry Obj
+ */
+ private void parse(Reader reader) throws IOException {
+ BufferedReader buf_reader = new BufferedReader(reader);
+ String line = null;
+ String continued = null;
+
+ while ((line = buf_reader.readLine()) != null) {
+ // LogSupport.log("parsing line: " + line);
+
+ line = line.trim();
+
+ try {
+ if (line.charAt(0) == '#')
+ continue;
+ if (line.charAt(line.length() - 1) == '\\') {
+ if (continued != null)
+ continued += line.substring(0, line.length() - 1);
+ else
+ continued = line.substring(0, line.length() - 1);
+ } else if (continued != null) {
+ // handle the two strings
+ continued = continued + line;
+ // LogSupport.log("parse: " + continued);
+ try {
+ parseLine(continued);
+ } catch (MailcapParseException e) {
+ //e.printStackTrace();
+ }
+ continued = null;
+ }
+ else {
+ // LogSupport.log("parse: " + line);
+ try {
+ parseLine(line);
+ // LogSupport.log("hash.size = " + type_hash.size());
+ } catch (MailcapParseException e) {
+ //e.printStackTrace();
+ }
+ }
+ } catch (StringIndexOutOfBoundsException e) {}
+ }
+ }
+
+ /**
+ * A routine to parse individual entries in a Mailcap file.
+ *
+ * Note that this routine does not handle line continuations.
+ * They should have been handled prior to calling this routine.
+ */
+ protected void parseLine(String mailcapEntry)
+ throws MailcapParseException, IOException {
+ MailcapTokenizer tokenizer = new MailcapTokenizer(mailcapEntry);
+ tokenizer.setIsAutoquoting(false);
+
+ if (LogSupport.isLoggable())
+ LogSupport.log("parse: " + mailcapEntry);
+ // parse the primary type
+ int currentToken = tokenizer.nextToken();
+ if (currentToken != MailcapTokenizer.STRING_TOKEN) {
+ reportParseError(MailcapTokenizer.STRING_TOKEN, currentToken,
+ tokenizer.getCurrentTokenValue());
+ }
+ String primaryType =
+ tokenizer.getCurrentTokenValue().toLowerCase(Locale.ENGLISH);
+ String subType = "*";
+
+ // parse the '/' between primary and sub
+ // if it's not present that's ok, we just don't have a subtype
+ currentToken = tokenizer.nextToken();
+ if ((currentToken != MailcapTokenizer.SLASH_TOKEN) &&
+ (currentToken != MailcapTokenizer.SEMICOLON_TOKEN)) {
+ reportParseError(MailcapTokenizer.SLASH_TOKEN,
+ MailcapTokenizer.SEMICOLON_TOKEN, currentToken,
+ tokenizer.getCurrentTokenValue());
+ }
+
+ // only need to look for a sub type if we got a '/'
+ if (currentToken == MailcapTokenizer.SLASH_TOKEN) {
+ // parse the sub type
+ currentToken = tokenizer.nextToken();
+ if (currentToken != MailcapTokenizer.STRING_TOKEN) {
+ reportParseError(MailcapTokenizer.STRING_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+ subType =
+ tokenizer.getCurrentTokenValue().toLowerCase(Locale.ENGLISH);
+
+ // get the next token to simplify the next step
+ currentToken = tokenizer.nextToken();
+ }
+
+ String mimeType = primaryType + "/" + subType;
+
+ if (LogSupport.isLoggable())
+ LogSupport.log(" Type: " + mimeType);
+
+ // now setup the commands hashtable
+ Map commands = new LinkedHashMap(); // keep commands in order found
+
+ // parse the ';' that separates the type from the parameters
+ if (currentToken != MailcapTokenizer.SEMICOLON_TOKEN) {
+ reportParseError(MailcapTokenizer.SEMICOLON_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+ // eat it
+
+ // parse the required view command
+ tokenizer.setIsAutoquoting(true);
+ currentToken = tokenizer.nextToken();
+ tokenizer.setIsAutoquoting(false);
+ if ((currentToken != MailcapTokenizer.STRING_TOKEN) &&
+ (currentToken != MailcapTokenizer.SEMICOLON_TOKEN)) {
+ reportParseError(MailcapTokenizer.STRING_TOKEN,
+ MailcapTokenizer.SEMICOLON_TOKEN, currentToken,
+ tokenizer.getCurrentTokenValue());
+ }
+
+ if (currentToken == MailcapTokenizer.STRING_TOKEN) {
+ // have a native comand, save the entire mailcap entry
+ //String nativeCommand = tokenizer.getCurrentTokenValue();
+ List v = (List)native_commands.get(mimeType);
+ if (v == null) {
+ v = new ArrayList();
+ v.add(mailcapEntry);
+ native_commands.put(mimeType, v);
+ } else {
+ // XXX - check for duplicates?
+ v.add(mailcapEntry);
+ }
+ }
+
+ // only have to get the next token if the current one isn't a ';'
+ if (currentToken != MailcapTokenizer.SEMICOLON_TOKEN) {
+ currentToken = tokenizer.nextToken();
+ }
+
+ // look for a ';' which will indicate whether
+ // a parameter list is present or not
+ if (currentToken == MailcapTokenizer.SEMICOLON_TOKEN) {
+ boolean isFallback = false;
+ do {
+ // eat the ';'
+
+ // parse the parameter name
+ currentToken = tokenizer.nextToken();
+ if (currentToken != MailcapTokenizer.STRING_TOKEN) {
+ reportParseError(MailcapTokenizer.STRING_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+ String paramName = tokenizer.getCurrentTokenValue().
+ toLowerCase(Locale.ENGLISH);
+
+ // parse the '=' which separates the name from the value
+ currentToken = tokenizer.nextToken();
+ if ((currentToken != MailcapTokenizer.EQUALS_TOKEN) &&
+ (currentToken != MailcapTokenizer.SEMICOLON_TOKEN) &&
+ (currentToken != MailcapTokenizer.EOI_TOKEN)) {
+ reportParseError(MailcapTokenizer.EQUALS_TOKEN,
+ MailcapTokenizer.SEMICOLON_TOKEN,
+ MailcapTokenizer.EOI_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+
+ // we only have a useful command if it is named
+ if (currentToken == MailcapTokenizer.EQUALS_TOKEN) {
+ // eat it
+
+ // parse the parameter value (which is autoquoted)
+ tokenizer.setIsAutoquoting(true);
+ currentToken = tokenizer.nextToken();
+ tokenizer.setIsAutoquoting(false);
+ if (currentToken != MailcapTokenizer.STRING_TOKEN) {
+ reportParseError(MailcapTokenizer.STRING_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+ String paramValue =
+ tokenizer.getCurrentTokenValue();
+
+ // add the class to the list iff it is one we care about
+ if (paramName.startsWith("x-java-")) {
+ String commandName = paramName.substring(7);
+ // 7 == "x-java-".length
+
+ if (commandName.equals("fallback-entry") &&
+ paramValue.equalsIgnoreCase("true")) {
+ isFallback = true;
+ } else {
+
+ // setup the class entry list
+ if (LogSupport.isLoggable())
+ LogSupport.log(" Command: " + commandName +
+ ", Class: " + paramValue);
+ List classes = (List)commands.get(commandName);
+ if (classes == null) {
+ classes = new ArrayList();
+ commands.put(commandName, classes);
+ }
+ if (addReverse)
+ classes.add(0, paramValue);
+ else
+ classes.add(paramValue);
+ }
+ }
+
+ // set up the next iteration
+ currentToken = tokenizer.nextToken();
+ }
+ } while (currentToken == MailcapTokenizer.SEMICOLON_TOKEN);
+
+ Map masterHash = isFallback ? fallback_hash : type_hash;
+ Map curcommands =
+ (Map)masterHash.get(mimeType);
+ if (curcommands == null) {
+ masterHash.put(mimeType, commands);
+ } else {
+ if (LogSupport.isLoggable())
+ LogSupport.log("Merging commands for type " + mimeType);
+ // have to merge current and new commands
+ // first, merge list of classes for commands already known
+ Iterator cn = curcommands.keySet().iterator();
+ while (cn.hasNext()) {
+ String cmdName = (String)cn.next();
+ List ccv = (List)curcommands.get(cmdName);
+ List cv = (List)commands.get(cmdName);
+ if (cv == null)
+ continue;
+ // add everything in cv to ccv, if it's not already there
+ Iterator cvn = cv.iterator();
+ while (cvn.hasNext()) {
+ String clazz = (String)cvn.next();
+ if (!ccv.contains(clazz))
+ if (addReverse)
+ ccv.add(0, clazz);
+ else
+ ccv.add(clazz);
+ }
+ }
+ // now, add commands not previously known
+ cn = commands.keySet().iterator();
+ while (cn.hasNext()) {
+ String cmdName = (String)cn.next();
+ if (curcommands.containsKey(cmdName))
+ continue;
+ List cv = (List)commands.get(cmdName);
+ curcommands.put(cmdName, cv);
+ }
+ }
+ } else if (currentToken != MailcapTokenizer.EOI_TOKEN) {
+ reportParseError(MailcapTokenizer.EOI_TOKEN,
+ MailcapTokenizer.SEMICOLON_TOKEN,
+ currentToken, tokenizer.getCurrentTokenValue());
+ }
+ }
+
+ protected static void reportParseError(int expectedToken, int actualToken,
+ String actualTokenValue) throws MailcapParseException {
+ throw new MailcapParseException("Encountered a " +
+ MailcapTokenizer.nameForToken(actualToken) + " token (" +
+ actualTokenValue + ") while expecting a " +
+ MailcapTokenizer.nameForToken(expectedToken) + " token.");
+ }
+
+ protected static void reportParseError(int expectedToken,
+ int otherExpectedToken, int actualToken, String actualTokenValue)
+ throws MailcapParseException {
+ throw new MailcapParseException("Encountered a " +
+ MailcapTokenizer.nameForToken(actualToken) + " token (" +
+ actualTokenValue + ") while expecting a " +
+ MailcapTokenizer.nameForToken(expectedToken) + " or a " +
+ MailcapTokenizer.nameForToken(otherExpectedToken) + " token.");
+ }
+
+ protected static void reportParseError(int expectedToken,
+ int otherExpectedToken, int anotherExpectedToken, int actualToken,
+ String actualTokenValue) throws MailcapParseException {
+ if (LogSupport.isLoggable())
+ LogSupport.log("PARSE ERROR: " + "Encountered a " +
+ MailcapTokenizer.nameForToken(actualToken) + " token (" +
+ actualTokenValue + ") while expecting a " +
+ MailcapTokenizer.nameForToken(expectedToken) + ", a " +
+ MailcapTokenizer.nameForToken(otherExpectedToken) + ", or a " +
+ MailcapTokenizer.nameForToken(anotherExpectedToken) + " token.");
+ throw new MailcapParseException("Encountered a " +
+ MailcapTokenizer.nameForToken(actualToken) + " token (" +
+ actualTokenValue + ") while expecting a " +
+ MailcapTokenizer.nameForToken(expectedToken) + ", a " +
+ MailcapTokenizer.nameForToken(otherExpectedToken) + ", or a " +
+ MailcapTokenizer.nameForToken(anotherExpectedToken) + " token.");
+ }
+
+ /** for debugging
+ public static void main(String[] args) throws Exception {
+ Map masterHash = new HashMap();
+ for (int i = 0; i < args.length; ++i) {
+ System.out.println("Entry " + i + ": " + args[i]);
+ parseLine(args[i], masterHash);
+ }
+
+ Enumeration types = masterHash.keys();
+ while (types.hasMoreElements()) {
+ String key = (String)types.nextElement();
+ System.out.println("MIME Type: " + key);
+
+ Map commandHash = (Map)masterHash.get(key);
+ Enumeration commands = commandHash.keys();
+ while (commands.hasMoreElements()) {
+ String command = (String)commands.nextElement();
+ System.out.println(" Command: " + command);
+
+ Vector classes = (Vector)commandHash.get(command);
+ for (int i = 0; i < classes.size(); ++i) {
+ System.out.println(" Class: " +
+ (String)classes.elementAt(i));
+ }
+ }
+
+ System.out.println("");
+ }
+ }
+ */
+}

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/MailcapParseException.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/MailcapParseException.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,55 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+/**
+ * A class to encapsulate Mailcap parsing related exceptions
+ */
+public class MailcapParseException extends Exception {
+
+ public MailcapParseException() {
+ super();
+ }
+
+ public MailcapParseException(String inInfo) {
+ super(inInfo);
+ }
+}

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/MailcapTokenizer.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/MailcapTokenizer.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,337 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+/**
+ * A tokenizer for strings in the form of "foo/bar; prop1=val1; ... ".
+ * Useful for parsing MIME content types.
+ */
+public class MailcapTokenizer {
+
+ public static final int UNKNOWN_TOKEN = 0;
+ public static final int START_TOKEN = 1;
+ public static final int STRING_TOKEN = 2;
+ public static final int EOI_TOKEN = 5;
+ public static final int SLASH_TOKEN = '/';
+ public static final int SEMICOLON_TOKEN = ';';
+ public static final int EQUALS_TOKEN = '=';
+
+ /**
+ * Constructor
+ *
+ * @parameter inputString the string to tokenize
+ */
+ public MailcapTokenizer(String inputString) {
+ data = inputString;
+ dataIndex = 0;
+ dataLength = inputString.length();
+
+ currentToken = START_TOKEN;
+ currentTokenValue = "";
+
+ isAutoquoting = false;
+ autoquoteChar = ';';
+ }
+
+ /**
+ * Set whether auto-quoting is on or off.
+ *
+ * Auto-quoting means that all characters after the first
+ * non-whitespace, non-control character up to the auto-quote
+ * terminator character or EOI (minus any whitespace immediatley
+ * preceeding it) is considered a token.
+ *
+ * This is required for handling command strings in a mailcap entry.
+ */
+ public void setIsAutoquoting(boolean value) {
+ isAutoquoting = value;
+ }
+
+ /**
+ * Retrieve current token.
+ *
+ * @returns The current token value
+ */
+ public int getCurrentToken() {
+ return currentToken;
+ }
+
+ /*
+ * Get a String that describes the given token.
+ */
+ public static String nameForToken(int token) {
+ String name = "really unknown";
+
+ switch(token) {
+ case UNKNOWN_TOKEN:
+ name = "unknown";
+ break;
+ case START_TOKEN:
+ name = "start";
+ break;
+ case STRING_TOKEN:
+ name = "string";
+ break;
+ case EOI_TOKEN:
+ name = "EOI";
+ break;
+ case SLASH_TOKEN:
+ name = "'/'";
+ break;
+ case SEMICOLON_TOKEN:
+ name = "';'";
+ break;
+ case EQUALS_TOKEN:
+ name = "'='";
+ break;
+ }
+
+ return name;
+ }
+
+ /*
+ * Retrieve current token value.
+ *
+ * @returns A String containing the current token value
+ */
+ public String getCurrentTokenValue() {
+ return currentTokenValue;
+ }
+
+ /*
+ * Process the next token.
+ *
+ * @returns the next token
+ */
+ public int nextToken() {
+ if (dataIndex < dataLength) {
+ // skip white space
+ while ((dataIndex < dataLength) &&
+ (isWhiteSpaceChar(data.charAt(dataIndex)))) {
+ ++dataIndex;
+ }
+
+ if (dataIndex < dataLength) {
+ // examine the current character and see what kind of token we have
+ char c = data.charAt(dataIndex);
+ if (isAutoquoting) {
+ if (c == ';' || c == '=') {
+ currentToken = c;
+ currentTokenValue = new Character(c).toString();
+ ++dataIndex;
+ } else {
+ processAutoquoteToken();
+ }
+ } else {
+ if (isStringTokenChar(c)) {
+ processStringToken();
+ } else if ((c == '/') || (c == ';') || (c == '=')) {
+ currentToken = c;
+ currentTokenValue = new Character(c).toString();
+ ++dataIndex;
+ } else {
+ currentToken = UNKNOWN_TOKEN;
+ currentTokenValue = new Character(c).toString();
+ ++dataIndex;
+ }
+ }
+ } else {
+ currentToken = EOI_TOKEN;
+ currentTokenValue = null;
+ }
+ } else {
+ currentToken = EOI_TOKEN;
+ currentTokenValue = null;
+ }
+
+ return currentToken;
+ }
+
+ private void processStringToken() {
+ // capture the initial index
+ int initialIndex = dataIndex;
+
+ // skip to 1st non string token character
+ while ((dataIndex < dataLength) &&
+ isStringTokenChar(data.charAt(dataIndex))) {
+ ++dataIndex;
+ }
+
+ currentToken = STRING_TOKEN;
+ currentTokenValue = data.substring(initialIndex, dataIndex);
+ }
+
+ private void processAutoquoteToken() {
+ // capture the initial index
+ int initialIndex = dataIndex;
+
+ // now skip to the 1st non-escaped autoquote termination character
+ // XXX - doesn't actually consider escaping
+ boolean foundTerminator = false;
+ while ((dataIndex < dataLength) && !foundTerminator) {
+ char c = data.charAt(dataIndex);
+ if (c != autoquoteChar) {
+ ++dataIndex;
+ } else {
+ foundTerminator = true;
+ }
+ }
+
+ currentToken = STRING_TOKEN;
+ currentTokenValue =
+ fixEscapeSequences(data.substring(initialIndex, dataIndex));
+ }
+
+ private static boolean isSpecialChar(char c) {
+ boolean lAnswer = false;
+
+ switch(c) {
+ case '(':
+ case ')':
+ case '<':
+ case '>':
+ case '@':
+ case ',':
+ case ';':
+ case ':':
+ case '\\':
+ case '"':
+ case '/':
+ case '[':
+ case ']':
+ case '?':
+ case '=':
+ lAnswer = true;
+ break;
+ }
+
+ return lAnswer;
+ }
+
+ private static boolean isControlChar(char c) {
+ return Character.isISOControl(c);
+ }
+
+ private static boolean isWhiteSpaceChar(char c) {
+ return Character.isWhitespace(c);
+ }
+
+ private static boolean isStringTokenChar(char c) {
+ return !isSpecialChar(c) && !isControlChar(c) && !isWhiteSpaceChar(c);
+ }
+
+ private static String fixEscapeSequences(String inputString) {
+ int inputLength = inputString.length();
+ StringBuffer buffer = new StringBuffer();
+ buffer.ensureCapacity(inputLength);
+
+ for (int i = 0; i < inputLength; ++i) {
+ char currentChar = inputString.charAt(i);
+ if (currentChar != '\\') {
+ buffer.append(currentChar);
+ } else {
+ if (i < inputLength - 1) {
+ char nextChar = inputString.charAt(i + 1);
+ buffer.append(nextChar);
+
+ // force a skip over the next character too
+ ++i;
+ } else {
+ buffer.append(currentChar);
+ }
+ }
+ }
+
+ return buffer.toString();
+ }
+
+ private String data;
+ private int dataIndex;
+ private int dataLength;
+ private int currentToken;
+ private String currentTokenValue;
+ private boolean isAutoquoting;
+ private char autoquoteChar;
+
+ /*
+ public static void main(String[] args) {
+ for (int i = 0; i < args.length; ++i) {
+ MailcapTokenizer tokenizer = new MailcapTokenizer(args[i]);
+
+ System.out.println("Original: |" + args[i] + "|");
+
+ int currentToken = tokenizer.nextToken();
+ while (currentToken != EOI_TOKEN) {
+ switch(currentToken) {
+ case UNKNOWN_TOKEN:
+ System.out.println(" Unknown Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case START_TOKEN:
+ System.out.println(" Start Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case STRING_TOKEN:
+ System.out.println(" String Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case EOI_TOKEN:
+ System.out.println(" EOI Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case SLASH_TOKEN:
+ System.out.println(" Slash Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case SEMICOLON_TOKEN:
+ System.out.println(" Semicolon Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ case EQUALS_TOKEN:
+ System.out.println(" Equals Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ default:
+ System.out.println(" Really Unknown Token: |" + tokenizer.getCurrentTokenValue() + "|");
+ break;
+ }
+
+ currentToken = tokenizer.nextToken();
+ }
+
+ System.out.println("");
+ }
+ }
+ */
+}

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/MimeTypeEntry.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/MimeTypeEntry.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,65 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+import java.lang.*;
+
+public class MimeTypeEntry {
+ private String type;
+ private String extension;
+
+ public MimeTypeEntry(String mime_type, String file_ext) {
+ type = mime_type;
+ extension = file_ext;
+ }
+
+ public String getMIMEType() {
+ return type;
+ }
+
+ public String getFileExtension() {
+ return extension;
+ }
+
+ public String toString() {
+ return "MIMETypeEntry: " + type + ", " + extension;
+ }
+}

diff -r b074be087fab -r 80a182f23183 android/activation/src/main/java/com/sun/activation/registries/MimeTypeFile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/android/activation/src/main/java/com/sun/activation/registries/MimeTypeFile.java Thu Aug 27 15:35:34 2015 -0700
@@ -0,0 +1,332 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.activation.registries;
+
+import java.io.*;
+import java.util.*;
+
+public class MimeTypeFile {
+ private String fname = null;
+ private Hashtable type_hash = new Hashtable();
+
+ /**
+ * The construtor that takes a filename as an argument.
+ *
+ * @param new_fname The file name of the mime types file.
+ */
+ public MimeTypeFile(String new_fname) throws IOException {
+ File mime_file = null;
+ FileReader fr = null;
+
+ fname = new_fname; // remember the file name
+
+ mime_file = new File(fname); // get a file object
+
+ fr = new FileReader(mime_file);
+
+ try {
+ parse(new BufferedReader(fr));
+ } finally {
+ try {
+ fr.close(); // close it
+ } catch (IOException e) {
+ // ignore it
+ }
+ }
+ }
+
+ public MimeTypeFile(InputStream is) throws IOException {
+ parse(new BufferedReader(new InputStreamReader(is, "iso-8859-1")));
+ }
+
+ /**
+ * Creates an empty DB.
+ */
+ public MimeTypeFile() {
+ }
+
+ /**
+ * get the MimeTypeEntry based on the file extension
+ */
+ public MimeTypeEntry getMimeTypeEntry(String file_ext) {
+ return (MimeTypeEntry)type_hash.get((Object)file_ext);
+ }
+
+ /**
+ * Get the MIME type string corresponding to the file extension.
+ */
+ public String getMIMETypeString(String file_ext) {
+ MimeTypeEntry entry = this.getMimeTypeEntry(file_ext);
+
+ if (entry != null)
+ return entry.getMIMEType();
+ else
+ return null;
+ }
+
+ /**
+ * Appends string of entries to the types registry, must be valid
+ * .mime.types format.
+ * A mime.types entry is one of two forms:
+ *
+ * type/subtype ext1 ext2 ...
+ * or
+ * type=type/subtype desc="description of type" exts=ext1,ext2,...
+ *
+ * Example:
+ * # this is a test
+ * audio/basic au
+ * text/plain txt text
+ * type=application/postscript exts=ps,eps
+ */
+ public void appendToRegistry(String mime_types) {
+ try {
+ parse(new BufferedReader(new StringReader(mime_types)));
+ } catch (IOException ex) {
+ // can't happen
+ }
+ }
+
+ /**
+ * Parse a stream of mime.types entries.
+ */
+ private void parse(BufferedReader buf_reader) throws IOException {
+ String line = null, prev = null;
+
+ while ((line = buf_reader.readLine()) != null) {
+ if (prev == null)
+ prev = line;
+ else
+ prev += line;
+ int end = prev.length();
+ if (prev.length() > 0 && prev.charAt(end - 1) == '\\') {
+ prev = prev.substring(0, end - 1);
+ continue;
+ }
+ this.parseEntry(prev);
+ prev = null;
+ }
+ if (prev != null)
+ this.parseEntry(prev);
+ }
+
+ /**
+ * Parse single mime.types entry.
+ */
+ private void parseEntr
[truncated due to length]