Index: java/org/apache/poi/openxml4j/opc/internal/ContentType.java =================================================================== --- java/org/apache/poi/openxml4j/opc/internal/ContentType.java (revision 1518613) +++ java/org/apache/poi/openxml4j/opc/internal/ContentType.java (working copy) @@ -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; @@ -68,7 +67,7 @@ /** * Media type compiled pattern for parameters. */ - private final static Pattern patternMediaType; + private final static Pattern patternMediaType, patternMediaTypeParams; static { /* @@ -90,8 +89,7 @@ * * value = token | quoted-string */ - // Keep for future use with parameter: - // String parameter = "(" + token + "+)=(\"?" + token + "+\"?)"; + String parameter = "(" + token + "+)=(\"?" + token + "+\"?)"; /* * Pattern for media type. * @@ -118,11 +116,9 @@ * quoted-pair = "\" CHAR */ - // Keep for future use with parameter: - // patternMediaType = Pattern.compile("^(" + token + "+)/(" + token - // + "+)(;" + parameter + ")*$"); patternMediaType = Pattern.compile("^(" + token + "+)/(" + token - + "+)$"); + + "+)(;" + parameter + ")*$"); + patternMediaTypeParams = Pattern.compile(";" + parameter); } /** @@ -146,11 +142,17 @@ this.type = mMediaType.group(1); this.subType = mMediaType.group(2); // Parameters + // Be careful that java pattern matcher do not allow a multiple group capture + // only the last group is saved: + // http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#cg + // http://stackoverflow.com/questions/6138894/regex-to-read-multiple-parameters-of-unknown-multiplicity + // So a solution is to split pattern matcher in 2 parts... :-( this.parameters = new Hashtable(1); - for (int i = 4; i <= mMediaType.groupCount() - && (mMediaType.group(i) != null); i += 2) { - this.parameters.put(mMediaType.group(i), mMediaType - .group(i + 1)); + if (mMediaType.groupCount() >= 5) { + Matcher mParams = patternMediaTypeParams.matcher(contentType.substring(mMediaType.end(2))); + while (mParams.find()) { + this.parameters.put(mParams.group(1), mParams.group(2)); + } } } } @@ -161,13 +163,12 @@ 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)); - // } + for (String key : parameters.keySet()) { + retVal.append(";"); + retVal.append(key); + retVal.append("="); + retVal.append(parameters.get(key)); + } return retVal.toString(); } Index: testcases/org/apache/poi/openxml4j/opc/TestContentType.java =================================================================== --- testcases/org/apache/poi/openxml4j/opc/TestContentType.java (revision 1518613) +++ testcases/org/apache/poi/openxml4j/opc/TestContentType.java (working copy) @@ -84,10 +84,16 @@ * criteria of rule [01.2] * Invalid parameters are verified as incorrect in * {@link #testContentTypeParameterFailure()} + * @throws InvalidFormatException */ - public void testContentTypeParam() { - // TODO Review [01.2], then add tests for valid ones - // TODO See bug #55026 + public void testContentTypeParam() throws InvalidFormatException { + // Reviewed [01.2], and added tests for valid ones + // See bug #55026 + String[] contentTypesToTest = new String[] { "text/xml;key1=param1;key2=param2", + "application/pgp-key;version=\"2\"", "application/x-resqml+xml;version=2.0;type=obj_global2dCrs" }; + for (int i = 0; i < contentTypesToTest.length; ++i) { + new ContentType(contentTypesToTest[i]); + } } /** @@ -95,8 +101,8 @@ * 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", + "text/xml;a=;c=d", "mail/toto;\"titi=tata\"", "text/\u0080" // characters above ASCII are not allowed }; for (int i = 0; i < contentTypesToTest.length; ++i) {