]> source.dussan.org Git - poi.git/commitdiff
Begin to implement some of the tests and logic for content types with parameters...
authorNick Burch <nick@apache.org>
Wed, 19 Feb 2014 23:12:56 +0000 (23:12 +0000)
committerNick Burch <nick@apache.org>
Wed, 19 Feb 2014 23:12:56 +0000 (23:12 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1569965 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/openxml4j/opc/PackagePart.java
src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentType.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestContentType.java

index e97349447f0330f22c6cb3247514f5098fe176e3..1420fd44154cce49ed5ebe9970b32338777a12a7 100644 (file)
@@ -572,12 +572,19 @@ public abstract class PackagePart implements RelationshipSource {
        }
 
        /**
-        * @return the contentType
+        * @return The Content Type of the part
         */
        public String getContentType() {
                return _contentType.toString();
        }
 
+    /**
+     * @return The Content Type, including parameters, of the part
+     */
+    public ContentType getContentTypeDetails() {
+        return _contentType;
+    }
+
        /**
         * Set the content type.
         *
index 4d4c9283c2b7d156926bdc8f98affdf3ccf92090..fcb77bc971d654679d9be847c897a18d3e54ba8e 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.openxml4j.opc.internal;
 
-import java.io.UnsupportedEncodingException;
 import java.util.Hashtable;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -66,9 +65,13 @@ public final class ContentType {
        private Hashtable<String, String> parameters;
 
        /**
-        * Media type compiled pattern for parameters.
+        * Media type compiled pattern, without parameters
         */
-       private final static Pattern patternMediaType;
+       private final static Pattern patternTypeSubType;
+    /**
+     * Media type compiled pattern, with parameters.
+     */
+    private final static Pattern patternTypeSubTypeParams;
 
        static {
                /*
@@ -90,8 +93,7 @@ public final class ContentType {
                 *
                 * value = token | quoted-string
                 */
-               // Keep for future use with parameter:
-               // String parameter = "(" + token + "+)=(\"?" + token + "+\"?)";
+               String parameter = "(" + token + "+)=(\"?" + token + "+\"?)";
                /*
                 * Pattern for media type.
                 *
@@ -118,11 +120,10 @@ public final class ContentType {
                 * quoted-pair = "\" CHAR
                 */
 
-               // Keep for future use with parameter:
-               // patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
-               // + "+)(;" + parameter + ")*$");
-               patternMediaType = Pattern.compile("^(" + token + "+)/(" + token
-                               + "+)$");
+               patternTypeSubType       = Pattern.compile("^(" + token + "+)/(" + 
+                                                          token + "+)$");
+               patternTypeSubTypeParams = Pattern.compile("^(" + token + "+)/(" + 
+                                                          token + "+)(;" + parameter + ")+$");
        }
 
        /**
@@ -134,19 +135,27 @@ public final class ContentType {
         *             If the specified content type is not valid with RFC 2616.
         */
        public ContentType(String contentType) throws InvalidFormatException {
-               Matcher mMediaType = patternMediaType.matcher(contentType);
-               if (!mMediaType.matches())
+               Matcher mMediaType = patternTypeSubType.matcher(contentType);
+               if (!mMediaType.matches()) {
+                   // How about with parameters?
+                   mMediaType = patternTypeSubTypeParams.matcher(contentType);
+               }
+        if (!mMediaType.matches()) {
                        throw new InvalidFormatException(
                                        "The specified content type '"
-                                                       + contentType
-                                                       + "' is not compliant with RFC 2616: malformed content type.");
+                                       + contentType
+                                       + "' is not compliant with RFC 2616: malformed content type.");
+        }
 
                // Type/subtype
                if (mMediaType.groupCount() >= 2) {
                        this.type = mMediaType.group(1);
                        this.subType = mMediaType.group(2);
+                       
                        // Parameters
                        this.parameters = new Hashtable<String, String>(1);
+//System.out.println(mMediaType.groupCount() + " = " + contentType);
+//for (int j=1; j<mMediaType.groupCount(); j++) { System.out.println("  " + j + " - " + mMediaType.group(j)); }
                        for (int i = 4; i <= mMediaType.groupCount()
                                        && (mMediaType.group(i) != null); i += 2) {
                                this.parameters.put(mMediaType.group(i), mMediaType
@@ -161,16 +170,22 @@ public final class ContentType {
                retVal.append(this.getType());
                retVal.append("/");
                retVal.append(this.getSubType());
-               // Keep for future implementation if needed
-               // for (String key : parameters.keySet()) {
-               // retVal.append(";");
-               // retVal.append(key);
-               // retVal.append("=");
-               // retVal.append(parameters.get(key));
-               // }
                return retVal.toString();
        }
 
+    public final String toStringWithParameters() {
+        StringBuffer retVal = new StringBuffer();
+        retVal.append(toString());
+        
+        for (String key : parameters.keySet()) {
+           retVal.append(";");
+           retVal.append(key);
+           retVal.append("=");
+           retVal.append(parameters.get(key));
+        }
+        return retVal.toString();
+    }
+
        @Override
        public boolean equals(Object obj) {
                return (!(obj instanceof ContentType))
@@ -201,6 +216,22 @@ public final class ContentType {
        public String getType() {
                return this.type;
        }
+       
+       /**
+        * Does this content type have any parameters associated with it?
+        */
+       public boolean hasParameters() {
+           return (parameters != null) && !parameters.isEmpty();
+       }
+       
+       /**
+        * Return the parameter keys
+        */
+       public String[] getParameterKeys() {
+           if (parameters == null)
+               return new String[0];
+           return parameters.keySet().toArray(new String[parameters.size()]);
+       }
 
        /**
         * Gets the value associated to the specified key.
@@ -209,7 +240,13 @@ public final class ContentType {
         *            The key of the key/value pair.
         * @return The value associated to the specified key.
         */
-       public String getParameters(String key) {
+       public String getParameter(String key) {
                return parameters.get(key);
        }
+       /**
+        * @deprecated Use {@link #getParameter(String)} instead
+        */
+    public String getParameters(String key) {
+        return getParameter(key);
+    }
 }
index a74d3822006d6fbf870db2661a8ede1091d222b4..350e0bb6c9920468fb9b712f5744cae4a0c18f3a 100644 (file)
 
 package org.apache.poi.openxml4j.opc;
 
+import java.io.InputStream;
+
 import junit.framework.TestCase;
 
+import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.internal.ContentType;
 
@@ -88,6 +91,9 @@ public final class TestContentType extends TestCase {
    public void testContentTypeParam() {
       // TODO Review [01.2], then add tests for valid ones
       // TODO See bug #55026
+      // String[] contentTypesToTest = new String[] { "mail/toto;titi=tata",
+      //         "text/xml;a=b;c=d" // TODO Maybe more?
+      // };
    }
    
        /**
@@ -95,8 +101,8 @@ public final class TestContentType extends TestCase {
         * parameters for content types.
         */
        public void testContentTypeParameterFailure() {
-               String[] contentTypesToTest = new String[] { "mail/toto;titi=tata",
-                               "text/xml;a=b;c=d", "mail/toto;\"titi=tata\"",
+               String[] contentTypesToTest = new String[] { 
+                       "mail/toto;\"titi=tata\"", // quotes not allowed like that
                 "text/\u0080" // characters above ASCII are not allowed
         };
                for (int i = 0; i < contentTypesToTest.length; ++i) {
@@ -128,11 +134,72 @@ public final class TestContentType extends TestCase {
                }
        }
        
+       /**
+        * OOXML content types don't need entities, but we shouldn't
+        * barf if we get one from a third party system that added them
+        */
+       public void testFileWithContentTypeEntities() {
+           // TODO
+       }
+       
        /**
         * Check that we can open a file where there are valid
         *  parameters on a content type
         */
-       public void testFileWithContentTypeParams() {
-          // TODO Implement with ContentTypeHasParameters.ooxml
+       public void DISABLEDtestFileWithContentTypeParams() throws Exception {
+        InputStream is = OpenXML4JTestDataSamples.openSampleStream("ContentTypeHasParameters.ooxml");
+
+        OPCPackage p = OPCPackage.open(is);
+        
+        final String typeResqml = "application/x-resqml+xml";
+        
+        // Check the types on everything
+        for (PackagePart part : p.getParts()) {
+            // _rels type doesn't have any params
+            if (part.isRelationshipPart()) {
+                assertEquals(ContentTypes.RELATIONSHIPS_PART, part.getContentType());
+                assertEquals(ContentTypes.RELATIONSHIPS_PART, part.getContentTypeDetails().toString());
+                assertEquals(false, part.getContentTypeDetails().hasParameters());
+                assertEquals(0, part.getContentTypeDetails().getParameterKeys().length);
+            }
+            // Core type doesn't have any params
+            else if (part.getPartName().toString().equals("/docProps/core.xml")) {
+                assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType());
+                assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentTypeDetails().toString());
+                assertEquals(false, part.getContentTypeDetails().hasParameters());
+                assertEquals(0, part.getContentTypeDetails().getParameterKeys().length);
+            }
+            // Global Crs types do have params
+            else if (part.getPartName().toString().equals("/global1dCrs.xml")) {
+//System.out.println(part.getContentTypeDetails().toStringWithParameters());
+                assertEquals(typeResqml, part.getContentType());
+                assertEquals(typeResqml, part.getContentTypeDetails().toString());
+                assertEquals(true, part.getContentTypeDetails().hasParameters());
+                assertEquals(2, part.getContentTypeDetails().getParameterKeys().length);
+                assertEquals("2.0", part.getContentTypeDetails().getParameter("version"));
+                assertEquals("obj_global1dCrs", part.getContentTypeDetails().getParameter("type"));
+            }
+            else if (part.getPartName().toString().equals("/global2dCrs.xml")) {
+                assertEquals(typeResqml, part.getContentType());
+                assertEquals(typeResqml, part.getContentTypeDetails().toString());
+                assertEquals(true, part.getContentTypeDetails().hasParameters());
+                assertEquals(2, part.getContentTypeDetails().getParameterKeys().length);
+                assertEquals("2.0", part.getContentTypeDetails().getParameter("version"));
+                assertEquals("obj_global2dCrs", part.getContentTypeDetails().getParameter("type"));
+            }
+            // Other thingy
+            else if (part.getPartName().toString().equals("/myTestingGuid.xml")) {
+                assertEquals(typeResqml, part.getContentType());
+                assertEquals(typeResqml, part.getContentTypeDetails().toString());
+                assertEquals(true, part.getContentTypeDetails().hasParameters());
+                assertEquals(2, part.getContentTypeDetails().getParameterKeys().length);
+                assertEquals("2.0", part.getContentTypeDetails().getParameter("version"));
+                assertEquals("obj_tectonicBoundaryFeature", part.getContentTypeDetails().getParameter("type"));
+            }
+            // That should be it!
+            else {
+                fail("Unexpected part " + part);
+            }
+        }
        }
 }