git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1691845 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_13_FINAL
@@ -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()); |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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>(); | |||
} | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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() { |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
*/ |
@@ -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 |
@@ -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" | |||
); | |||
} |
@@ -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 | |||
} | |||
} | |||
} |
@@ -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(); | |||