Begin to implement some of the tests and logic for content types with parameters, based on the test file for bug #55026

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1569965 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-02-19 23:12:56 +00:00
parent 8ba2a370ba
commit ec93085044
3 changed files with 138 additions and 27 deletions

View 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.
*

View 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);
}
}

View File

@ -17,8 +17,11 @@
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);
}
}
}
}