fixed compatibility issues with OpenOffice 3.0 and Excel 2008 Mac sp2, see Bugzilla #46419 and #47559

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@797350 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2009-07-24 07:29:22 +00:00
parent 32d0c7213e
commit 0f1f7d1d48
11 changed files with 91 additions and 30 deletions

View File

@ -22,10 +22,6 @@
<document>
<header>
<title>Busy Developers' Guide to HSSF and XSSF Features</title>
<authors>
<person email="user@poi.apache.org" name="Glen Stampoultzis" id="CO"/>
<person email="user@poi.apache.org" name="Yegor Kozlov" id="YK"/>
</authors>
</header>
<body>
<section><title>Busy Developers' Guide to Features</title>

View File

@ -33,6 +33,8 @@
<changes>
<release version="3.5-beta7" date="2009-??-??">
<action dev="POI-DEVELOPERS" type="fix">46419 - Fixed compatibility issue with OpenOffice 3.0</action>
<action dev="POI-DEVELOPERS" type="fix">47559 - Fixed compatibility issue with Excel 2008 Max sp2</action>
<action dev="POI-DEVELOPERS" type="fix">47540 - Fix for saving custom and extended OOXML properties</action>
<action dev="POI-DEVELOPERS" type="fix">47535 - Fixed WordExtractor to tolerate files with empty footnote block</action>
<action dev="POI-DEVELOPERS" type="fix">47517 - Fixed ExtractorFactory to support .xltx and .dotx files</action>

View File

