git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1843481 13f79535-47bb-0310-9956-ffa450edef68tags/REL_4_0_1
@@ -63,7 +63,7 @@ import org.w3c.dom.events.EventListener; | |||
* This class bundles the configuration options used for the existing | |||
* signature facets. | |||
* Apart of the thread local members (e.g. opc-package) most values will probably be constant, so | |||
* it might be configured centrally (e.g. by spring) | |||
* it might be configured centrally (e.g. by spring) | |||
*/ | |||
@SuppressWarnings({"unused","WeakerAccess"}) | |||
public class SignatureConfig { | |||
@@ -76,14 +76,14 @@ public class SignatureConfig { | |||
public interface SignatureConfigurable { | |||
void setSignatureConfig(SignatureConfig signatureConfig); | |||
void setSignatureConfig(SignatureConfig signatureConfig); | |||
} | |||
private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>(); | |||
private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>(); | |||
private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>(); | |||
private ThreadLocal<Provider> provider = new ThreadLocal<>(); | |||
private List<SignatureFacet> signatureFacets = new ArrayList<>(); | |||
private HashAlgorithm digestAlgo = HashAlgorithm.sha256; | |||
private Date executionTime = new Date(); | |||
@@ -96,11 +96,11 @@ public class SignatureConfig { | |||
private SignaturePolicyService signaturePolicyService; | |||
private URIDereferencer uriDereferencer; | |||
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE; | |||
private boolean includeEntireCertificateChain = true; | |||
private boolean includeIssuerSerial; | |||
private boolean includeKeyValue; | |||
/** | |||
* the time-stamp service used for XAdES-T and XAdES-X. | |||
*/ | |||
@@ -123,7 +123,7 @@ public class SignatureConfig { | |||
private String tspRequestPolicy = "1.3.6.1.4.1.13762.3"; | |||
private String userAgent = "POI XmlSign Service TSP Client"; | |||
private String proxyUrl; | |||
/** | |||
* the optional revocation data service used for XAdES-C and XAdES-X-L. | |||
* When <code>null</code> the signature will be limited to XAdES-T only. | |||
@@ -148,16 +148,16 @@ public class SignatureConfig { | |||
* <code>null</code> value will trigger an automatically generated signature Id. | |||
*/ | |||
private String packageSignatureId = "idPackageSignature"; | |||
/** | |||
* Gives back the human-readable description of what the citizen will be | |||
* signing. The default value is "Office OpenXML Document". | |||
*/ | |||
private String signatureDescription = "Office OpenXML Document"; | |||
/** | |||
* The process of signing includes the marshalling of xml structures. | |||
* This also includes the canonicalization. Currently this leads to problems | |||
* This also includes the canonicalization. Currently this leads to problems | |||
* with certain namespaces, so this EventListener is used to interfere | |||
* with the marshalling process. | |||
*/ | |||
@@ -177,7 +177,7 @@ public class SignatureConfig { | |||
/** | |||
* Inits and checks the config object. | |||
* If not set previously, complex configuration properties also get | |||
* If not set previously, complex configuration properties also get | |||
* created/initialized via this initialization call. | |||
* | |||
* @param onlyValidation if true, only a subset of the properties | |||
@@ -202,7 +202,7 @@ public class SignatureConfig { | |||
namespacePrefixes.put(OO_DIGSIG_NS, "mdssi"); | |||
namespacePrefixes.put(XADES_132_NS, "xd"); | |||
} | |||
if (onlyValidation) { | |||
return; | |||
} | |||
@@ -210,15 +210,15 @@ public class SignatureConfig { | |||
if (signatureMarshalListener == null) { | |||
signatureMarshalListener = new SignatureMarshalListener(); | |||
} | |||
if (signatureMarshalListener instanceof SignatureConfigurable) { | |||
((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this); | |||
} | |||
if (tspService != null) { | |||
tspService.setSignatureConfig(this); | |||
} | |||
if (signatureFacets.isEmpty()) { | |||
addSignatureFacet(new OOXMLSignatureFacet()); | |||
addSignatureFacet(new KeyInfoSignatureFacet()); | |||
@@ -230,14 +230,14 @@ public class SignatureConfig { | |||
sf.setSignatureConfig(this); | |||
} | |||
} | |||
/** | |||
* @param signatureFacet the signature facet is appended to facet list | |||
* @param signatureFacet the signature facet is appended to facet list | |||
*/ | |||
public void addSignatureFacet(SignatureFacet signatureFacet) { | |||
signatureFacets.add(signatureFacet); | |||
} | |||
/** | |||
* @return the list of facets, may be empty when the config object is not initialized | |||
*/ | |||
@@ -265,14 +265,14 @@ public class SignatureConfig { | |||
public void setDigestAlgo(HashAlgorithm digestAlgo) { | |||
this.digestAlgo = digestAlgo; | |||
} | |||
/** | |||
* @return the opc package to be used by this thread, stored as thread-local | |||
*/ | |||
public OPCPackage getOpcPackage() { | |||
return opcPackage.get(); | |||
} | |||
/** | |||
* @param opcPackage the opc package to be handled by this thread, stored as thread-local | |||
*/ | |||
@@ -398,14 +398,14 @@ public class SignatureConfig { | |||
public void setSignatureDescription(String signatureDescription) { | |||
this.signatureDescription = signatureDescription; | |||
} | |||
/** | |||
* @return the default canonicalization method, defaults to INCLUSIVE | |||
*/ | |||
public String getCanonicalizationMethod() { | |||
return canonicalizationMethod; | |||
} | |||
/** | |||
* @param canonicalizationMethod the default canonicalization method | |||
*/ | |||
@@ -459,15 +459,15 @@ public class SignatureConfig { | |||
public void setTspUrl(String tspUrl) { | |||
this.tspUrl = tspUrl; | |||
} | |||
/** | |||
* @return if true, uses timestamp-request/response mimetype, | |||
* if false, timestamp-query/reply mimetype | |||
* if false, timestamp-query/reply mimetype | |||
*/ | |||
public boolean isTspOldProtocol() { | |||
return tspOldProtocol; | |||
} | |||
/** | |||
* @param tspOldProtocol defines the timestamp-protocol mimetype | |||
* @see #isTspOldProtocol | |||
@@ -475,7 +475,7 @@ public class SignatureConfig { | |||
public void setTspOldProtocol(boolean tspOldProtocol) { | |||
this.tspOldProtocol = tspOldProtocol; | |||
} | |||
/** | |||
* @return the hash algorithm to be used for the timestamp entry. | |||
* Defaults to the hash algorithm of the main entry | |||
@@ -483,7 +483,7 @@ public class SignatureConfig { | |||
public HashAlgorithm getTspDigestAlgo() { | |||
return nvl(tspDigestAlgo,digestAlgo); | |||
} | |||
/** | |||
* @param tspDigestAlgo the algorithm to be used for the timestamp entry. | |||
* if <code>null</code>, the hash algorithm of the main entry | |||
@@ -499,7 +499,7 @@ public class SignatureConfig { | |||
public String getProxyUrl() { | |||
return proxyUrl; | |||
} | |||
/** | |||
* @param proxyUrl the proxy url to be used for all communications. | |||
* Currently this affects the timestamp service | |||
@@ -507,56 +507,56 @@ public class SignatureConfig { | |||
public void setProxyUrl(String proxyUrl) { | |||
this.proxyUrl = proxyUrl; | |||
} | |||
/** | |||
* @return the timestamp service. Defaults to {@link TSPTimeStampService} | |||
*/ | |||
public TimeStampService getTspService() { | |||
return tspService; | |||
} | |||
/** | |||
* @param tspService the timestamp service | |||
*/ | |||
public void setTspService(TimeStampService tspService) { | |||
this.tspService = tspService; | |||
} | |||
/** | |||
* @return the user id for the timestamp service - currently only basic authorization is supported | |||
*/ | |||
public String getTspUser() { | |||
return tspUser; | |||
} | |||
/** | |||
* @param tspUser the user id for the timestamp service - currently only basic authorization is supported | |||
*/ | |||
public void setTspUser(String tspUser) { | |||
this.tspUser = tspUser; | |||
} | |||
/** | |||
* @return the password for the timestamp service | |||
*/ | |||
public String getTspPass() { | |||
return tspPass; | |||
} | |||
/** | |||
* @param tspPass the password for the timestamp service | |||
*/ | |||
public void setTspPass(String tspPass) { | |||
this.tspPass = tspPass; | |||
} | |||
/** | |||
* @return the validator for the timestamp service (certificate) | |||
*/ | |||
public TimeStampServiceValidator getTspValidator() { | |||
return tspValidator; | |||
} | |||
/** | |||
* @param tspValidator the validator for the timestamp service (certificate) | |||
*/ | |||
@@ -586,7 +586,7 @@ public class SignatureConfig { | |||
public HashAlgorithm getXadesDigestAlgo() { | |||
return nvl(xadesDigestAlgo,digestAlgo); | |||
} | |||
/** | |||
* @param xadesDigestAlgo hash algorithm used for XAdES. | |||
* When <code>null</code>, defaults to {@link #getDigestAlgo()} | |||
@@ -611,7 +611,7 @@ public class SignatureConfig { | |||
public String getUserAgent() { | |||
return userAgent; | |||
} | |||
/** | |||
* @param userAgent the user agent used for http communication (e.g. to the TSP) | |||
*/ | |||
@@ -626,7 +626,7 @@ public class SignatureConfig { | |||
public String getTspRequestPolicy() { | |||
return tspRequestPolicy; | |||
} | |||
/** | |||
* @param tspRequestPolicy the asn.1 object id for the tsp request policy. | |||
*/ | |||
@@ -636,7 +636,7 @@ public class SignatureConfig { | |||
/** | |||
* @return true, if the whole certificate chain is included in the signature. | |||
* When false, only the signer cert will be included | |||
* When false, only the signer cert will be included | |||
*/ | |||
public boolean isIncludeEntireCertificateChain() { | |||
return includeEntireCertificateChain; | |||
@@ -728,7 +728,7 @@ public class SignatureConfig { | |||
* Make sure the DN is encoded using the same order as present | |||
* within the certificate. This is an Office2010 work-around. | |||
* Should be reverted back. | |||
* | |||
* | |||
* XXX: not correct according to RFC 4514. | |||
* | |||
* @return when true, the issuer DN is used instead of the issuer X500 principal | |||
@@ -744,7 +744,7 @@ public class SignatureConfig { | |||
this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder; | |||
} | |||
/** | |||
* @return the event listener which is active while xml structure for | |||
* the signature is created. | |||
@@ -813,8 +813,8 @@ public class SignatureConfig { | |||
/** | |||
* Converts the digest algorithm - currently only sha* and ripemd160 is supported. | |||
* MS Office only supports sha1, sha256, sha384, sha512. | |||
* | |||
* MS Office only supports sha1, sha256, sha384, sha512. | |||
* | |||
* @param digestAlgo the digest algorithm | |||
* @return the uri for the given digest | |||
*/ | |||
@@ -835,7 +835,7 @@ public class SignatureConfig { | |||
* Converts the digest algorithm ur - currently only sha* and ripemd160 is supported. | |||
* MS Office only supports sha1, sha256, sha384, sha512. | |||
* | |||
* @param digestAlgo the digest algorithm uri | |||
* @param digestMethodUri the digest algorithm uri | |||
* @return the hash algorithm for the given digest | |||
*/ | |||
private static HashAlgorithm getDigestMethodAlgo(String digestMethodUri) { | |||
@@ -895,7 +895,7 @@ public class SignatureConfig { | |||
public void setSignatureFactory(XMLSignatureFactory signatureFactory) { | |||
this.signatureFactory.set(signatureFactory); | |||
} | |||
/** | |||
* @return the xml signature factory (thread-local) | |||
*/ | |||
@@ -914,7 +914,7 @@ public class SignatureConfig { | |||
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) { | |||
this.keyInfoFactory.set(keyInfoFactory); | |||
} | |||
/** | |||
* @return the key factory (thread-local) | |||
*/ | |||
@@ -934,10 +934,10 @@ public class SignatureConfig { | |||
* <li>the Santuario xmlsec provider</li> | |||
* <li>the JDK xmlsec provider</li> | |||
* </ul> | |||
* | |||
* | |||
* For signing the classes are linked against the Santuario xmlsec, so this might | |||
* only work for validation (not tested). | |||
* | |||
* | |||
* @return the xml dsig provider | |||
*/ | |||
public Provider getProvider() { | |||
@@ -948,7 +948,7 @@ public class SignatureConfig { | |||
// Santuario xmlsec | |||
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", | |||
// JDK xmlsec | |||
"org.jcp.xml.dsig.internal.dom.XMLDSigRI" | |||
"org.jcp.xml.dsig.internal.dom.XMLDSigRI" | |||
}; | |||
for (String pn : dsigProviderNames) { | |||
if (pn == null) { | |||
@@ -966,7 +966,7 @@ public class SignatureConfig { | |||
if (prov == null) { | |||
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!"); | |||
} | |||
return prov; | |||
} | |||
@@ -116,13 +116,15 @@ public class XDGFShape extends XDGFSheet { | |||
_parentPage = parentPage; | |||
TextType text = shapeSheet.getText(); | |||
if (text != null) | |||
if (text != null) { | |||
_text = new XDGFText(text, this); | |||
} | |||
if (shapeSheet.isSetShapes()) { | |||
_shapes = new ArrayList<>(); | |||
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray()) | |||
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray()) { | |||
_shapes.add(new XDGFShape(this, shape, parentPage, document)); | |||
} | |||
} | |||
readProperties(); | |||
@@ -130,10 +132,11 @@ public class XDGFShape extends XDGFSheet { | |||
@Override | |||
public String toString() { | |||
if (_parentPage instanceof XDGFMasterContents) | |||
if (_parentPage instanceof XDGFMasterContents) { | |||
return _parentPage + ": <Shape ID=\"" + getID() + "\">"; | |||
else | |||
} else { | |||
return "<Shape ID=\"" + getID() + "\">"; | |||
} | |||
} | |||
protected void readProperties() { | |||
@@ -181,9 +184,10 @@ public class XDGFShape extends XDGFSheet { | |||
if (obj.isSetMaster()) { | |||
_master = pageContents.getMasterById(obj.getMaster()); | |||
if (_master == null) | |||
if (_master == null) { | |||
throw XDGFException.error("refers to non-existant master " | |||
+ obj.getMaster(), this); | |||
} | |||
/* | |||
* If a master has one top-level shape, a shape that inherits from | |||
@@ -209,11 +213,12 @@ public class XDGFShape extends XDGFSheet { | |||
} | |||
} else if (obj.isSetMasterShape()) { | |||
_masterShape = master.getShapeById(obj.getMasterShape()); | |||
if (_masterShape == null) | |||
_masterShape = (master == null) ? null : master.getShapeById(obj.getMasterShape()); | |||
if (_masterShape == null) { | |||
throw XDGFException.error( | |||
"refers to non-existant master shape " | |||
+ obj.getMasterShape(), this); | |||
} | |||
} | |||
@@ -229,21 +234,24 @@ public class XDGFShape extends XDGFSheet { | |||
protected void setupSectionMasters() { | |||
if (_masterShape == null) | |||
if (_masterShape == null) { | |||
return; | |||
} | |||
try { | |||
for (Entry<String, XDGFSection> section : _sections.entrySet()) { | |||
XDGFSection master = _masterShape.getSection(section.getKey()); | |||
if (master != null) | |||
if (master != null) { | |||
section.getValue().setupMaster(master); | |||
} | |||
} | |||
for (Entry<Long, GeometrySection> section : _geometry.entrySet()) { | |||
GeometrySection master = _masterShape.getGeometryByIdx(section | |||
.getKey()); | |||
if (master != null) | |||
if (master != null) { | |||
section.getValue().setupMaster(master); | |||
} | |||
} | |||
} catch (POIXMLException e) { | |||
throw XDGFException.wrap(this.toString(), e); | |||
@@ -266,8 +274,9 @@ public class XDGFShape extends XDGFSheet { | |||
public String getTextAsString() { | |||
XDGFText text = getText(); | |||
if (text == null) | |||
if (text == null) { | |||
return ""; | |||
} | |||
return text.getTextContent(); | |||
} | |||
@@ -294,7 +303,7 @@ public class XDGFShape extends XDGFSheet { | |||
} | |||
/** | |||
* Only available if this shape is a shape group, may be null | |||
* Only available if this shape is a shape group, may be null | |||
*/ | |||
// -> May be null | |||
public List<XDGFShape> getShapes() { | |||
@@ -304,28 +313,32 @@ public class XDGFShape extends XDGFSheet { | |||
// unique to this shape on the page? | |||
public String getName() { | |||
String name = getXmlObject().getName(); | |||
if (name == null) | |||
if (name == null) { | |||
return ""; | |||
} | |||
return name; | |||
} | |||
// unique to this shape on the page? | |||
public String getShapeType() { | |||
String type = getXmlObject().getType(); | |||
if (type == null) | |||
if (type == null) { | |||
return ""; | |||
} | |||
return type; | |||
} | |||
// name of the symbol that this was derived from | |||
public String getSymbolName() { | |||
if (_master == null) | |||
if (_master == null) { | |||
return ""; | |||
} | |||
String name = _master.getName(); | |||
if (name == null) | |||
if (name == null) { | |||
return ""; | |||
} | |||
return name; | |||
} | |||
@@ -345,8 +358,9 @@ public class XDGFShape extends XDGFSheet { | |||
XDGFShape top = null; | |||
if (_parent != null) { | |||
top = _parent.getTopmostParentShape(); | |||
if (top == null) | |||
if (top == null) { | |||
top = _parent; | |||
} | |||
} | |||
return top; | |||
@@ -381,190 +395,223 @@ public class XDGFShape extends XDGFSheet { | |||
} | |||
public XDGFText getText() { | |||
if (_text == null && _masterShape != null) | |||
if (_text == null && _masterShape != null) { | |||
return _masterShape.getText(); | |||
} | |||
return _text; | |||
} | |||
public Double getPinX() { | |||
if (_pinX == null && _masterShape != null) | |||
if (_pinX == null && _masterShape != null) { | |||
return _masterShape.getPinX(); | |||
} | |||
if (_pinX == null) | |||
if (_pinX == null) { | |||
throw XDGFException.error("PinX not set!", this); | |||
} | |||
return _pinX; | |||
} | |||
public Double getPinY() { | |||
if (_pinY == null && _masterShape != null) | |||
if (_pinY == null && _masterShape != null) { | |||
return _masterShape.getPinY(); | |||
} | |||
if (_pinY == null) | |||
if (_pinY == null) { | |||
throw XDGFException.error("PinY not specified!", this); | |||
} | |||
return _pinY; | |||
} | |||
public Double getWidth() { | |||
if (_width == null && _masterShape != null) | |||
if (_width == null && _masterShape != null) { | |||
return _masterShape.getWidth(); | |||
} | |||
if (_width == null) | |||
if (_width == null) { | |||
throw XDGFException.error("Width not specified!", this); | |||
} | |||
return _width; | |||
} | |||
public Double getHeight() { | |||
if (_height == null && _masterShape != null) | |||
if (_height == null && _masterShape != null) { | |||
return _masterShape.getHeight(); | |||
} | |||
if (_height == null) | |||
if (_height == null) { | |||
throw XDGFException.error("Height not specified!", this); | |||
} | |||
return _height; | |||
} | |||
public Double getLocPinX() { | |||
if (_locPinX == null && _masterShape != null) | |||
if (_locPinX == null && _masterShape != null) { | |||
return _masterShape.getLocPinX(); | |||
} | |||
if (_locPinX == null) | |||
if (_locPinX == null) { | |||
throw XDGFException.error("LocPinX not specified!", this); | |||
} | |||
return _locPinX; | |||
} | |||
public Double getLocPinY() { | |||
if (_locPinY == null && _masterShape != null) | |||
if (_locPinY == null && _masterShape != null) { | |||
return _masterShape.getLocPinY(); | |||
} | |||
if (_locPinY == null) | |||
if (_locPinY == null) { | |||
throw XDGFException.error("LocPinY not specified!", this); | |||
} | |||
return _locPinY; | |||
} | |||
public Double getBeginX() { | |||
if (_beginX == null && _masterShape != null) | |||
if (_beginX == null && _masterShape != null) { | |||
return _masterShape.getBeginX(); | |||
} | |||
return _beginX; | |||
} | |||
public Double getBeginY() { | |||
if (_beginY == null && _masterShape != null) | |||
if (_beginY == null && _masterShape != null) { | |||
return _masterShape.getBeginY(); | |||
} | |||
return _beginY; | |||
} | |||
public Double getEndX() { | |||
if (_endX == null && _masterShape != null) | |||
if (_endX == null && _masterShape != null) { | |||
return _masterShape.getEndX(); | |||
} | |||
return _endX; | |||
} | |||
public Double getEndY() { | |||
if (_endY == null && _masterShape != null) | |||
if (_endY == null && _masterShape != null) { | |||
return _masterShape.getEndY(); | |||
} | |||
return _endY; | |||
} | |||
public Double getAngle() { | |||
if (_angle == null && _masterShape != null) | |||
if (_angle == null && _masterShape != null) { | |||
return _masterShape.getAngle(); | |||
} | |||
return _angle; | |||
} | |||
public Boolean getFlipX() { | |||
if (_flipX == null && _masterShape != null) | |||
if (_flipX == null && _masterShape != null) { | |||
return _masterShape.getFlipX(); | |||
} | |||
return _flipX; | |||
} | |||
public Boolean getFlipY() { | |||
if (_flipY == null && _masterShape != null) | |||
if (_flipY == null && _masterShape != null) { | |||
return _masterShape.getFlipY(); | |||
} | |||
return _flipY; | |||
} | |||
public Double getTxtPinX() { | |||
if (_txtPinX == null && _masterShape != null | |||
&& _masterShape._txtPinX != null) | |||
&& _masterShape._txtPinX != null) { | |||
return _masterShape._txtPinX; | |||
} | |||
if (_txtPinX == null) | |||
if (_txtPinX == null) { | |||
return getWidth() * 0.5; | |||
} | |||
return _txtPinX; | |||
} | |||
public Double getTxtPinY() { | |||
if (_txtLocPinY == null && _masterShape != null | |||
&& _masterShape._txtLocPinY != null) | |||
&& _masterShape._txtLocPinY != null) { | |||
return _masterShape._txtLocPinY; | |||
} | |||
if (_txtPinY == null) | |||
if (_txtPinY == null) { | |||
return getHeight() * 0.5; | |||
} | |||
return _txtPinY; | |||
} | |||
public Double getTxtLocPinX() { | |||
if (_txtLocPinX == null && _masterShape != null | |||
&& _masterShape._txtLocPinX != null) | |||
&& _masterShape._txtLocPinX != null) { | |||
return _masterShape._txtLocPinX; | |||
} | |||
if (_txtLocPinX == null) | |||
if (_txtLocPinX == null) { | |||
return getTxtWidth() * 0.5; | |||
} | |||
return _txtLocPinX; | |||
} | |||
public Double getTxtLocPinY() { | |||
if (_txtLocPinY == null && _masterShape != null | |||
&& _masterShape._txtLocPinY != null) | |||
&& _masterShape._txtLocPinY != null) { | |||
return _masterShape._txtLocPinY; | |||
} | |||
if (_txtLocPinY == null) | |||
if (_txtLocPinY == null) { | |||
return getTxtHeight() * 0.5; | |||
} | |||
return _txtLocPinY; | |||
} | |||
public Double getTxtAngle() { | |||
if (_txtAngle == null && _masterShape != null) | |||
if (_txtAngle == null && _masterShape != null) { | |||
return _masterShape.getTxtAngle(); | |||
} | |||
return _txtAngle; | |||
} | |||
public Double getTxtWidth() { | |||
if (_txtWidth == null && _masterShape != null | |||
&& _masterShape._txtWidth != null) | |||
&& _masterShape._txtWidth != null) { | |||
return _masterShape._txtWidth; | |||
} | |||
if (_txtWidth == null) | |||
if (_txtWidth == null) { | |||
return getWidth(); | |||
} | |||
return _txtWidth; | |||
} | |||
public Double getTxtHeight() { | |||
if (_txtHeight == null && _masterShape != null | |||
&& _masterShape._txtHeight != null) | |||
&& _masterShape._txtHeight != null) { | |||
return _masterShape._txtHeight; | |||
} | |||
if (_txtHeight == null) | |||
if (_txtHeight == null) { | |||
return getHeight(); | |||
} | |||
return _txtHeight; | |||
} | |||
@@ -573,8 +620,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Integer getLineCap() { | |||
Integer lineCap = super.getLineCap(); | |||
if (lineCap != null) | |||
if (lineCap != null) { | |||
return lineCap; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -589,8 +637,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Color getLineColor() { | |||
Color lineColor = super.getLineColor(); | |||
if (lineColor != null) | |||
if (lineColor != null) { | |||
return lineColor; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -605,8 +654,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Integer getLinePattern() { | |||
Integer linePattern = super.getLinePattern(); | |||
if (linePattern != null) | |||
if (linePattern != null) { | |||
return linePattern; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -621,8 +671,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Double getLineWeight() { | |||
Double lineWeight = super.getLineWeight(); | |||
if (lineWeight != null) | |||
if (lineWeight != null) { | |||
return lineWeight; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -637,8 +688,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Color getFontColor() { | |||
Color fontColor = super.getFontColor(); | |||
if (fontColor != null) | |||
if (fontColor != null) { | |||
return fontColor; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -653,8 +705,9 @@ public class XDGFShape extends XDGFSheet { | |||
public Double getFontSize() { | |||
Double fontSize = super.getFontSize(); | |||
if (fontSize != null) | |||
if (fontSize != null) { | |||
return fontSize; | |||
} | |||
// get from master | |||
if (_masterShape != null) { | |||
@@ -791,11 +844,11 @@ public class XDGFShape extends XDGFSheet { | |||
public Rectangle2D.Double getBounds() { | |||
return new Rectangle2D.Double(0, 0, getWidth(), getHeight()); | |||
} | |||
/** | |||
* @return returns bounds as a path in local coordinates, which is | |||
* userful if you need to transform to global coordinates | |||
* | |||
* | |||
* Warning: Don't use this for 1d objects, and will fail for | |||
* infinite line objects | |||
*/ | |||
@@ -819,8 +872,9 @@ public class XDGFShape extends XDGFSheet { | |||
*/ | |||
public Path2D.Double getPath() { | |||
for (GeometrySection geoSection : getGeometrySections()) { | |||
if (geoSection.getNoShow()) | |||
if (geoSection.getNoShow()) { | |||
continue; | |||
} | |||
return geoSection.getPath(this); | |||
} | |||
@@ -833,8 +887,9 @@ public class XDGFShape extends XDGFSheet { | |||
*/ | |||
public boolean hasGeometry() { | |||
for (GeometrySection geoSection : getGeometrySections()) { | |||
if (!geoSection.getNoShow()) | |||
if (!geoSection.getNoShow()) { | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
@@ -889,8 +944,9 @@ public class XDGFShape extends XDGFSheet { | |||
tr.concatenate(getParentTransform()); | |||
try { | |||
if (visitor.accept(this)) | |||
if (visitor.accept(this)) { | |||
visitor.visit(this, tr, level); | |||
} | |||
if (_shapes != null) { | |||
for (XDGFShape shape : _shapes) { | |||
@@ -914,8 +970,9 @@ public class XDGFShape extends XDGFSheet { | |||
public void visitShapes(ShapeVisitor visitor, int level) { | |||
try { | |||
if (visitor.accept(this)) | |||
if (visitor.accept(this)) { | |||
visitor.visit(this, null, level); | |||
} | |||
if (_shapes != null) { | |||
for (XDGFShape shape : _shapes) { |
@@ -52,7 +52,7 @@ public class XDGFText { | |||
// is a mixed type) | |||
return ((TextTypeImpl) _text).getStringValue(); | |||
} | |||
/** | |||
* These are in the shape coordinate system | |||
* | |||
@@ -82,8 +82,8 @@ public class XDGFText { | |||
public Path2D.Double getBoundsAsPath() { | |||
Rectangle2D.Double rect = getTextBounds(); | |||
Double w = rect.getWidth(); | |||
Double h = rect.getHeight(); | |||
double w = rect.getWidth(); | |||
double h = rect.getHeight(); | |||
Path2D.Double bounds = new Path2D.Double(); | |||
bounds.moveTo(0, 0); | |||
@@ -94,7 +94,7 @@ public class XDGFText { | |||
return bounds; | |||
} | |||
/** | |||
* @return Center of text in local coordinates | |||
*/ | |||
@@ -110,8 +110,9 @@ public class XDGFText { | |||
public void draw(Graphics2D graphics) { | |||
String textContent = getTextContent(); | |||
if (textContent.length() == 0) | |||
if (textContent.length() == 0) { | |||
return; | |||
} | |||
Rectangle2D.Double bounds = getTextBounds(); | |||
@@ -140,22 +141,25 @@ public class XDGFText { | |||
} | |||
Double txtAngle = _parent.getTxtAngle(); | |||
if (txtAngle != null && Math.abs(txtAngle) > 0.01) | |||
if (txtAngle != null && Math.abs(txtAngle) > 0.01) { | |||
graphics.rotate(txtAngle); | |||
} | |||
float nextY = 0; | |||
for (String line : lines) { | |||
if (line.length() == 0) | |||
if (line.length() == 0) { | |||
continue; | |||
} | |||
TextLayout layout = new TextLayout(line, font, frc); | |||
if (layout.isLeftToRight()) | |||
if (layout.isLeftToRight()) { | |||
layout.draw(graphics, 0, nextY); | |||
else | |||
} else { | |||
layout.draw(graphics, | |||
(float) (bounds.width - layout.getAdvance()), nextY); | |||
} | |||
nextY += layout.getAscent() + layout.getDescent() | |||
+ layout.getLeading(); |
@@ -22,6 +22,7 @@ import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.io.PrintStream; | |||
import java.io.UnsupportedEncodingException; | |||
@@ -38,17 +39,17 @@ import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor; | |||
public class HierarchyPrinter { | |||
public static void printHierarchy(XDGFPage page, File outDir) | |||
throws FileNotFoundException, UnsupportedEncodingException { | |||
throws FileNotFoundException, UnsupportedEncodingException, IOException { | |||
File pageFile = new File(outDir, "page" + page.getPageNumber() + "-" | |||
+ Util.sanitizeFilename(page.getName()) + ".txt"); | |||
OutputStream os = new FileOutputStream(pageFile); | |||
PrintStream pos = new PrintStream(os, false, "utf-8"); | |||
printHierarchy(page, pos); | |||
pos.close(); | |||
try ( | |||
OutputStream os = new FileOutputStream(pageFile); | |||
PrintStream pos = new PrintStream(os, false, "utf-8") | |||
) { | |||
printHierarchy(page, pos); | |||
} | |||
} | |||
public static void printHierarchy(XDGFPage page, final PrintStream os) { | |||
@@ -71,7 +72,7 @@ public class HierarchyPrinter { | |||
} | |||
public static void printHierarchy(XmlVisioDocument document, | |||
String outDirname) throws FileNotFoundException, UnsupportedEncodingException { | |||
String outDirname) throws FileNotFoundException, UnsupportedEncodingException, IOException { | |||
File outDir = new File(outDirname); | |||
@@ -89,8 +90,9 @@ public class HierarchyPrinter { | |||
String inFilename = args[0]; | |||
String outDir = args[1]; | |||
XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream( | |||
inFilename)); | |||
printHierarchy(doc, outDir); | |||
try (FileInputStream is = new FileInputStream(inFilename)) { | |||
XmlVisioDocument doc = new XmlVisioDocument(is); | |||
printHierarchy(doc, outDir); | |||
} | |||
} | |||
} |
@@ -21,7 +21,10 @@ import java.awt.Color; | |||
import java.awt.Graphics2D; | |||
import java.awt.RenderingHints; | |||
import java.awt.image.BufferedImage; | |||
import java.io.*; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import javax.imageio.ImageIO; | |||
@@ -33,7 +36,7 @@ import org.apache.poi.xdgf.usermodel.shape.ShapeRenderer; | |||
/** | |||
* Converts a Visio diagram to a PNG file. | |||
* | |||
* | |||
* As more elements and styles are added/supported the output will get | |||
* better, but it's very rough right now. | |||
*/ | |||
@@ -91,11 +94,8 @@ public class VsdxToPng { | |||
graphics.dispose(); | |||
OutputStream out = new FileOutputStream(outFile); | |||
try { | |||
try (FileOutputStream out = new FileOutputStream(outFile)) { | |||
ImageIO.write(img, "png", out); | |||
} finally { | |||
out.close(); | |||
} | |||
} | |||
@@ -127,8 +127,9 @@ public class VsdxToPng { | |||
renderer = new ShapeDebuggerRenderer(); | |||
} | |||
XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream( | |||
inFilename)); | |||
renderToPng(doc, pngDir, 2000 / 11.0, renderer); | |||
try (FileInputStream is = new FileInputStream(inFilename)) { | |||
XmlVisioDocument doc = new XmlVisioDocument(is); | |||
renderToPng(doc, pngDir, 2000 / 11.0, renderer); | |||
} | |||
} | |||
} |
@@ -36,6 +36,7 @@ import org.apache.poi.ooxml.POIXMLDocument; | |||
import org.apache.poi.ooxml.POIXMLDocumentPart; | |||
import org.apache.poi.ooxml.POIXMLException; | |||
import org.apache.poi.ooxml.extractor.POIXMLPropertiesTextExtractor; | |||
import org.apache.poi.ooxml.util.PackageHelper; | |||
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; | |||
import org.apache.poi.openxml4j.opc.OPCPackage; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
@@ -50,7 +51,6 @@ import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.ooxml.util.PackageHelper; | |||
import org.apache.poi.util.Units; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.apache.xmlbeans.XmlObject; | |||
@@ -362,7 +362,7 @@ public class XMLSlideShow extends POIXMLDocument | |||
CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId(); | |||
notesMasterId.setId(rp.getRelationship().getId()); | |||
Integer themeIndex = 1; | |||
int themeIndex = 1; | |||
// TODO: check if that list can be replaced by idx = Math.max(idx,themeIdx) | |||
List<Integer> themeIndexList = new ArrayList<>(); | |||
for (POIXMLDocumentPart p : getRelations()) { | |||
@@ -626,7 +626,7 @@ public class XMLSlideShow extends POIXMLDocument | |||
// TODO: implement! | |||
throw new UnsupportedOperationException(); | |||
} | |||
@Override | |||
public POIXMLPropertiesTextExtractor getMetadataTextExtractor() { | |||
return new POIXMLPropertiesTextExtractor(this); |
@@ -48,7 +48,7 @@ import org.w3c.dom.Node; | |||
@Internal | |||
public class XSLFColor { | |||
private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class); | |||
private XmlObject _xmlObject; | |||
private Color _color; | |||
private CTSchemeColor _phClr; | |||
@@ -128,7 +128,7 @@ public class XSLFColor { | |||
} | |||
}; | |||
} | |||
private Color toColor(XmlObject obj, XSLFTheme theme) { | |||
Color color = null; | |||
for (XmlObject ch : obj.selectPath("*")) { | |||
@@ -207,19 +207,19 @@ public class XSLFColor { | |||
if (fill.isSetScrgbClr()) { | |||
fill.unsetScrgbClr(); | |||
} | |||
if (fill.isSetHslClr()) { | |||
fill.unsetHslClr(); | |||
} | |||
if (fill.isSetPrstClr()) { | |||
fill.unsetPrstClr(); | |||
} | |||
if (fill.isSetSchemeClr()) { | |||
fill.unsetSchemeClr(); | |||
} | |||
if (fill.isSetSysClr()) { | |||
fill.unsetSysClr(); | |||
} | |||
@@ -227,12 +227,12 @@ public class XSLFColor { | |||
float[] rgbaf = color.getRGBComponents(null); | |||
boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f); | |||
CTPositiveFixedPercentage alphaPct; | |||
// see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32 | |||
if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) { | |||
// sRGB has a gamma of 2.2 | |||
CTSRgbColor rgb = fill.addNewSrgbClr(); | |||
byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() }; | |||
rgb.setVal(rgbBytes); | |||
alphaPct = (addAlpha) ? rgb.addNewAlpha() : null; | |||
@@ -249,14 +249,14 @@ public class XSLFColor { | |||
alphaPct.setVal((int)(100000 * rgbaf[3])); | |||
} | |||
} | |||
/** | |||
* @return true, if this is an integer color value | |||
*/ | |||
private static boolean isInt(float f) { | |||
return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f; | |||
return Math.abs((f*255d) - Math.rint(f*255d)) < 0.00001; | |||
} | |||
private int getRawValue(String elem) { | |||
String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem; | |||
@@ -281,9 +281,9 @@ public class XSLFColor { | |||
} | |||
} | |||
return -1; | |||
return -1; | |||
} | |||
/** | |||
* Read a perecentage value from the supplied xml bean. | |||
* Example: | |||
@@ -305,7 +305,7 @@ public class XSLFColor { | |||
* or -1 if the value is not set | |||
*/ | |||
int getAlpha(){ | |||
return getPercentageValue("alpha"); | |||
return getPercentageValue("alpha"); | |||
} | |||
/** | |||
@@ -413,7 +413,7 @@ public class XSLFColor { | |||
/** | |||
* specifies the input color with the specific red component, but with the blue and green color | |||
* components unchanged | |||
* | |||
* | |||
* @return the value of the red component specified as a | |||
* percentage with 0% indicating minimal blue and 100% indicating maximum | |||
* or -1 if the value is not set | |||
@@ -479,7 +479,7 @@ public class XSLFColor { | |||
/** | |||
* specifies a darker version of its input color. | |||
* A 10% shade is 10% of the input color combined with 90% black. | |||
* | |||
* | |||
* @return the value of the shade specified as a | |||
* percentage with 0% indicating minimal shade and 100% indicating maximum | |||
* or -1 if the value is not set |
@@ -49,9 +49,7 @@ implements Notes<XSLFShape,XSLFTextParagraph> { | |||
* | |||
* @param part the package part holding the notes data, | |||
* the content type must be <code>application/vnd.openxmlformats-officedocument.notes+xml</code> | |||
* @param rel the package relationship holding this notes, | |||
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/notes | |||
* | |||
* | |||
* @since POI 3.14-Beta1 | |||
*/ | |||
XSLFNotes(PackagePart part) throws IOException, XmlException { | |||
@@ -77,7 +75,7 @@ implements Notes<XSLFShape,XSLFTextParagraph> { | |||
@Override | |||
protected String getRootElementName(){ | |||
return "notes"; | |||
return "notes"; | |||
} | |||
@Override |
@@ -70,7 +70,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||
@Beta | |||
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main"; | |||
private final XmlObject _shape; | |||
private final XSLFSheet _sheet; | |||
private XSLFShapeContainer _parent; | |||
@@ -82,7 +82,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
_shape = shape; | |||
_sheet = sheet; | |||
} | |||
/** | |||
* @return the xml bean holding this shape's data | |||
*/ | |||
@@ -91,11 +91,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
// the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value | |||
return _shape; | |||
} | |||
@Override | |||
public XSLFSheet getSheet() { | |||
return _sheet; | |||
} | |||
@Override | |||
public String getShapeName(){ | |||
return getCNvPr().getName(); | |||
@@ -124,22 +125,24 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this; | |||
ps.setAnchor(sh.getAnchor()); | |||
} | |||
} | |||
public void setParent(XSLFShapeContainer parent) { | |||
this._parent = parent; | |||
} | |||
@Override | |||
public XSLFShapeContainer getParent() { | |||
return this._parent; | |||
} | |||
protected PaintStyle getFillPaint() { | |||
final XSLFTheme theme = getSheet().getTheme(); | |||
final boolean hasPlaceholder = getPlaceholder() != null; | |||
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() { | |||
@Override | |||
public boolean fetch(XSLFShape shape) { | |||
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties()); | |||
if (fp == null) { | |||
@@ -150,7 +153,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
setValue(null); | |||
return true; | |||
} | |||
PackagePart pp = shape.getSheet().getPackagePart(); | |||
PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder); | |||
if (paint != null) { | |||
@@ -167,8 +170,8 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
setValue(paint); | |||
return true; | |||
} | |||
return false; | |||
} | |||
}; | |||
@@ -181,16 +184,16 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
protected CTBackgroundProperties getBgPr() { | |||
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr"); | |||
} | |||
@SuppressWarnings("unused") | |||
protected CTStyleMatrixReference getBgRef() { | |||
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef"); | |||
} | |||
protected CTGroupShapeProperties getGrpSpPr() { | |||
return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr"); | |||
} | |||
protected CTNonVisualDrawingProps getCNvPr() { | |||
if (_nvPr == null) { | |||
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"; | |||
@@ -239,7 +242,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
public Placeholder getPlaceholder() { | |||
return getPlaceholderDetails().getPlaceholder(); | |||
} | |||
/** | |||
* @see PlaceholderDetails#setPlaceholder(Placeholder) | |||
*/ | |||
@@ -268,7 +271,9 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
@SuppressWarnings({"unchecked", "WeakerAccess"}) | |||
protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) { | |||
XmlObject[] rs = getXmlObject().selectPath(xquery); | |||
if (rs.length == 0) return null; | |||
if (rs.length == 0) { | |||
return null; | |||
} | |||
return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null; | |||
} | |||
@@ -281,7 +286,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
* <li>slideLayout | |||
* <li>slideMaster | |||
* </ol> | |||
* | |||
* | |||
* Currently themes and their defaults aren't correctly handled | |||
* | |||
* @param visitor the object that collects the desired property | |||
@@ -299,7 +304,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
return false; | |||
} | |||
MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet(); | |||
// try slide layout | |||
if (sm instanceof XSLFSlideLayout) { | |||
XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm; | |||
@@ -309,7 +314,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
} | |||
sm = slideLayout.getMasterSheet(); | |||
} | |||
// try slide master | |||
if (sm instanceof XSLFSlideMaster) { | |||
XSLFSlideMaster master = (XSLFSlideMaster)sm; | |||
@@ -317,15 +322,15 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
XSLFSimpleShape masterShape = master.getPlaceholderByType(textType); | |||
return masterShape != null && visitor.fetch(masterShape); | |||
} | |||
return false; | |||
} | |||
private static int getPlaceholderType(CTPlaceholder ph) { | |||
if ( !ph.isSetType()) { | |||
return STPlaceholderType.INT_BODY; | |||
} | |||
switch (ph.getType().intValue()) { | |||
case STPlaceholderType.INT_TITLE: | |||
case STPlaceholderType.INT_CTR_TITLE: | |||
@@ -397,7 +402,8 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
@Override | |||
public InputStream getImageData() { | |||
try { | |||
return getPart().getInputStream(); | |||
@@ -406,17 +412,19 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
} | |||
} | |||
@Override | |||
public String getContentType() { | |||
/* TOOD: map content-type */ | |||
return getPart().getContentType(); | |||
} | |||
@Override | |||
public int getAlpha() { | |||
return (blip.sizeOfAlphaModFixArray() > 0) | |||
? blip.getAlphaModFixArray(0).getAmt() | |||
: 100000; | |||
} | |||
}; | |||
}; | |||
} | |||
@SuppressWarnings("WeakerAccess") | |||
@@ -426,14 +434,14 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); | |||
Arrays.sort(gs, (o1, o2) -> { | |||
Integer pos1 = o1.getPos(); | |||
Integer pos2 = o2.getPos(); | |||
return pos1.compareTo(pos2); | |||
int pos1 = o1.getPos(); | |||
int pos2 = o2.getPos(); | |||
return Integer.compare(pos1, pos2); | |||
}); | |||
final ColorStyle cs[] = new ColorStyle[gs.length]; | |||
final float fractions[] = new float[gs.length]; | |||
int i=0; | |||
for (CTGradientStop cgs : gs) { | |||
CTSchemeColor phClrCgs = phClr; | |||
@@ -444,32 +452,37 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
fractions[i] = cgs.getPos() / 100000.f; | |||
i++; | |||
} | |||
return new GradientPaint() { | |||
@Override | |||
public double getGradientAngle() { | |||
return (gradFill.isSetLin()) | |||
? gradFill.getLin().getAng() / 60000.d | |||
: 0; | |||
} | |||
@Override | |||
public ColorStyle[] getGradientColors() { | |||
return cs; | |||
} | |||
@Override | |||
public float[] getGradientFractions() { | |||
return fractions; | |||
} | |||
@Override | |||
public boolean isRotatedWithShape() { | |||
return gradFill.getRotWithShape(); | |||
} | |||
@Override | |||
public GradientType getGradientType() { | |||
if (gradFill.isSetLin()) { | |||
return GradientType.linear; | |||
} | |||
if (gradFill.isSetPath()) { | |||
/* TODO: handle rect path */ | |||
STPathShadeType.Enum ps = gradFill.getPath().getPath(); | |||
@@ -479,16 +492,18 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
return GradientType.shape; | |||
} | |||
} | |||
return GradientType.linear; | |||
} | |||
}; | |||
}; | |||
} | |||
@SuppressWarnings("WeakerAccess") | |||
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) { | |||
if (fillRef == null) return null; | |||
if (fillRef == null) { | |||
return null; | |||
} | |||
// The idx attribute refers to the index of a fill style or | |||
// background fill style within the presentation's style matrix, defined by the fmtScheme element. | |||
// value of 0 or 1000 indicates no background, | |||
@@ -513,7 +528,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject()); | |||
} | |||
cur.dispose(); | |||
CTSchemeColor phClr = fillRef.getSchemeClr(); | |||
PaintStyle res = selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder); | |||
// check for empty placeholder value | |||
@@ -524,12 +539,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { | |||
XSLFColor col = new XSLFColor(fillRef, theme, phClr); | |||
return DrawPaint.createSolidPaint(col.getColorStyle()); | |||
} | |||
@Override | |||
public void draw(Graphics2D graphics, Rectangle2D bounds) { | |||
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); | |||
} | |||
/** | |||
* Return the shape specific (visual) properties | |||
* |
@@ -74,13 +74,13 @@ public class PPTX2PNG { | |||
for (int i = 0; i < args.length; i++) { | |||
if (args[i].startsWith("-")) { | |||
if ("-scale".equals(args[i])) { | |||
scale = Float.parseFloat(args[++i]); | |||
scale = Float.parseFloat(args[++i]); // lgtm[java/index-out-of-bounds] | |||
} else if ("-slide".equals(args[i])) { | |||
slidenumStr = args[++i]; | |||
slidenumStr = args[++i]; // lgtm[java/index-out-of-bounds] | |||
} else if ("-format".equals(args[i])) { | |||
format = args[++i]; | |||
format = args[++i]; // lgtm[java/index-out-of-bounds] | |||
} else if ("-outdir".equals(args[i])) { | |||
outdir = new File(args[++i]); | |||
outdir = new File(args[++i]); // lgtm[java/index-out-of-bounds] | |||
} else if ("-quiet".equals(args[i])) { | |||
quiet = true; | |||
} | |||
@@ -98,11 +98,11 @@ public class PPTX2PNG { | |||
usage("Invalid format given"); | |||
return; | |||
} | |||
if (outdir == null) { | |||
outdir = file.getParentFile(); | |||
} | |||
if (!"null".equals(format) && (outdir == null || !outdir.exists() || !outdir.isDirectory())) { | |||
usage("Output directory doesn't exist"); | |||
return; | |||
@@ -112,7 +112,7 @@ public class PPTX2PNG { | |||
usage("Invalid scale given"); | |||
return; | |||
} | |||
if (!quiet) { | |||
System.out.println("Processing " + file); | |||
} | |||
@@ -169,7 +169,7 @@ public class PPTX2PNG { | |||
System.out.println("Done"); | |||
} | |||
} | |||
private static Set<Integer> slideIndexes(final int slideCount, String range) { | |||
Set<Integer> slideIdx = new TreeSet<>(); | |||
if ("-1".equals(range)) { |
@@ -51,7 +51,7 @@ public class XSSFBUtils { | |||
int numBytes = 2*(int)numChars; | |||
offset += 4; | |||
if (offset+numBytes > data.length) { | |||
throw new XSSFBParseException("trying to read beyond data length:" + | |||
throw new XSSFBParseException("trying to read beyond data length: " + | |||
"offset="+offset+", numBytes="+numBytes+", data.length="+data.length); | |||
} | |||
sb.append(new String(data, offset, numBytes, StandardCharsets.UTF_16LE)); |
@@ -39,22 +39,22 @@ import org.apache.poi.util.NotImplemented; | |||
public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
{ | |||
private static final Boolean UNDEFINED = null; | |||
private final SXSSFSheet _sheet; // parent sheet | |||
private final SortedMap<Integer, SXSSFCell> _cells = new TreeMap<>(); | |||
private short _style = -1; // index of cell style in style table | |||
private short _height = -1; // row height in twips (1/20 point) | |||
private boolean _zHeight; // row zero-height (this is somehow different than being hidden) | |||
private int _outlineLevel; // Outlining level of the row, when outlining is on | |||
// use Boolean to have a tri-state for on/off/undefined | |||
// use Boolean to have a tri-state for on/off/undefined | |||
private Boolean _hidden = UNDEFINED; | |||
private Boolean _collapsed = UNDEFINED; | |||
public SXSSFRow(SXSSFSheet sheet) | |||
{ | |||
_sheet=sheet; | |||
} | |||
public Iterator<Cell> allCellsIterator() | |||
{ | |||
return new CellIterator(); | |||
@@ -71,7 +71,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
void setOutlineLevel(int level){ | |||
_outlineLevel = level; | |||
} | |||
/** | |||
* get row hidden state: Hidden (true), Unhidden (false), Undefined (null) | |||
* | |||
@@ -235,7 +235,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
public SXSSFCell getCell(int cellnum, MissingCellPolicy policy) | |||
{ | |||
checkBounds(cellnum); | |||
final SXSSFCell cell = _cells.get(cellnum); | |||
switch (policy) { | |||
case RETURN_NULL_AND_BLANK: | |||
@@ -345,10 +345,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
@Override | |||
public void setHeightInPoints(float height) | |||
{ | |||
if(height==-1) | |||
if(height==-1) { | |||
_height=-1; | |||
else | |||
} else { | |||
_height=(short)(height*20); | |||
} | |||
} | |||
/** | |||
@@ -375,7 +376,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
{ | |||
return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():_height/20.0); | |||
} | |||
/** | |||
* Is this row formatted? Most aren't, but some rows | |||
* do have whole-row styles. For those that do, you | |||
@@ -392,16 +393,18 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
*/ | |||
@Override | |||
public CellStyle getRowStyle() { | |||
if(!isFormatted()) return null; | |||
if(!isFormatted()) { | |||
return null; | |||
} | |||
return getSheet().getWorkbook().getCellStyleAt(_style); | |||
} | |||
@Internal | |||
/*package*/ int getRowStyleIndex() { | |||
return _style; | |||
} | |||
/** | |||
* Applies a whole-row cell styling to the row. | |||
* The row style can be cleared by passing in <code>null</code>. | |||
@@ -440,7 +443,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
/** | |||
* Create an iterator over the cells from [0, getLastCellNum()). | |||
* Includes blank cells, excludes empty cells | |||
* | |||
* | |||
* Returns an iterator over all filled cells (created via Row.createCell()) | |||
* Throws ConcurrentModificationException if cells are added, moved, or | |||
* removed after the iterator is created. | |||
@@ -485,10 +488,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
@Override | |||
public Cell next() throws NoSuchElementException | |||
{ | |||
if (hasNext()) | |||
if (hasNext()) { | |||
return _cells.get(pos++); | |||
else | |||
} else { | |||
throw new NoSuchElementException(); | |||
} | |||
} | |||
@Override | |||
public void remove() | |||
@@ -496,7 +500,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
throw new UnsupportedOperationException(); | |||
} | |||
} | |||
/** | |||
* Compares two <code>SXSSFRow</code> objects. Two rows are equal if they belong to the same worksheet and | |||
* their row indexes are equal. | |||
@@ -524,9 +528,9 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow> | |||
throw new IllegalArgumentException("The compared rows must belong to the same sheet"); | |||
} | |||
Integer thisRow = this.getRowNum(); | |||
Integer otherRow = other.getRowNum(); | |||
return thisRow.compareTo(otherRow); | |||
int thisRow = this.getRowNum(); | |||
int otherRow = other.getRowNum(); | |||
return Integer.compare(thisRow, otherRow); | |||
} | |||
@Override |
@@ -446,7 +446,7 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSS | |||
XSSFSheet sheet = getSheet(); | |||
XSSFWorkbook wb = sheet.getWorkbook(); | |||
int sheetIndex = wb.getSheetIndex(sheet); | |||
long shapeId = (sheetIndex + 1) * 1024 + newShapeId(); | |||
long shapeId = (sheetIndex + 1L) * 1024 + newShapeId(); | |||
// add reference to OLE part | |||
PackagePartName olePN; |
@@ -22,8 +22,8 @@ import java.util.Iterator; | |||
import java.util.Set; | |||
import java.util.TreeMap; | |||
import org.apache.poi.ss.formula.FormulaShifter; | |||
import org.apache.poi.ss.SpreadsheetVersion; | |||
import org.apache.poi.ss.formula.FormulaShifter; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellCopyPolicy; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
@@ -77,7 +77,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
_cells.put(colI, cell); | |||
sheet.onReadCell(cell); | |||
} | |||
if (! row.isSetR()) { | |||
// Certain file format writers skip the row number | |||
// Assume no gaps, and give this the next row number | |||
@@ -158,9 +158,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
throw new IllegalArgumentException("The compared rows must belong to the same sheet"); | |||
} | |||
Integer thisRow = this.getRowNum(); | |||
Integer otherRow = other.getRowNum(); | |||
return thisRow.compareTo(otherRow); | |||
int thisRow = this.getRowNum(); | |||
int otherRow = other.getRowNum(); | |||
return Integer.compare(thisRow, otherRow); | |||
} | |||
@Override | |||
@@ -245,7 +245,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
*/ | |||
@Override | |||
public XSSFCell getCell(int cellnum, MissingCellPolicy policy) { | |||
if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0"); | |||
if(cellnum < 0) { | |||
throw new IllegalArgumentException("Cell index must be >= 0"); | |||
} | |||
// Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory | |||
final Integer colI = Integer.valueOf(cellnum); // NOSONAR | |||
@@ -332,8 +334,12 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
@Override | |||
public void setHeight(short height) { | |||
if (height == -1) { | |||
if (_row.isSetHt()) _row.unsetHt(); | |||
if (_row.isSetCustomHeight()) _row.unsetCustomHeight(); | |||
if (_row.isSetHt()) { | |||
_row.unsetHt(); | |||
} | |||
if (_row.isSetCustomHeight()) { | |||
_row.unsetCustomHeight(); | |||
} | |||
} else { | |||
_row.setHt((double) height / 20); | |||
_row.setCustomHeight(true); | |||
@@ -425,8 +431,10 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
*/ | |||
@Override | |||
public XSSFCellStyle getRowStyle() { | |||
if(!isFormatted()) return null; | |||
if(!isFormatted()) { | |||
return null; | |||
} | |||
StylesTable stylesSource = getSheet().getWorkbook().getStylesSource(); | |||
if(stylesSource.getNumCellStyles() > 0) { | |||
return stylesSource.getStyleAt((int)_row.getS()); | |||
@@ -434,7 +442,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
return null; | |||
} | |||
} | |||
/** | |||
* Applies a whole-row cell styling to the row. | |||
* If the value is null then the style information is removed, | |||
@@ -449,7 +457,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
} | |||
} else { | |||
StylesTable styleSource = getSheet().getWorkbook().getStylesSource(); | |||
XSSFCellStyle xStyle = (XSSFCellStyle)style; | |||
xStyle.verifyBelongsToStylesSource(styleSource); | |||
@@ -458,7 +466,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
_row.setCustomFormat(true); | |||
} | |||
} | |||
/** | |||
* Remove the Cell from this row. | |||
* | |||
@@ -502,8 +510,8 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
int i = 0; | |||
for (XSSFCell xssfCell : _cells.values()) { | |||
cArray[i] = (CTCell) xssfCell.getCTCell().copy(); | |||
// we have to copy and re-create the XSSFCell here because the | |||
// we have to copy and re-create the XSSFCell here because the | |||
// elements as otherwise setCArray below invalidates all the columns! | |||
// see Bug 56170, XMLBeans seems to always release previous objects | |||
// in the CArray, so we need to provide completely new ones here! | |||
@@ -537,7 +545,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
} | |||
setRowNum(rownum); | |||
} | |||
/** | |||
* Copy the cells from srcRow to this row | |||
* If this row is not a blank row, this will merge the two rows, overwriting | |||
@@ -589,7 +597,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
final int srcRowNum = srcRow.getRowNum(); | |||
final int destRowNum = getRowNum(); | |||
final int rowDifference = destRowNum - srcRowNum; | |||
final FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007); | |||
final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet); | |||
rowShifter.updateRowFormulas(this, formulaShifter); | |||
@@ -617,7 +625,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
public int getOutlineLevel() { | |||
return _row.getOutlineLevel(); | |||
} | |||
/** | |||
* Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the right. | |||
* @param firstShiftColumnIndex the column to start shifting | |||
@@ -626,20 +634,23 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
*/ | |||
@Override | |||
public void shiftCellsRight(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) { | |||
if(step < 0) | |||
if(step < 0) { | |||
throw new IllegalArgumentException("Shifting step may not be negative "); | |||
if(firstShiftColumnIndex > lastShiftColumnIndex) | |||
} | |||
if(firstShiftColumnIndex > lastShiftColumnIndex) { | |||
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), | |||
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex)); | |||
for (int columnIndex = lastShiftColumnIndex; columnIndex >= firstShiftColumnIndex; columnIndex--){ // process cells backwards, because of shifting | |||
} | |||
for (int columnIndex = lastShiftColumnIndex; columnIndex >= firstShiftColumnIndex; columnIndex--){ // process cells backwards, because of shifting | |||
shiftCell(columnIndex, step); | |||
} | |||
for (int columnIndex = firstShiftColumnIndex; columnIndex <= firstShiftColumnIndex+step-1; columnIndex++) | |||
{ | |||
_cells.remove(columnIndex); | |||
XSSFCell targetCell = getCell(columnIndex); | |||
if(targetCell != null) | |||
if(targetCell != null) { | |||
targetCell.getCTCell().set(CTCell.Factory.newInstance()); | |||
} | |||
} | |||
} | |||
/** | |||
@@ -650,27 +661,32 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
*/ | |||
@Override | |||
public void shiftCellsLeft(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) { | |||
if(step < 0) | |||
if(step < 0) { | |||
throw new IllegalArgumentException("Shifting step may not be negative "); | |||
if(firstShiftColumnIndex > lastShiftColumnIndex) | |||
} | |||
if(firstShiftColumnIndex > lastShiftColumnIndex) { | |||
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), | |||
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex)); | |||
if(firstShiftColumnIndex - step < 0) | |||
} | |||
if(firstShiftColumnIndex - step < 0) { | |||
throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(firstShiftColumnIndex + step)).toString()); | |||
for (int columnIndex = firstShiftColumnIndex; columnIndex <= lastShiftColumnIndex; columnIndex++){ | |||
} | |||
for (int columnIndex = firstShiftColumnIndex; columnIndex <= lastShiftColumnIndex; columnIndex++){ | |||
shiftCell(columnIndex, -step); | |||
} | |||
for (int columnIndex = lastShiftColumnIndex-step+1; columnIndex <= lastShiftColumnIndex; columnIndex++){ | |||
_cells.remove(columnIndex); | |||
XSSFCell targetCell = getCell(columnIndex); | |||
if(targetCell != null) | |||
if(targetCell != null) { | |||
targetCell.getCTCell().set(CTCell.Factory.newInstance()); | |||
} | |||
} | |||
} | |||
private void shiftCell(int columnIndex, int step/*pass negative value for left shift*/){ | |||
if(columnIndex + step < 0) // only for shifting left | |||
if(columnIndex + step < 0) { | |||
throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(columnIndex + step)).toString()); | |||
} | |||
XSSFCell currentCell = getCell(columnIndex); | |||
if(currentCell != null){ | |||
currentCell.setCellNum(columnIndex+step); | |||
@@ -679,8 +695,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> { | |||
else { | |||
_cells.remove(columnIndex+step); | |||
XSSFCell targetCell = getCell(columnIndex+step); | |||
if(targetCell != null) | |||
if(targetCell != null) { | |||
targetCell.getCTCell().set(CTCell.Factory.newInstance()); | |||
} | |||
} | |||
} | |||
} |
@@ -40,16 +40,16 @@ public class XWPFSDTContent implements ISDTContent { | |||
// private final IBody part; | |||
// private final XWPFDocument document; | |||
private List<XWPFParagraph> paragraphs = new ArrayList<>(); | |||
private List<XWPFTable> tables = new ArrayList<>(); | |||
private List<XWPFRun> runs = new ArrayList<>(); | |||
private List<XWPFSDT> contentControls = new ArrayList<>(); | |||
// private List<XWPFParagraph> paragraphs = new ArrayList<>(); | |||
// private List<XWPFTable> tables = new ArrayList<>(); | |||
// private List<XWPFRun> runs = new ArrayList<>(); | |||
// private List<XWPFSDT> contentControls = new ArrayList<>(); | |||
private List<ISDTContents> bodyElements = new ArrayList<>(); | |||
public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) { | |||
for (CTR ctr : sdtRun.getRArray()) { | |||
XWPFRun run = new XWPFRun(ctr, parent); | |||
runs.add(run); | |||
// runs.add(run); | |||
bodyElements.add(run); | |||
} | |||
} | |||
@@ -62,24 +62,25 @@ public class XWPFSDTContent implements ISDTContent { | |||
if (o instanceof CTP) { | |||
XWPFParagraph p = new XWPFParagraph((CTP) o, part); | |||
bodyElements.add(p); | |||
paragraphs.add(p); | |||
// paragraphs.add(p); | |||
} else if (o instanceof CTTbl) { | |||
XWPFTable t = new XWPFTable((CTTbl) o, part); | |||
bodyElements.add(t); | |||
tables.add(t); | |||
// tables.add(t); | |||
} else if (o instanceof CTSdtBlock) { | |||
XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part); | |||
bodyElements.add(c); | |||
contentControls.add(c); | |||
// contentControls.add(c); | |||
} else if (o instanceof CTR) { | |||
XWPFRun run = new XWPFRun((CTR) o, parent); | |||
runs.add(run); | |||
// runs.add(run); | |||
bodyElements.add(run); | |||
} | |||
} | |||
cursor.dispose(); | |||
} | |||
@Override | |||
public String getText() { | |||
StringBuilder text = new StringBuilder(); | |||
boolean addNewLine = false; | |||
@@ -130,6 +131,7 @@ public class XWPFSDTContent implements ISDTContent { | |||
} | |||
} | |||
@Override | |||
public String toString() { | |||
return getText(); | |||
} |
@@ -161,8 +161,9 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
this.ctTbl = table; | |||
// is an empty table: I add one row and one column as default | |||
if (table.sizeOfTrArray() == 0) | |||
if (table.sizeOfTrArray() == 0) { | |||
createEmptyTable(table); | |||
} | |||
for (CTRow row : table.getTrList()) { | |||
StringBuilder rowText = new StringBuilder(); | |||
@@ -233,7 +234,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
return text.toString(); | |||
} | |||
/** | |||
* This method has existed since 2008 without an implementation. | |||
* It will be removed unless an implementation is provided. | |||
@@ -288,7 +289,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get the width value as an integer. | |||
* <p>If the width type is AUTO, DXA, or NIL, the value is 20ths of a point. If | |||
* the width type is PCT, the value is the percentage times 50 (e.g., 2500 for 50%).</p> | |||
* the width type is PCT, the value is the percentage times 50 (e.g., 2500 for 50%).</p> | |||
* @return width value as an integer | |||
*/ | |||
public int getWidth() { | |||
@@ -322,7 +323,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
} | |||
/** | |||
* Returns CTTblPr object for table. If force parameter is true, will | |||
* Returns CTTblPr object for table. If force parameter is true, will | |||
* create the element if necessary. If force parameter is false, returns | |||
* null when CTTblPr element is missing. | |||
* | |||
@@ -343,7 +344,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
private CTTblBorders getTblBorders(boolean force) { | |||
CTTblPr tblPr = getTblPr(force); | |||
return tblPr == null ? null | |||
: tblPr.isSetTblBorders() ? tblPr.getTblBorders() | |||
: tblPr.isSetTblBorders() ? tblPr.getTblBorders() | |||
: force ? tblPr.addNewTblBorders() | |||
: null; | |||
} | |||
@@ -413,18 +414,18 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
: tPr.isSetJc() ? TableRowAlign.valueOf(tPr.getJc().getVal().intValue()) | |||
: null; | |||
} | |||
/** | |||
* Set table alignment to specified {@link TableRowAlign} | |||
* | |||
* @param ha {@link TableRowAlign} to set | |||
* @param tra {@link TableRowAlign} to set | |||
*/ | |||
public void setTableAlignment(TableRowAlign tra) { | |||
CTTblPr tPr = getTblPr(true); | |||
CTJc jc = tPr.isSetJc() ? tPr.getJc() : tPr.addNewJc(); | |||
jc.setVal(STJc.Enum.forInt(tra.getValue())); | |||
} | |||
/** | |||
* Removes the table alignment attribute from a table | |||
*/ | |||
@@ -434,7 +435,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
tPr.unsetJc(); | |||
} | |||
} | |||
private void addColumn(XWPFTableRow tabRow, int sizeCol) { | |||
if (sizeCol > 0) { | |||
for (int i = 0; i < sizeCol; i++) { | |||
@@ -486,7 +487,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside horizontal border size | |||
* | |||
* | |||
* @return The width of the Inside Horizontal borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -496,7 +497,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside horizontal border spacing | |||
* | |||
* | |||
* @return The offset to the Inside Horizontal borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -506,7 +507,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside horizontal border color | |||
* | |||
* | |||
* @return The color of the Inside Horizontal borders, null if missing. | |||
*/ | |||
public String getInsideHBorderColor() { | |||
@@ -524,7 +525,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside vertical border size | |||
* | |||
* | |||
* @return The width of the Inside vertical borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -534,7 +535,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside vertical border spacing | |||
* | |||
* | |||
* @return The offset to the Inside vertical borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -544,7 +545,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get inside vertical border color | |||
* | |||
* | |||
* @return The color of the Inside vertical borders, null if missing. | |||
*/ | |||
public String getInsideVBorderColor() { | |||
@@ -562,7 +563,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get top border size | |||
* | |||
* | |||
* @return The width of the top borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -572,7 +573,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get top border spacing | |||
* | |||
* | |||
* @return The offset to the top borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -582,7 +583,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get top border color | |||
* | |||
* | |||
* @return The color of the top borders, null if missing. | |||
*/ | |||
public String getTopBorderColor() { | |||
@@ -600,7 +601,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get bottom border size | |||
* | |||
* | |||
* @return The width of the bottom borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -610,7 +611,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get bottom border spacing | |||
* | |||
* | |||
* @return The offset to the bottom borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -620,7 +621,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get bottom border color | |||
* | |||
* | |||
* @return The color of the bottom borders, null if missing. | |||
*/ | |||
public String getBottomBorderColor() { | |||
@@ -638,7 +639,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Left border size | |||
* | |||
* | |||
* @return The width of the Left borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -648,7 +649,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Left border spacing | |||
* | |||
* | |||
* @return The offset to the Left borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -658,7 +659,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Left border color | |||
* | |||
* | |||
* @return The color of the Left borders, null if missing. | |||
*/ | |||
public String getLeftBorderColor() { | |||
@@ -676,7 +677,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Right border size | |||
* | |||
* | |||
* @return The width of the Right borders in 1/8th points, | |||
* -1 if missing. | |||
*/ | |||
@@ -686,7 +687,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Right border spacing | |||
* | |||
* | |||
* @return The offset to the Right borders in points, | |||
* -1 if missing. | |||
*/ | |||
@@ -696,7 +697,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
/** | |||
* Get Right border color | |||
* | |||
* | |||
* @return The color of the Right borders, null if missing. | |||
*/ | |||
public String getRightBorderColor() { | |||
@@ -770,7 +771,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -786,7 +787,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -802,7 +803,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setTopBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -818,7 +819,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setBottomBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -834,7 +835,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setLeftBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -850,7 +851,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* of a point) and a maximum value of 96 (twelve points). Any values outside this | |||
* range may be reassigned to a more appropriate value. | |||
* @param space - Specifies the spacing offset that shall be used to place this border on the table | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format), | |||
* or auto to allow a consumer to automatically determine the border color as appropriate. | |||
*/ | |||
public void setRightBorder(XWPFBorderType type, int size, int space, String rgbColor) { | |||
@@ -872,14 +873,14 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
public void removeInsideHBorder() { | |||
removeBorder(Border.INSIDE_H); | |||
} | |||
/** | |||
* Remove inside vertical borders for table | |||
*/ | |||
public void removeInsideVBorder() { | |||
removeBorder(Border.INSIDE_V); | |||
} | |||
/** | |||
* Remove top borders for table | |||
*/ | |||
@@ -893,21 +894,21 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
public void removeBottomBorder() { | |||
removeBorder(Border.BOTTOM); | |||
} | |||
/** | |||
* Remove left borders for table | |||
*/ | |||
public void removeLeftBorder() { | |||
removeBorder(Border.LEFT); | |||
} | |||
/** | |||
* Remove right borders for table | |||
*/ | |||
public void removeRightBorder() { | |||
removeBorder(Border.RIGHT); | |||
} | |||
/** | |||
* Remove all borders from table | |||
*/ | |||
@@ -959,7 +960,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
} | |||
/** | |||
* removes the Borders node from Table properties if there are | |||
* removes the Borders node from Table properties if there are | |||
* no border elements | |||
*/ | |||
private void cleanupTblBorders() { | |||
@@ -976,7 +977,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
} | |||
} | |||
} | |||
public int getCellMarginTop() { | |||
return getCellMargin(CTTblCellMar::getTop); | |||
} | |||
@@ -1095,10 +1096,12 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* | |||
* @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType() | |||
*/ | |||
@Override | |||
public BodyElementType getElementType() { | |||
return BodyElementType.TABLE; | |||
} | |||
@Override | |||
public IBody getBody() { | |||
return part; | |||
} | |||
@@ -1108,6 +1111,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* | |||
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() | |||
*/ | |||
@Override | |||
public POIXMLDocumentPart getPart() { | |||
if (part != null) { | |||
return part.getPart(); | |||
@@ -1120,6 +1124,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* | |||
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType() | |||
*/ | |||
@Override | |||
public BodyType getPartType() { | |||
return part.getPartType(); | |||
} | |||
@@ -1130,11 +1135,13 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
*/ | |||
public XWPFTableRow getRow(CTRow row) { | |||
for (int i = 0; i < getRows().size(); i++) { | |||
if (getRows().get(i).getCtRow() == row) return getRow(i); | |||
if (getRows().get(i).getCtRow() == row) { | |||
return getRow(i); | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Get the table width as a decimal value. | |||
* <p>If the width type is DXA or AUTO, then the value will always have | |||
@@ -1159,14 +1166,14 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
protected static double getWidthDecimal(CTTblWidth ctWidth) { | |||
double result = 0.0; | |||
STTblWidth.Enum typeValue = ctWidth.getType(); | |||
if (typeValue == STTblWidth.DXA | |||
|| typeValue == STTblWidth.AUTO | |||
if (typeValue == STTblWidth.DXA | |||
|| typeValue == STTblWidth.AUTO | |||
|| typeValue == STTblWidth.NIL) { | |||
result = 0.0 + ctWidth.getW().intValue(); | |||
} else if (typeValue == STTblWidth.PCT) { | |||
// Percentage values are stored as integers that are 50 times | |||
// percentage. | |||
result = ctWidth.getW().intValue() / 50.0; | |||
result = ctWidth.getW().intValue() / 50.0; | |||
} else { | |||
// Should never get here | |||
} | |||
@@ -1230,7 +1237,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
protected static void setWidthValue(String widthValue, CTTblWidth ctWidth) { | |||
if (!widthValue.matches(REGEX_WIDTH_VALUE)) { | |||
throw new RuntimeException("Table width value \"" + widthValue + "\" " | |||
+ "must match regular expression \"" + REGEX_WIDTH_VALUE + "\"."); | |||
+ "must match regular expression \"" + REGEX_WIDTH_VALUE + "\"."); | |||
} | |||
if (widthValue.matches("auto")) { | |||
ctWidth.setType(STTblWidth.AUTO); | |||
@@ -1240,13 +1247,13 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
} else { | |||
// Must be an integer | |||
ctWidth.setW(new BigInteger(widthValue)); | |||
ctWidth.setType(STTblWidth.DXA); | |||
ctWidth.setType(STTblWidth.DXA); | |||
} | |||
} | |||
/** | |||
* Set the underlying table width value to a percentage value. | |||
* @param ctWidth The CTTblWidth to set the value on | |||
* @param ctWidth The CTTblWidth to set the value on | |||
* @param widthValue String width value in form "33.3%" or an integer that is 50 times desired percentage value (e.g, | |||
* 2500 for 50%) | |||
* @since 4.0.0 | |||
@@ -1257,7 +1264,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
String numberPart = widthValue.substring(0, widthValue.length() - 1); | |||
double percentage = Double.parseDouble(numberPart) * 50; | |||
long intValue = Math.round(percentage); | |||
ctWidth.setW(BigInteger.valueOf(intValue)); | |||
ctWidth.setW(BigInteger.valueOf(intValue)); | |||
} else if (widthValue.matches("[0-9]+")) { | |||
ctWidth.setW(new BigInteger(widthValue)); | |||
} else { | |||
@@ -1275,7 +1282,7 @@ public class XWPFTable implements IBodyElement, ISDTContents { | |||
* @since 4.0.0 | |||
*/ | |||
public void setWidthType(TableWidthType widthType) { | |||
setWidthType(widthType, getTblPr().getTblW()); | |||
setWidthType(widthType, getTblPr().getTblW()); | |||
} | |||
/** |