merge trunk to common sl branch
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1691845 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java
index 85b0580..784b9ba 100644
--- a/src/integrationtest/org/apache/poi/TestAllFiles.java
+++ b/src/integrationtest/org/apache/poi/TestAllFiles.java
@@ -103,12 +103,12 @@
HANDLERS.put(".vsd", new HDGFFileHandler());
// Visio - ooxml (currently unsupported)
- HANDLERS.put(".vsdm", new NullFileHandler());
- HANDLERS.put(".vsdx", new NullFileHandler());
- HANDLERS.put(".vssm", new NullFileHandler());
- HANDLERS.put(".vssx", new NullFileHandler());
- HANDLERS.put(".vstm", new NullFileHandler());
- HANDLERS.put(".vstx", new NullFileHandler());
+ HANDLERS.put(".vsdm", new XDGFFileHandler());
+ HANDLERS.put(".vsdx", new XDGFFileHandler());
+ HANDLERS.put(".vssm", new XDGFFileHandler());
+ HANDLERS.put(".vssx", new XDGFFileHandler());
+ HANDLERS.put(".vstm", new XDGFFileHandler());
+ HANDLERS.put(".vstx", new XDGFFileHandler());
// POIFS
HANDLERS.put(".ole2", new POIFSFileHandler());
diff --git a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
index 7b0821d..1a8cbf6 100644
--- a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java
@@ -20,17 +20,10 @@
import java.io.IOException;
import java.io.InputStream;
-import java.util.List;
import org.apache.poi.POIXMLDocument;
-import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
-import org.apache.poi.openxml4j.opc.OPCPackage;
-import org.apache.poi.openxml4j.opc.PackageAccess;
-import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.junit.Ignore;
-import org.junit.Test;
public final class POIXMLDocumentHandler {
protected void handlePOIXMLDocument(POIXMLDocument doc) throws Exception {
@@ -44,33 +37,15 @@
protected static boolean isEncrypted(InputStream stream) throws IOException {
if (POIFSFileSystem.hasPOIFSHeader(stream)) {
POIFSFileSystem poifs = new POIFSFileSystem(stream);
- if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
- return true;
+ try {
+ if (poifs.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
+ return true;
+ }
+ } finally {
+ poifs.close();
}
throw new IOException("wrong file format or file extension for OO XML file");
}
return false;
}
-
- // a test-case to test this locally without executing the full TestAllFiles
- @Ignore("POIXMLDocument cannot handle this Visio file currently...")
- @Test
- public void test() throws Exception {
- OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ);
- try {
- handlePOIXMLDocument(new TestPOIXMLDocument(pkg));
- } finally {
- pkg.close();
- }
- }
-
- private final static class TestPOIXMLDocument extends POIXMLDocument {
- public TestPOIXMLDocument(OPCPackage pkg) {
- super(pkg);
- }
-
- public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
- return null;
- }
- }
}
diff --git a/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java
new file mode 100644
index 0000000..4c4fd60
--- /dev/null
+++ b/src/integrationtest/org/apache/poi/stress/XDGFFileHandler.java
@@ -0,0 +1,75 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+package org.apache.poi.stress;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.openxml4j.opc.PackageAccess;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.util.PackageHelper;
+import org.junit.Test;
+
+public class XDGFFileHandler extends AbstractFileHandler {
+ @Override
+ public void handleFile(InputStream stream) throws Exception {
+ // ignore password protected files
+ if (POIXMLDocumentHandler.isEncrypted(stream)) return;
+
+ TestXDGFXMLDocument doc = new TestXDGFXMLDocument(stream);
+ new POIXMLDocumentHandler().handlePOIXMLDocument(doc);
+ }
+
+ @Override
+ public void handleExtracting(File file) throws Exception {
+ // TODO: extraction/actual operations not supported yet
+ }
+
+ // a test-case to test this locally without executing the full TestAllFiles
+ @Test
+ public void test() throws Exception {
+ OPCPackage pkg = OPCPackage.open("test-data/diagram/test.vsdx", PackageAccess.READ);
+ try {
+ TestXDGFXMLDocument doc = new TestXDGFXMLDocument(pkg);
+ new POIXMLDocumentHandler().handlePOIXMLDocument(doc);
+ } finally {
+ pkg.close();
+ }
+ }
+
+ // TODO: Get rid of this when full visio ooxml support is added
+ private final static class TestXDGFXMLDocument extends POIXMLDocument {
+ public TestXDGFXMLDocument(OPCPackage pkg) {
+ super(pkg, PackageRelationshipTypes.VISIO_CORE_DOCUMENT);
+ }
+
+ public TestXDGFXMLDocument(InputStream is) throws IOException {
+ this(PackageHelper.open(is));
+ }
+
+ public List<PackagePart> getAllEmbedds() throws OpenXML4JException {
+ return new ArrayList<PackagePart>();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/CFRule12Record.java b/src/java/org/apache/poi/hssf/record/CFRule12Record.java
index c9d0f17..e7974a0 100644
--- a/src/java/org/apache/poi/hssf/record/CFRule12Record.java
+++ b/src/java/org/apache/poi/hssf/record/CFRule12Record.java
@@ -19,6 +19,7 @@
import java.util.Arrays;
+import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
import org.apache.poi.hssf.record.cf.Threshold;
import org.apache.poi.hssf.record.common.FtrHeader;
@@ -56,9 +57,9 @@
private byte[] template_params;
private IconMultiStateFormatting multistate;
+ private ColorGradientFormatting color_gradient;
// TODO Parse these
- private byte[] gradient_data;
private byte[] databar_data;
private byte[] filter_data;
@@ -176,7 +177,7 @@
byte type = getConditionType();
if (type == CONDITION_TYPE_COLOR_SCALE) {
- gradient_data = in.readRemainder();
+ color_gradient = new ColorGradientFormatting(in);
} else if (type == CONDITION_TYPE_DATA_BAR) {
databar_data = in.readRemainder();
} else if (type == CONDITION_TYPE_FILTER) {
@@ -201,6 +202,21 @@
return multistate;
}
+ public boolean containsColorGradientBlock() {
+ return (color_gradient != null);
+ }
+ public ColorGradientFormatting getColorGradientFormatting() {
+ return color_gradient;
+ }
+ public ColorGradientFormatting createColorGradientFormatting() {
+ if (color_gradient != null) return color_gradient;
+
+ // Convert, setup and return
+ setConditionType(CONDITION_TYPE_COLOR_SCALE);
+ color_gradient = new ColorGradientFormatting();
+ return color_gradient;
+ }
+
/**
* get the stack of the scale expression as a list
*
@@ -261,7 +277,7 @@
byte type = getConditionType();
if (type == CONDITION_TYPE_COLOR_SCALE) {
- out.write(gradient_data);
+ color_gradient.serialize(out);
} else if (type == CONDITION_TYPE_DATA_BAR) {
out.write(databar_data);
} else if (type == CONDITION_TYPE_FILTER) {
@@ -285,7 +301,7 @@
byte type = getConditionType();
if (type == CONDITION_TYPE_COLOR_SCALE) {
- len += gradient_data.length;
+ len += color_gradient.getDataLength();
} else if (type == CONDITION_TYPE_DATA_BAR) {
len += databar_data.length;
} else if (type == CONDITION_TYPE_FILTER) {
@@ -319,9 +335,11 @@
buffer.append(" .priority =").append(priority).append("\n");
buffer.append(" .template_type =").append(template_type).append("\n");
buffer.append(" .template_params=").append(HexDump.toHex(template_params)).append("\n");
- buffer.append(" .gradient_data =").append(HexDump.toHex(gradient_data)).append("\n");
buffer.append(" .databar_data =").append(HexDump.toHex(databar_data)).append("\n");
buffer.append(" .filter_data =").append(HexDump.toHex(filter_data)).append("\n");
+ if (color_gradient != null) {
+ buffer.append(color_gradient);
+ }
if (multistate != null) {
buffer.append(multistate);
}
diff --git a/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java b/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java
new file mode 100644
index 0000000..3b58af7
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/record/cf/ColorGradientFormatting.java
@@ -0,0 +1,144 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.cf;
+
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Color Gradient / Color Scale Conditional Formatting Rule Record.
+ * (Called Color Gradient in the file format docs, but more commonly
+ * Color Scale in the UI)
+ */
+public final class ColorGradientFormatting implements Cloneable {
+ private static POILogger log = POILogFactory.getLogger(ColorGradientFormatting.class);
+
+ private byte options = 0;
+ private Threshold[] thresholds;
+ private byte[] colors; // TODO Decode
+
+ private static BitField clamp = BitFieldFactory.getInstance(0x01);
+ private static BitField background = BitFieldFactory.getInstance(0x02);
+
+ public ColorGradientFormatting() {
+ options = 3;
+ thresholds = new Threshold[3];
+ }
+ public ColorGradientFormatting(LittleEndianInput in) {
+ in.readShort(); // Ignored
+ in.readByte(); // Reserved
+ int numI = in.readByte();
+ int numG = in.readByte();
+ if (numI != numG) {
+ log.log(POILogger.WARN, "Inconsistent Color Gradient defintion, found " + numI + " vs " + numG + " entries");
+ }
+ options = in.readByte();
+
+ // TODO Are these correct?
+ thresholds = new Threshold[numI];
+ for (int i=0; i<thresholds.length; i++) {
+ thresholds[i] = new Threshold(in);
+ in.readDouble(); // Rather pointless value...
+ }
+ // TODO Decode colors
+ colors = new byte[in.available()];
+ in.readFully(colors);
+ }
+
+ public int getNumControlPoints() {
+ return thresholds.length;
+ }
+ public void setNumControlPoints(int num) {
+ if (num != thresholds.length) {
+ thresholds = new Threshold[num];
+ // TODO Colors
+ }
+ }
+
+ public Threshold[] getThresholds() {
+ return thresholds;
+ }
+ public void setThresholds(Threshold[] thresholds) {
+ this.thresholds = thresholds;
+ }
+
+ // TODO Colors
+
+ public boolean isClampToCurve() {
+ return getOptionFlag(clamp);
+ }
+ public boolean isAppliesToBackground() {
+ return getOptionFlag(background);
+ }
+ private boolean getOptionFlag(BitField field) {
+ int value = field.getValue(options);
+ return value==0 ? false : true;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(" [Color Gradient Formatting]\n");
+ buffer.append(" .clamp = ").append(isClampToCurve()).append("\n");
+ buffer.append(" .background= ").append(isAppliesToBackground()).append("\n");
+ for (Threshold t : thresholds) {
+ buffer.append(t.toString());
+ }
+ buffer.append(" [/Color Gradient Formatting]\n");
+ return buffer.toString();
+ }
+
+ public Object clone() {
+ ColorGradientFormatting rec = new ColorGradientFormatting();
+ rec.options = options;
+ rec.thresholds = new Threshold[thresholds.length];
+ System.arraycopy(thresholds, 0, rec.thresholds, 0, thresholds.length);
+ // TODO Colors
+ return rec;
+ }
+
+ public int getDataLength() {
+ int len = 6;
+ for (Threshold t : thresholds) {
+ len += t.getDataLength();
+ len += 8;
+ }
+ len += colors.length;
+ return len;
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeShort(0);
+ out.writeByte(0);
+ out.writeByte(thresholds.length);
+ out.writeByte(thresholds.length);
+ out.writeByte(options);
+
+ double step = 1d / (thresholds.length-1);
+ for (int i=0; i<thresholds.length; i++) {
+ Threshold t = thresholds[i];
+ t.serialize(out);
+ out.writeDouble(step*i);
+ }
+
+ out.write(colors);
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/record/cf/Threshold.java b/src/java/org/apache/poi/hssf/record/cf/Threshold.java
index 4620278..414bf0f 100644
--- a/src/java/org/apache/poi/hssf/record/cf/Threshold.java
+++ b/src/java/org/apache/poi/hssf/record/cf/Threshold.java
@@ -73,6 +73,14 @@
}
public void setType(byte type) {
this.type = type;
+
+ // Ensure the value presense / absense is consistent for the new type
+ if (type == RangeType.MIN.id || type == RangeType.MAX.id ||
+ type == RangeType.FORMULA.id) {
+ this.value = null;
+ } else if (value == null) {
+ this.value = 0d;
+ }
}
public void setType(int type) {
this.type = (byte)type;
@@ -86,6 +94,9 @@
}
public void setParsedExpression(Ptg[] ptgs) {
formula = Formula.create(ptgs);
+ if (ptgs.length > 0) {
+ this.value = null;
+ }
}
public Double getValue() {
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java
new file mode 100644
index 0000000..6e82072
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFColorScaleFormatting.java
@@ -0,0 +1,75 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.usermodel;
+
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
+import org.apache.poi.hssf.record.cf.Threshold;
+import org.apache.poi.ss.usermodel.Color;
+import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold;
+
+/**
+ * High level representation for Color Scale / Color Gradient
+ * Formatting component of Conditional Formatting settings
+ */
+public final class HSSFColorScaleFormatting implements org.apache.poi.ss.usermodel.ColorScaleFormatting {
+ private final HSSFSheet sheet;
+ private final CFRule12Record cfRule12Record;
+ private final ColorGradientFormatting colorFormatting;
+
+ protected HSSFColorScaleFormatting(CFRule12Record cfRule12Record, HSSFSheet sheet) {
+ this.sheet = sheet;
+ this.cfRule12Record = cfRule12Record;
+ this.colorFormatting = this.cfRule12Record.getColorGradientFormatting();
+ }
+
+ public int getNumControlPoints() {
+ return colorFormatting.getNumControlPoints();
+ }
+ public void setNumControlPoints(int num) {
+ colorFormatting.setNumControlPoints(num);
+ }
+
+ public Color[] getColors() {
+ return null; // TODO
+ }
+ public void setColors(Color[] colors) {
+ // TODO
+ }
+
+ public HSSFConditionalFormattingThreshold[] getThresholds() {
+ Threshold[] t = colorFormatting.getThresholds();
+ HSSFConditionalFormattingThreshold[] ht = new HSSFConditionalFormattingThreshold[t.length];
+ for (int i=0; i<t.length; i++) {
+ ht[i] = new HSSFConditionalFormattingThreshold(t[i], sheet);
+ }
+ return ht;
+ }
+
+ public void setThresholds(ConditionalFormattingThreshold[] thresholds) {
+ Threshold[] t = new Threshold[thresholds.length];
+ for (int i=0; i<t.length; i++) {
+ t[i] = ((HSSFConditionalFormattingThreshold)thresholds[i]).getThreshold();
+ }
+ colorFormatting.setThresholds(t);
+ }
+
+ public HSSFConditionalFormattingThreshold createThreshold() {
+ return new HSSFConditionalFormattingThreshold(new Threshold(), sheet);
+ }
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
index a999488..a6cdbcf 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
@@ -23,6 +23,7 @@
import org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator;
import org.apache.poi.hssf.record.CFRuleRecord;
import org.apache.poi.hssf.record.cf.BorderFormatting;
+import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
import org.apache.poi.hssf.record.cf.FontFormatting;
import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
import org.apache.poi.hssf.record.cf.PatternFormatting;
@@ -55,10 +56,18 @@
cfRuleRecord = pRuleRecord;
}
- CFRuleBase getCfRuleRecord()
- {
+ CFRuleBase getCfRuleRecord() {
return cfRuleRecord;
}
+ private CFRule12Record getCFRule12Record(boolean create) {
+ if (cfRuleRecord instanceof CFRule12Record) {
+ // Good
+ } else {
+ if (create) throw new IllegalArgumentException("Can't convert a CF into a CF12 record");
+ return null;
+ }
+ return (CFRule12Record)cfRuleRecord;
+ }
private HSSFFontFormatting getFontFormatting(boolean create)
{
@@ -171,13 +180,7 @@
}
private HSSFIconMultiStateFormatting getMultiStateFormatting(boolean create) {
- if (cfRuleRecord instanceof CFRule12Record) {
- // Good
- } else {
- if (create) throw new IllegalArgumentException("Can't convert a CF into a CF12 record");
- return null;
- }
- CFRule12Record cfRule12Record = (CFRule12Record)cfRuleRecord;
+ CFRule12Record cfRule12Record = getCFRule12Record(create);
IconMultiStateFormatting iconFormatting = cfRule12Record.getMultiStateFormatting();
if (iconFormatting != null)
{
@@ -193,14 +196,12 @@
return null;
}
}
-
/**
* @return icon / multi-state formatting object if defined, <code>null</code> otherwise
*/
public HSSFIconMultiStateFormatting getMultiStateFormatting() {
return getMultiStateFormatting(false);
}
-
/**
* create a new icon / multi-state formatting object if it does not exist,
* otherwise just return the existing object.
@@ -209,6 +210,37 @@
return getMultiStateFormatting(true);
}
+ private HSSFColorScaleFormatting getColorScaleFormatting(boolean create) {
+ CFRule12Record cfRule12Record = getCFRule12Record(create);
+ ColorGradientFormatting colorFormatting = cfRule12Record.getColorGradientFormatting();
+ if (colorFormatting != null)
+ {
+ return new HSSFColorScaleFormatting(cfRule12Record, sheet);
+ }
+ else if( create )
+ {
+ colorFormatting = cfRule12Record.createColorGradientFormatting();
+ return new HSSFColorScaleFormatting(cfRule12Record, sheet);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ /**
+ * @return color scale / gradient formatting object if defined, <code>null</code> otherwise
+ */
+ public HSSFColorScaleFormatting getColorScaleFormatting() {
+ return getColorScaleFormatting(false);
+ }
+ /**
+ * create a new color scale / gradient formatting object if it does not exist,
+ * otherwise just return the existing object.
+ */
+ public HSSFColorScaleFormatting createColorScaleFormatting() {
+ return getColorScaleFormatting(true);
+ }
+
/**
* @return - the conditiontype for the cfrule
*/
diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java
index 0e18ee1..0352d5c 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java
@@ -57,6 +57,15 @@
protected POIXMLDocument(OPCPackage pkg) {
super(pkg);
+ init(pkg);
+ }
+
+ protected POIXMLDocument(OPCPackage pkg, String coreDocumentRel) {
+ super(pkg, coreDocumentRel);
+ init(pkg);
+ }
+
+ private void init(OPCPackage pkg) {
this.pkg = pkg;
// Workaround for XMLBEANS-512 - ensure that when we parse
diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
index f051eb3..857f0da 100644
--- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
+++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
@@ -63,7 +63,7 @@
DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8");
}
-
+ private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT;
private PackagePart packagePart;
private PackageRelationship packageRel;
private POIXMLDocumentPart parent;
@@ -93,7 +93,16 @@
* Construct POIXMLDocumentPart representing a "core document" package part.
*/
public POIXMLDocumentPart(OPCPackage pkg) {
- PackageRelationship coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT).getRelationship(0);
+ this(pkg, PackageRelationshipTypes.CORE_DOCUMENT);
+ }
+
+ /**
+ * Construct POIXMLDocumentPart representing a custom "core document" package part.
+ */
+ public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) {
+ this.coreDocumentRel = coreDocumentRel;
+ PackageRelationship coreRel = pkg.getRelationshipsByType(this.coreDocumentRel).getRelationship(0);
+
if (coreRel == null) {
coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0);
if (coreRel != null) {
@@ -151,10 +160,10 @@
*/
protected final void rebase(OPCPackage pkg) throws InvalidFormatException {
PackageRelationshipCollection cores =
- packagePart.getRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
+ packagePart.getRelationshipsByType(coreDocumentRel);
if(cores.size() != 1) {
throw new IllegalStateException(
- "Tried to rebase using " + PackageRelationshipTypes.CORE_DOCUMENT +
+ "Tried to rebase using " + coreDocumentRel +
" but found " + cores.size() + " parts of the right type"
);
}
diff --git a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
index 55f4093..2c41b18 100644
--- a/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
+++ b/src/ooxml/testcases/org/apache/poi/TestPOIXMLDocument.java
@@ -31,6 +31,7 @@
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.util.PackageHelper;
import org.apache.poi.util.TempFile;
@@ -44,6 +45,10 @@
public OPCParser(OPCPackage pkg) {
super(pkg);
}
+
+ public OPCParser(OPCPackage pkg, String coreDocumentRel) {
+ super(pkg, coreDocumentRel);
+ }
@Override
public List<PackagePart> getAllEmbedds() {
@@ -181,4 +186,33 @@
part.onDocumentCreate();
//part.getTargetPart(null);
}
+
+ public void testVSDX() throws Exception {
+ OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx"));
+
+ POIXMLDocument part = new OPCParser(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT);
+
+ assertNotNull(part);
+ assertEquals(0, part.getRelationCounter());
+ }
+
+ public void testVSDXPart() throws Exception {
+ OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx"));
+
+ POIXMLDocumentPart part = new POIXMLDocumentPart(open, PackageRelationshipTypes.VISIO_CORE_DOCUMENT);
+
+ assertNotNull(part);
+ assertEquals(0, part.getRelationCounter());
+ }
+
+ public void testInvalidCoreRel() throws Exception {
+ OPCPackage open = PackageHelper.open(POIDataSamples.getDiagramInstance().openResourceAsStream("test.vsdx"));
+
+ try {
+ new POIXMLDocumentPart(open, "somethingillegal");
+ fail("Unknown core ref will throw exception");
+ } catch (POIXMLException e) {
+ // expected here
+ }
+ }
}
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
index b8eeb20..1a130b7 100644
--- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
+++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java
@@ -101,6 +101,7 @@
/**
* Test format conditions based on a boolean formula
*/
+ @SuppressWarnings("deprecation")
public void testBooleanFormulaConditions() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sh = wb.createSheet();
@@ -136,6 +137,7 @@
assertEquals("B1:B3", ranges2[0].formatAsString());
}
+ @SuppressWarnings("deprecation")
public void testSingleFormulaConditions() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sh = wb.createSheet();
@@ -207,6 +209,7 @@
assertEquals(ComparisonOperator.NOT_BETWEEN, rule9.getComparisonOperation());
}
+ @SuppressWarnings("deprecation")
public void testCopy() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sheet1 = wb.createSheet();
@@ -546,18 +549,17 @@
Sheet s = wb.getSheet("CF");
ConditionalFormatting cf = null;
ConditionalFormattingRule cr = null;
- IconMultiStateFormatting icon = null;
- ConditionalFormattingThreshold th = null;
+
// Sanity check data
assertEquals("Values", s.getRow(0).getCell(0).toString());
assertEquals("10.0", s.getRow(2).getCell(0).toString());
- // Check we found all the conditional formattings rules we should have
+ // Check we found all the conditional formatting rules we should have
SheetConditionalFormatting sheetCF = s.getSheetConditionalFormatting();
int numCF = 3;
int numCF12 = 15;
- int numCFEX = 0; // TODO This should be 1, but we don't support CFEX formattings yet
+ int numCFEX = 0; // TODO This should be 2, but we don't support CFEX formattings yet, see #58149
assertEquals(numCF+numCF12+numCFEX, sheetCF.getNumConditionalFormattings());
int fCF = 0, fCF12 = 0, fCFEX = 0;
@@ -646,26 +648,18 @@
// TODO Support Data Bars, then check the rest of this rule
- // Colours R->G - Column F
+ // Colours Red->Yellow->Green - Column F
cf = sheetCF.getConditionalFormattingAt(3);
assertEquals(1, cf.getFormattingRanges().length);
assertEquals("F2:F17", cf.getFormattingRanges()[0].formatAsString());
-
- assertEquals(1, cf.getNumberOfRules());
- cr = cf.getRule(0);
- assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());
- // TODO Support Color Scales, then check the rest of this rule
+ assertColorScale(cf, "F8696B", "FFEB84", "63BE7B");
- // Colours BWR - Column G
+ // Colours Blue->White->Red - Column G
cf = sheetCF.getConditionalFormattingAt(4);
assertEquals(1, cf.getFormattingRanges().length);
assertEquals("G2:G17", cf.getFormattingRanges()[0].formatAsString());
-
- assertEquals(1, cf.getNumberOfRules());
- cr = cf.getRule(0);
- assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());
- // TODO Support Color Scales, then check the rest of this rule
+ assertColorScale(cf, "5A8AC6", "FCFCFF", "F8696B");
// Icons : Default - Column H, percentage thresholds
@@ -696,22 +690,95 @@
assertIconSetPercentages(cf, IconSet.GYRB_4_TRAFFIC_LIGHTS, 0d, 25d, 50d, 75d);
- // Icons : 3 symbols - Column L
- // Icons : 3 flags - Column M
- // Icons : 3 symbols 2 - Column N
- // Icons : 3 arrows - Column O
- // Icons : 5 arrows grey - Column P
- // Icons : 3 stars (ext) - Column Q
- // Icons : 4 ratings - Column R
- // Icons : 5 ratings - Column S
- // Custom Icon+Format - Column T
- // Mixed icons - Column U
+ // Icons : 3 symbols with backgrounds - Column L
+ cf = sheetCF.getConditionalFormattingAt(9);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("L2:L17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GYR_3_SYMBOLS_CIRCLE, 0d, 33d, 67d);
+
+ // Icons : 3 flags - Column M2 Only
+ cf = sheetCF.getConditionalFormattingAt(10);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("M2", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GYR_3_FLAGS, 0d, 33d, 67d);
+
+ // Icons : 3 flags - Column M (all)
+ cf = sheetCF.getConditionalFormattingAt(11);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("M2:M17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GYR_3_FLAGS, 0d, 33d, 67d);
+
+
+ // Icons : 3 symbols 2 (no background) - Column N
+ cf = sheetCF.getConditionalFormattingAt(12);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("N2:N17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GYR_3_SYMBOLS, 0d, 33d, 67d);
+
+
+ // Icons : 3 arrows - Column O
+ cf = sheetCF.getConditionalFormattingAt(13);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("O2:O17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GYR_3_ARROW, 0d, 33d, 67d);
+
+
+ // Icons : 5 arrows grey - Column P
+ cf = sheetCF.getConditionalFormattingAt(14);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("P2:P17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.GREY_5_ARROWS, 0d, 20d, 40d, 60d, 80d);
+
+
+ // Icons : 3 stars (ext) - Column Q
+ // TODO Support EXT formattings
+
+
+ // Icons : 4 ratings - Column R
+ cf = sheetCF.getConditionalFormattingAt(15);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("R2:R17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.RATINGS_4, 0d, 25d, 50d, 75d);
+
+
+ // Icons : 5 ratings - Column S
+ cf = sheetCF.getConditionalFormattingAt(16);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("S2:S17", cf.getFormattingRanges()[0].formatAsString());
+ assertIconSetPercentages(cf, IconSet.RATINGS_5, 0d, 20d, 40d, 60d, 80d);
+
+
+ // Custom Icon+Format - Column T
+ cf = sheetCF.getConditionalFormattingAt(17);
+ assertEquals(1, cf.getFormattingRanges().length);
+ assertEquals("T2:T17", cf.getFormattingRanges()[0].formatAsString());
+
+ // TODO Support IconSet + Other CFs with 2 rules
+// assertEquals(2, cf.getNumberOfRules());
+// cr = cf.getRule(0);
+// assertIconSetPercentages(cr, IconSet.GYR_3_TRAFFIC_LIGHTS_BOX, 0d, 33d, 67d);
+// cr = cf.getRule(1);
+// assertEquals(ConditionType.FORMULA, cr.getConditionTypeType());
+// assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());
+// // TODO Why aren't these two the same between formats?
+// if (cr instanceof HSSFConditionalFormattingRule) {
+// assertEquals("MOD(ROW($T1),2)=1", cr.getFormula1());
+// } else {
+// assertEquals("MOD(ROW($T2),2)=1", cr.getFormula1());
+// }
+// assertEquals(null, cr.getFormula2());
+
+
+ // Mixed icons - Column U
+ // TODO Support EXT formattings
}
private void assertIconSetPercentages(ConditionalFormatting cf, IconSet iconset, Double...vals) {
assertEquals(1, cf.getNumberOfRules());
ConditionalFormattingRule cr = cf.getRule(0);
-
+ assertIconSetPercentages(cr, iconset, vals);
+ }
+ private void assertIconSetPercentages(ConditionalFormattingRule cr, IconSet iconset, Double...vals) {
assertEquals(ConditionType.ICON_SET, cr.getConditionTypeType());
assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());
assertEquals(null, cr.getFormula1());
@@ -733,6 +800,50 @@
assertEquals(null, th.getFormula());
}
}
+
+ private void assertColorScale(ConditionalFormatting cf, String... colors) {
+ assertEquals(1, cf.getNumberOfRules());
+ ConditionalFormattingRule cr = cf.getRule(0);
+ assertColorScale(cr, colors);
+ }
+ private void assertColorScale(ConditionalFormattingRule cr, String... colors) {
+ assertEquals(ConditionType.COLOR_SCALE, cr.getConditionTypeType());
+ assertEquals(ComparisonOperator.NO_COMPARISON, cr.getComparisonOperation());
+ assertEquals(null, cr.getFormula1());
+ assertEquals(null, cr.getFormula2());
+
+ // TODO Implement
+/*
+ ColorScaleFormatting color = cr.getColorScaleFormatting();
+ assertNotNull(color);
+ assertNotNull(color.getColors());
+ assertNotNull(color.getThresholds());
+ assertEquals(colors.length, color.getNumControlPoints());
+ assertEquals(colors.length, color.getColors().length);
+ assertEquals(colors.length, color.getThresholds().length);
+
+ // Thresholds should be Min / (evenly spaced) / Max
+ int steps = 100 / (colors.length-1);
+ for (int i=0; i<colors.length; i++) {
+ ConditionalFormattingThreshold th = color.getThresholds()[i];
+ if (i == 0) {
+ assertEquals(RangeType.MIN, th.getRangeType());
+ } else if (i == colors.length-1) {
+ assertEquals(RangeType.MAX, th.getRangeType());
+ } else {
+ assertEquals(RangeType.PERCENT, th.getRangeType());
+ assertEquals(steps*i, th.getValue());
+ }
+ assertEquals(null, th.getFormula());
+ }
+
+ // Colors should match
+ for (int i=0; i<colors.length; i++) {
+ Color c = color.getColors()[i];
+ assertEquals(colors[i], c.toString());
+ }
+*/
+ }
public void testCreateFontFormatting() {
Workbook workbook = _testDataProvider.createWorkbook();
@@ -907,8 +1018,7 @@
assertEquals(BorderFormatting.BORDER_HAIR, r1fp.getBorderRight());
}
- // TODO Fix this test to work for HSSF
- public void DISABLEDtestCreateIconFormatting() {
+ public void testCreateIconFormatting() {
Workbook workbook = _testDataProvider.createWorkbook();
Sheet sheet = workbook.createSheet();