@ -136,7 +136,7 @@ public final class PackageRelationship {
/* Getters */
public URI getContainerPartRelationship() {
public static URI getContainerPartRelationship() {
return containerRelationshipPart;
}

View File

@ -259,11 +259,14 @@ public final class PackagingURIHelper {
* The source part URI.
* @param targetURI
* The target part URI.
* @param msCompatible if true then remove leading slash from the relativized URI.
* This flag violates [M1.4]: A part name shall start with a forward slash ('/') character, but
* allows generating URIs compatible with MS Office and OpenOffice.
* @return A fully relativize part name URI ('word/media/image1.gif',
* '/word/document.xml' => 'media/image1.gif') else
* <code>null</code>.
*/
public static URI relativizeURI(URI sourceURI, URI targetURI) {
public static URI relativizeURI(URI sourceURI, URI targetURI, boolean msCompatible) {
StringBuilder retVal = new StringBuilder();
String[] segmentsSource = sourceURI.getPath().split("/", -1);
String[] segmentsTarget = targetURI.getPath().split("/", -1);
@ -283,6 +286,15 @@ public final class PackagingURIHelper {
// If the source is the root, then the relativized
// form must actually be an absolute URI
if(sourceURI.toString().equals("/")) {
String path = targetURI.getPath();
if(msCompatible && path.charAt(0) == '/') {
try {
targetURI = new URI(path.substring(1));
} catch (Exception e) {
System.err.println(e);
return null;
}
}
return targetURI;
}
@ -358,7 +370,22 @@ public final class PackagingURIHelper {
}
}
/**
/**
* Fully relativize the source part URI against the target part URI.
*
* @param sourceURI
* The source part URI.
* @param targetURI
* The target part URI.
* @return A fully relativize part name URI ('word/media/image1.gif',
* '/word/document.xml' => 'media/image1.gif') else
* <code>null</code>.
*/
public static URI relativizeURI(URI sourceURI, URI targetURI) {
return relativizeURI(sourceURI, targetURI, false);
}
/**
* Resolve a source uri against a target.
*
* @param sourcePartUri

View File

@ -163,7 +163,7 @@ public final class ZipPartMarshaller implements PartMarshaller {
} else {
URI targetURI = rel.getTargetURI();
targetValue = PackagingURIHelper.relativizeURI(
sourcePartURI, targetURI).getPath();
sourcePartURI, targetURI, true).getPath();
if (targetURI.getRawFragment() != null) {
targetValue += "#" + targetURI.getRawFragment();
}

View File

@ -30,6 +30,7 @@ import javax.xml.namespace.QName;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.hssf.record.formula.SheetNameFormatter;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
@ -228,6 +229,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
bv.setActiveTab(0);
workbook.addNewSheets();
//required by Excel 2008 Mac sp2, see Bugzilla #47559
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication("Microsoft Excel");
sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());

View File

@ -23,6 +23,7 @@ import java.util.*;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.util.PackageHelper;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.xmlbeans.XmlException;
@ -187,6 +188,9 @@ public class XWPFDocument extends POIXMLDocument {
ctDocument = CTDocument1.Factory.newInstance();
ctDocument.addNewBody();
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication("Microsoft Office Word");
}
/**

View File

@ -27,6 +27,7 @@ import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.TreeMap;
import java.util.Iterator;
import junit.framework.TestCase;
@ -36,11 +37,14 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
import org.apache.poi.openxml4j.opc.internal.FileHelper;
import org.apache.poi.util.TempFile;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
public final class TestPackage extends TestCase {
private static Logger logger = Logger.getLogger("org.apache.poi.openxml4j.test");
@ -185,16 +189,17 @@ public final class TestPackage extends TestCase {
// Save and re-load
pkg.close();
File tmp = TempFile.createTempFile("testCreatePackageWithCoreDocument", ".zip");
FileOutputStream fout = new FileOutputStream(tmp);
FileOutputStream fout = new FileOutputStream(tmp);
fout.write(baos.toByteArray());
fout.close();
pkg = OPCPackage.open(tmp.getPath());
//tmp.delete();
// Check still right
coreRels = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
assertEquals(1, coreRels.size());
coreRel = coreRels.getRelationship(0);
assertEquals("/", coreRel.getSourceURI().toString());
assertEquals("/xl/workbook.xml", coreRel.getTargetURI().toString());
corePart = pkg.getPart(coreRel);
@ -205,10 +210,30 @@ public final class TestPackage extends TestCase {
rel = rels.getRelationship(0);
assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment());
assertMSCompatibility(pkg);
}
private void assertMSCompatibility(OPCPackage pkg) throws Exception {
PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship());
PackagePart relPart = pkg.getPart(relName);
SAXReader reader = new SAXReader();
Document xmlRelationshipsDoc = reader
.read(relPart.getInputStream());
Element root = xmlRelationshipsDoc.getRootElement();
for (Iterator i = root
.elementIterator(PackageRelationship.RELATIONSHIP_TAG_NAME); i
.hasNext();) {
Element element = (Element) i.next();
String value = element.attribute(
PackageRelationship.TARGET_ATTRIBUTE_NAME)
.getValue();
assertTrue("Root target must not start with a leadng slash ('/'): " + value, value.charAt(0) != '/');
}
}
/**
/**
* Test package opening.
*/
public void testOpenPackage() throws Exception {

View File

@ -31,8 +31,6 @@ public class TestPackagingURIHelper extends TestCase {
/**
* Test relativizePartName() method.
*
* TODO: fix and unable
*/
public void testRelativizeURI() throws Exception {
URI uri1 = new URI("/word/document.xml");
@ -54,23 +52,15 @@ public class TestPackagingURIHelper extends TestCase {
URI retURI2 = PackagingURIHelper.relativizeURI(uri1, uri1);
assertEquals("", retURI2.getPath());
// Document and root totally different
URI uri4 = new URI("/");
try {
PackagingURIHelper.relativizeURI(uri1, uri4);
//TODO: figure oout why the assertion fails
//fail("Must throw an exception ! Can't relativize with an empty URI");
} catch (Exception e) {
// Do nothing
}
try {
PackagingURIHelper.relativizeURI(uri4, uri1);
//TODO: figure oout why the assertion fails
//fail("Must throw an exception ! Can't relativize with an empty URI");
} catch (Exception e) {
// Do nothing
}
}
// relativization against root
URI root = new URI("/");
uriRes = PackagingURIHelper.relativizeURI(root, uri1);
assertEquals("/word/document.xml", uriRes.toString());
//URI compatible with MS Office and OpenOffice: leading slash is removed
uriRes = PackagingURIHelper.relativizeURI(root, uri1, true);
assertEquals("word/document.xml", uriRes.toString());
}
/**
* Test createPartName(String, y)

View File

@ -260,6 +260,8 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
XSSFWorkbook workbook = new XSSFWorkbook();
POIXMLProperties props = workbook.getProperties();
assertNotNull(props);
//the Application property must be set for new workbooks, see Bugzilla #47559
assertEquals("Microsoft Excel", props.getExtendedProperties().getUnderlyingProperties().getApplication());
PackagePropertiesPart opcProps = props.getCoreProperties().getUnderlyingProperties();
assertNotNull(opcProps);
@ -269,6 +271,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
opcProps.setCreatorProperty("poi-dev@poi.apache.org");
workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook);
assertEquals("Microsoft Excel", workbook.getProperties().getExtendedProperties().getUnderlyingProperties().getApplication());
opcProps = workbook.getProperties().getCoreProperties().getUnderlyingProperties();
assertEquals("Testing Bugzilla #47460", opcProps.getTitleProperty().getValue());
assertEquals("poi-dev@poi.apache.org", opcProps.getCreatorProperty().getValue());

View File

@ -21,6 +21,7 @@ import java.io.File;
import junit.framework.TestCase;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
@ -119,4 +120,12 @@ public class TestXWPFDocument extends TestCase {
assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
}
public void testWorkbookProperties() throws Exception {
XWPFDocument doc = new XWPFDocument();
POIXMLProperties props = doc.getProperties();
assertNotNull(props);
assertEquals("Microsoft Office Word", props.getExtendedProperties().getUnderlyingProperties().getApplication());
}
}