diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2015-07-19 19:32:41 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2015-07-19 19:32:41 +0000 |
commit | 9abd6a3e344e653343e39a054710d305f9289ab7 (patch) | |
tree | 806b5acd44ce9872b7b8c8fae7530675e68666d8 | |
parent | 89ab6304a47d06a3f16178e6d6c7451474200c8c (diff) | |
parent | 7244be056676a2fad746289641349a7ce7a0e16c (diff) | |
download | poi-9abd6a3e344e653343e39a054710d305f9289ab7.tar.gz poi-9abd6a3e344e653343e39a054710d305f9289ab7.zip |
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
12 files changed, 573 insertions, 81 deletions
diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 85b0580841..784b9baa2e 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -103,12 +103,12 @@ public class TestAllFiles { 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 7b0821dcc0..1a8cbf6a03 100644 --- a/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java +++ b/src/integrationtest/org/apache/poi/stress/POIXMLDocumentHandler.java @@ -20,17 +20,10 @@ import static org.junit.Assert.assertNotNull; 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 @@ public final class POIXMLDocumentHandler { 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 0000000000..4c4fd6088b --- /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 c9d0f174b9..e7974a0922 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 @@ package org.apache.poi.hssf.record; 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord { 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 0000000000..3b58af74e2 --- /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 462027807c..414bf0f4ca 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 final class Threshold { } 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 final class Threshold { } 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 0000000000..6e82072d44 --- /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 a999488d38..a6cdbcfd03 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; 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 @@ public final class HSSFConditionalFormattingRule implements ConditionalFormattin 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 @@ public final class HSSFConditionalFormattingRule implements ConditionalFormattin } 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 @@ public final class HSSFConditionalFormattingRule implements ConditionalFormattin 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 @@ public final class HSSFConditionalFormattingRule implements ConditionalFormattin 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 0e18ee1121..0352d5c874 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -57,6 +57,15 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close 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 f051eb32af..857f0dad23 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -63,7 +63,7 @@ public class POIXMLDocumentPart { 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 @@ public class POIXMLDocumentPart { * 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 @@ public class POIXMLDocumentPart { */ 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 55f4093fb6..2c41b18f73 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.exceptions.InvalidFormatException; 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 final class TestPOIXMLDocument extends TestCase { public OPCParser(OPCPackage pkg) { super(pkg); } + + public OPCParser(OPCPackage pkg, String coreDocumentRel) { + super(pkg, coreDocumentRel); + } @Override public List<PackagePart> getAllEmbedds() { @@ -181,4 +186,33 @@ public final class TestPOIXMLDocument extends TestCase { 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 b8eeb2053d..1a130b7510 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { /**
* 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { assertEquals("B1:B3", ranges2[0].formatAsString());
}
+ @SuppressWarnings("deprecation")
public void testSingleFormulaConditions() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sh = wb.createSheet();
@@ -207,6 +209,7 @@ public abstract class BaseTestConditionalFormatting extends TestCase { assertEquals(ComparisonOperator.NOT_BETWEEN, rule9.getComparisonOperation());
}
+ @SuppressWarnings("deprecation")
public void testCopy() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sheet1 = wb.createSheet();
@@ -546,18 +549,17 @@ public abstract class BaseTestConditionalFormatting extends TestCase { 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { // 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { 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 : 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { 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 @@ public abstract class BaseTestConditionalFormatting extends TestCase { 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();
|