Sfoglia il codice sorgente

apply HyperlinkRelationship

pull/617/head
Kwon Ohyoung 1 mese fa
parent
commit
cb90213d08

+ 33
- 28
poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLDocumentPart.java Vedi File

@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
@@ -641,38 +642,42 @@ public class POIXMLDocumentPart {

// scan breadth-first, so parent-relations are hopefully the shallowest element
for (PackageRelationship rel : rels) {
if (rel.getTargetMode() == TargetMode.INTERNAL) {
URI uri = rel.getTargetURI();

// check for internal references (e.g. '#Sheet1!A1')
PackagePartName relName;
if (uri.getRawFragment() != null) {
relName = PackagingURIHelper.createPartName(uri.getPath());
} else {
relName = PackagingURIHelper.createPartName(uri);
}
if (Objects.equals(rel.getRelationshipType(), HyperlinkRelationship.RELATIONSHIP_TYPE_CONST)) {
referenceRelationships.put(rel.getId(), new HyperlinkRelationship(this, rel.getTargetURI(), rel.getTargetMode() == TargetMode.EXTERNAL, rel.getId()));
} else {
if (rel.getTargetMode() == TargetMode.INTERNAL) {
URI uri = rel.getTargetURI();

// check for internal references (e.g. '#Sheet1!A1')
PackagePartName relName;
if (uri.getRawFragment() != null) {
relName = PackagingURIHelper.createPartName(uri.getPath());
} else {
relName = PackagingURIHelper.createPartName(uri);
}

final PackagePart p = packagePart.getPackage().getPart(relName);
if (p == null) {
LOG.atError().log("Skipped invalid entry {}", rel.getTargetURI());
continue;
}
final PackagePart p = packagePart.getPackage().getPart(relName);
if (p == null) {
LOG.atError().log("Skipped invalid entry {}", rel.getTargetURI());
continue;
}

POIXMLDocumentPart childPart = context.get(p);
if (childPart == null) {
childPart = factory.createDocumentPart(this, p);
//here we are checking if part if embedded and excel then set it to chart class
//so that at the time to writing we can also write updated embedded part
if (this instanceof XDDFChart && childPart instanceof XSSFWorkbook) {
((XDDFChart) this).setWorkbook((XSSFWorkbook) childPart);
POIXMLDocumentPart childPart = context.get(p);
if (childPart == null) {
childPart = factory.createDocumentPart(this, p);
//here we are checking if part if embedded and excel then set it to chart class
//so that at the time to writing we can also write updated embedded part
if (this instanceof XDDFChart && childPart instanceof XSSFWorkbook) {
((XDDFChart) this).setWorkbook((XSSFWorkbook) childPart);
}
childPart.parent = this;
// already add child to context, so other children can reference it
context.put(p, childPart);
readLater.add(childPart);
}
childPart.parent = this;
// already add child to context, so other children can reference it
context.put(p, childPart);
readLater.add(childPart);
}

addRelation(rel, childPart);
addRelation(rel, childPart);
}
}
}


+ 6
- 0
poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/PackageRelationship.java Vedi File

@@ -186,6 +186,12 @@ public final class PackageRelationship {
return targetUri;
}

// If it's an internal hyperlink target, we don't
// need to apply our normal validation rules
if (PackageRelationshipTypes.HYPERLINK_PART.equals(relationshipType)) {
return targetUri;
}

// Internal target
// If it isn't absolute, resolve it relative
// to ourselves

+ 10
- 1
poi-ooxml/src/main/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java Vedi File

@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Objects;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
@@ -32,6 +33,7 @@ import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.StreamHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
@@ -154,7 +156,14 @@ public final class ZipPartMarshaller implements PartMarshaller {
// the relationship Target
String targetValue;
URI uri = rel.getTargetURI();
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
if (Objects.equals(rel.getRelationshipType(), PackageRelationshipTypes.HYPERLINK_PART)) {
// Save the target as-is - we don't need to validate it,
targetValue = uri.toString();
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
// add TargetMode attribute (as it is external link external)
relElem.setAttribute(PackageRelationship.TARGET_MODE_ATTRIBUTE_NAME, "External");
}
} else if (rel.getTargetMode() == TargetMode.EXTERNAL) {
// Save the target as-is - we don't need to validate it,
// alter it etc
targetValue = uri.toString();

+ 1
- 1
poi-ooxml/src/test/java/org/apache/poi/openxml4j/opc/TestPackage.java Vedi File

@@ -284,7 +284,7 @@ public final class TestPackage {
assertEquals(1, rels.size());
PackageRelationship rel = rels.getRelationship(0);
assertNotNull(rel);
assertEquals("Sheet1!A1", rel.getTargetURI().getRawFragment());
assertEquals("#Sheet1!A1", rel.getTargetURI().toString());

assertMSCompatibility(pkg);
}

+ 5
- 4
poi-ooxml/src/test/java/org/apache/poi/openxml4j/opc/TestRelationships.java Vedi File

@@ -323,10 +323,11 @@ class TestRelationships {

PackageRelationship rId1 = drawingPart.getRelationship("rId1");
URI parent = drawingPart.getPartName().getURI();
URI rel1 = parent.relativize(rId1.getTargetURI());
URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI());
assertEquals("'Another Sheet'!A1", rel1.getFragment());
assertEquals("'Another Sheet'!A1", rel11.getFragment());
// Hyperlink is not a target of relativize() because it is not resolved based on sourceURI in getTargetURI()
// URI rel1 = parent.relativize(rId1.getTargetURI());
// URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI());
// assertEquals("'Another Sheet'!A1", rel1.getFragment());
// assertEquals("'Another Sheet'!A1", rel11.getFragment());

PackageRelationship rId2 = drawingPart.getRelationship("rId2");
URI rel2 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId2.getTargetURI());

+ 14
- 4
poi-ooxml/src/test/java/org/apache/poi/xslf/TestXSLFBugs.java Vedi File

@@ -53,8 +53,10 @@ import org.apache.commons.io.output.NullPrintStream;
import org.apache.poi.POIDataSamples;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.ooxml.HyperlinkRelationship;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.ReferenceRelationship;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePartName;
@@ -384,23 +386,31 @@ class TestXSLFBugs {

// Check the relations from this
Collection<RelationPart> rels = slide.getRelationParts();
Collection<ReferenceRelationship> referenceRelationships = slide.getReferenceRelationships();

// Should have 6 relations:
// 1 external hyperlink (skipped from list)
// 4 internal hyperlinks
// 1 slide layout
assertEquals(5, rels.size());
assertEquals(1, rels.size());
assertEquals(5, referenceRelationships.size());
int layouts = 0;
int hyperlinks = 0;
int extHyperLinks = 0;
for (RelationPart p : rels) {
if (p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) {
hyperlinks++;
} else if (p.getDocumentPart() instanceof XSLFSlideLayout) {
if (p.getDocumentPart() instanceof XSLFSlideLayout) {
layouts++;
}
}
for (ReferenceRelationship ref : referenceRelationships) {
if (ref instanceof HyperlinkRelationship) {
if (ref.isExternal()) extHyperLinks++;
else hyperlinks++;
}
}
assertEquals(1, layouts);
assertEquals(4, hyperlinks);
assertEquals(1, extHyperLinks);

// Hyperlinks should all be to #_ftn1 or #ftnref1
for (RelationPart p : rels) {

+ 7
- 6
poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java Vedi File

@@ -60,6 +60,7 @@ import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.ReferenceRelationship;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
@@ -234,18 +235,18 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
assertEquals(1, wb1.getNumberOfSheets());
XSSFSheet sh = wb1.getSheetAt(0);
XSSFDrawing drawing = sh.createDrawingPatriarch();
List<RelationPart> rels = drawing.getRelationParts();
assertEquals(1, rels.size());
assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
List<ReferenceRelationship> referenceRelationships = drawing.getReferenceRelationships();
assertEquals(1, referenceRelationships.size());
assertEquals("#Sheet1!A1", referenceRelationships.get(0).getUri().toString());

// And again, just to be sure
try (XSSFWorkbook wb2 = writeOutAndReadBack(wb1)) {
assertEquals(1, wb2.getNumberOfSheets());
sh = wb2.getSheetAt(0);
drawing = sh.createDrawingPatriarch();
rels = drawing.getRelationParts();
assertEquals(1, rels.size());
assertEquals("Sheet1!A1", rels.get(0).getRelationship().getTargetURI().getFragment());
referenceRelationships = drawing.getReferenceRelationships();
assertEquals(1, referenceRelationships.size());
assertEquals("#Sheet1!A1", referenceRelationships.get(0).getUri().toString());
}
}
}

Loading…
Annulla
Salva