Browse Source

fix most alerts reported by LGTM on OOXML

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1843481 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_4_0_1
Alain Béarez 5 years ago
parent
commit
65b7c9e273

+ 50
- 50
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java View File

* This class bundles the configuration options used for the existing * This class bundles the configuration options used for the existing
* signature facets. * signature facets.
* Apart of the thread local members (e.g. opc-package) most values will probably be constant, so * 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"}) @SuppressWarnings({"unused","WeakerAccess"})
public class SignatureConfig { public class SignatureConfig {




public interface SignatureConfigurable { public interface SignatureConfigurable {
void setSignatureConfig(SignatureConfig signatureConfig);
void setSignatureConfig(SignatureConfig signatureConfig);
} }


private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>(); private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>();
private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>(); private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>();
private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>(); private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>();
private ThreadLocal<Provider> provider = new ThreadLocal<>(); private ThreadLocal<Provider> provider = new ThreadLocal<>();
private List<SignatureFacet> signatureFacets = new ArrayList<>(); private List<SignatureFacet> signatureFacets = new ArrayList<>();
private HashAlgorithm digestAlgo = HashAlgorithm.sha256; private HashAlgorithm digestAlgo = HashAlgorithm.sha256;
private Date executionTime = new Date(); private Date executionTime = new Date();
private SignaturePolicyService signaturePolicyService; private SignaturePolicyService signaturePolicyService;
private URIDereferencer uriDereferencer; private URIDereferencer uriDereferencer;
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE; private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;
private boolean includeEntireCertificateChain = true; private boolean includeEntireCertificateChain = true;
private boolean includeIssuerSerial; private boolean includeIssuerSerial;
private boolean includeKeyValue; private boolean includeKeyValue;
/** /**
* the time-stamp service used for XAdES-T and XAdES-X. * the time-stamp service used for XAdES-T and XAdES-X.
*/ */
private String tspRequestPolicy = "1.3.6.1.4.1.13762.3"; private String tspRequestPolicy = "1.3.6.1.4.1.13762.3";
private String userAgent = "POI XmlSign Service TSP Client"; private String userAgent = "POI XmlSign Service TSP Client";
private String proxyUrl; private String proxyUrl;
/** /**
* the optional revocation data service used for XAdES-C and XAdES-X-L. * 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. * When <code>null</code> the signature will be limited to XAdES-T only.
* <code>null</code> value will trigger an automatically generated signature Id. * <code>null</code> value will trigger an automatically generated signature Id.
*/ */
private String packageSignatureId = "idPackageSignature"; private String packageSignatureId = "idPackageSignature";
/** /**
* Gives back the human-readable description of what the citizen will be * Gives back the human-readable description of what the citizen will be
* signing. The default value is "Office OpenXML Document". * signing. The default value is "Office OpenXML Document".
*/ */
private String signatureDescription = "Office OpenXML Document"; private String signatureDescription = "Office OpenXML Document";
/** /**
* The process of signing includes the marshalling of xml structures. * 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 certain namespaces, so this EventListener is used to interfere
* with the marshalling process. * with the marshalling process.
*/ */


/** /**
* Inits and checks the config object. * 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. * created/initialized via this initialization call.
* *
* @param onlyValidation if true, only a subset of the properties * @param onlyValidation if true, only a subset of the properties
namespacePrefixes.put(OO_DIGSIG_NS, "mdssi"); namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");
namespacePrefixes.put(XADES_132_NS, "xd"); namespacePrefixes.put(XADES_132_NS, "xd");
} }
if (onlyValidation) { if (onlyValidation) {
return; return;
} }
if (signatureMarshalListener == null) { if (signatureMarshalListener == null) {
signatureMarshalListener = new SignatureMarshalListener(); signatureMarshalListener = new SignatureMarshalListener();
} }
if (signatureMarshalListener instanceof SignatureConfigurable) { if (signatureMarshalListener instanceof SignatureConfigurable) {
((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this); ((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this);
} }
if (tspService != null) { if (tspService != null) {
tspService.setSignatureConfig(this); tspService.setSignatureConfig(this);
} }
if (signatureFacets.isEmpty()) { if (signatureFacets.isEmpty()) {
addSignatureFacet(new OOXMLSignatureFacet()); addSignatureFacet(new OOXMLSignatureFacet());
addSignatureFacet(new KeyInfoSignatureFacet()); addSignatureFacet(new KeyInfoSignatureFacet());
sf.setSignatureConfig(this); 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) { public void addSignatureFacet(SignatureFacet signatureFacet) {
signatureFacets.add(signatureFacet); signatureFacets.add(signatureFacet);
} }
/** /**
* @return the list of facets, may be empty when the config object is not initialized * @return the list of facets, may be empty when the config object is not initialized
*/ */
public void setDigestAlgo(HashAlgorithm digestAlgo) { public void setDigestAlgo(HashAlgorithm digestAlgo) {
this.digestAlgo = digestAlgo; this.digestAlgo = digestAlgo;
} }
/** /**
* @return the opc package to be used by this thread, stored as thread-local * @return the opc package to be used by this thread, stored as thread-local
*/ */
public OPCPackage getOpcPackage() { public OPCPackage getOpcPackage() {
return opcPackage.get(); return opcPackage.get();
} }
/** /**
* @param opcPackage the opc package to be handled by this thread, stored as thread-local * @param opcPackage the opc package to be handled by this thread, stored as thread-local
*/ */
public void setSignatureDescription(String signatureDescription) { public void setSignatureDescription(String signatureDescription) {
this.signatureDescription = signatureDescription; this.signatureDescription = signatureDescription;
} }
/** /**
* @return the default canonicalization method, defaults to INCLUSIVE * @return the default canonicalization method, defaults to INCLUSIVE
*/ */
public String getCanonicalizationMethod() { public String getCanonicalizationMethod() {
return canonicalizationMethod; return canonicalizationMethod;
} }
/** /**
* @param canonicalizationMethod the default canonicalization method * @param canonicalizationMethod the default canonicalization method
*/ */
public void setTspUrl(String tspUrl) { public void setTspUrl(String tspUrl) {
this.tspUrl = tspUrl; this.tspUrl = tspUrl;
} }
/** /**
* @return if true, uses timestamp-request/response mimetype, * @return if true, uses timestamp-request/response mimetype,
* if false, timestamp-query/reply mimetype
* if false, timestamp-query/reply mimetype
*/ */
public boolean isTspOldProtocol() { public boolean isTspOldProtocol() {
return tspOldProtocol; return tspOldProtocol;
} }
/** /**
* @param tspOldProtocol defines the timestamp-protocol mimetype * @param tspOldProtocol defines the timestamp-protocol mimetype
* @see #isTspOldProtocol * @see #isTspOldProtocol
public void setTspOldProtocol(boolean tspOldProtocol) { public void setTspOldProtocol(boolean tspOldProtocol) {
this.tspOldProtocol = tspOldProtocol; this.tspOldProtocol = tspOldProtocol;
} }
/** /**
* @return the hash algorithm to be used for the timestamp entry. * @return the hash algorithm to be used for the timestamp entry.
* Defaults to the hash algorithm of the main entry * Defaults to the hash algorithm of the main entry
public HashAlgorithm getTspDigestAlgo() { public HashAlgorithm getTspDigestAlgo() {
return nvl(tspDigestAlgo,digestAlgo); return nvl(tspDigestAlgo,digestAlgo);
} }
/** /**
* @param tspDigestAlgo the algorithm to be used for the timestamp entry. * @param tspDigestAlgo the algorithm to be used for the timestamp entry.
* if <code>null</code>, the hash algorithm of the main entry * if <code>null</code>, the hash algorithm of the main entry
public String getProxyUrl() { public String getProxyUrl() {
return proxyUrl; return proxyUrl;
} }
/** /**
* @param proxyUrl the proxy url to be used for all communications. * @param proxyUrl the proxy url to be used for all communications.
* Currently this affects the timestamp service * Currently this affects the timestamp service
public void setProxyUrl(String proxyUrl) { public void setProxyUrl(String proxyUrl) {
this.proxyUrl = proxyUrl; this.proxyUrl = proxyUrl;
} }
/** /**
* @return the timestamp service. Defaults to {@link TSPTimeStampService} * @return the timestamp service. Defaults to {@link TSPTimeStampService}
*/ */
public TimeStampService getTspService() { public TimeStampService getTspService() {
return tspService; return tspService;
} }
/** /**
* @param tspService the timestamp service * @param tspService the timestamp service
*/ */
public void setTspService(TimeStampService tspService) { public void setTspService(TimeStampService tspService) {
this.tspService = tspService; this.tspService = tspService;
} }
/** /**
* @return the user id for the timestamp service - currently only basic authorization is supported * @return the user id for the timestamp service - currently only basic authorization is supported
*/ */
public String getTspUser() { public String getTspUser() {
return tspUser; return tspUser;
} }
/** /**
* @param tspUser the user id for the timestamp service - currently only basic authorization is supported * @param tspUser the user id for the timestamp service - currently only basic authorization is supported
*/ */
public void setTspUser(String tspUser) { public void setTspUser(String tspUser) {
this.tspUser = tspUser; this.tspUser = tspUser;
} }
/** /**
* @return the password for the timestamp service * @return the password for the timestamp service
*/ */
public String getTspPass() { public String getTspPass() {
return tspPass; return tspPass;
} }
/** /**
* @param tspPass the password for the timestamp service * @param tspPass the password for the timestamp service
*/ */
public void setTspPass(String tspPass) { public void setTspPass(String tspPass) {
this.tspPass = tspPass; this.tspPass = tspPass;
} }
/** /**
* @return the validator for the timestamp service (certificate) * @return the validator for the timestamp service (certificate)
*/ */
public TimeStampServiceValidator getTspValidator() { public TimeStampServiceValidator getTspValidator() {
return tspValidator; return tspValidator;
} }
/** /**
* @param tspValidator the validator for the timestamp service (certificate) * @param tspValidator the validator for the timestamp service (certificate)
*/ */
public HashAlgorithm getXadesDigestAlgo() { public HashAlgorithm getXadesDigestAlgo() {
return nvl(xadesDigestAlgo,digestAlgo); return nvl(xadesDigestAlgo,digestAlgo);
} }
/** /**
* @param xadesDigestAlgo hash algorithm used for XAdES. * @param xadesDigestAlgo hash algorithm used for XAdES.
* When <code>null</code>, defaults to {@link #getDigestAlgo()} * When <code>null</code>, defaults to {@link #getDigestAlgo()}
public String getUserAgent() { public String getUserAgent() {
return userAgent; return userAgent;
} }
/** /**
* @param userAgent the user agent used for http communication (e.g. to the TSP) * @param userAgent the user agent used for http communication (e.g. to the TSP)
*/ */
public String getTspRequestPolicy() { public String getTspRequestPolicy() {
return tspRequestPolicy; return tspRequestPolicy;
} }
/** /**
* @param tspRequestPolicy the asn.1 object id for the tsp request policy. * @param tspRequestPolicy the asn.1 object id for the tsp request policy.
*/ */


/** /**
* @return true, if the whole certificate chain is included in the signature. * @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() { public boolean isIncludeEntireCertificateChain() {
return includeEntireCertificateChain; return includeEntireCertificateChain;
* Make sure the DN is encoded using the same order as present * Make sure the DN is encoded using the same order as present
* within the certificate. This is an Office2010 work-around. * within the certificate. This is an Office2010 work-around.
* Should be reverted back. * Should be reverted back.
*
*
* XXX: not correct according to RFC 4514. * XXX: not correct according to RFC 4514.
* *
* @return when true, the issuer DN is used instead of the issuer X500 principal * @return when true, the issuer DN is used instead of the issuer X500 principal
this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder; this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder;
} }


/** /**
* @return the event listener which is active while xml structure for * @return the event listener which is active while xml structure for
* the signature is created. * the signature is created.


/** /**
* Converts the digest algorithm - currently only sha* and ripemd160 is supported. * 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 * @param digestAlgo the digest algorithm
* @return the uri for the given digest * @return the uri for the given digest
*/ */
* Converts the digest algorithm ur - currently only sha* and ripemd160 is supported. * Converts the digest algorithm ur - 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 uri
* @param digestMethodUri the digest algorithm uri
* @return the hash algorithm for the given digest * @return the hash algorithm for the given digest
*/ */
private static HashAlgorithm getDigestMethodAlgo(String digestMethodUri) { private static HashAlgorithm getDigestMethodAlgo(String digestMethodUri) {
public void setSignatureFactory(XMLSignatureFactory signatureFactory) { public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
this.signatureFactory.set(signatureFactory); this.signatureFactory.set(signatureFactory);
} }
/** /**
* @return the xml signature factory (thread-local) * @return the xml signature factory (thread-local)
*/ */
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) { public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
this.keyInfoFactory.set(keyInfoFactory); this.keyInfoFactory.set(keyInfoFactory);
} }
/** /**
* @return the key factory (thread-local) * @return the key factory (thread-local)
*/ */
* <li>the Santuario xmlsec provider</li> * <li>the Santuario xmlsec provider</li>
* <li>the JDK xmlsec provider</li> * <li>the JDK xmlsec provider</li>
* </ul> * </ul>
*
*
* For signing the classes are linked against the Santuario xmlsec, so this might * For signing the classes are linked against the Santuario xmlsec, so this might
* only work for validation (not tested). * only work for validation (not tested).
*
*
* @return the xml dsig provider * @return the xml dsig provider
*/ */
public Provider getProvider() { public Provider getProvider() {
// Santuario xmlsec // Santuario xmlsec
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI", "org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI",
// JDK xmlsec // JDK xmlsec
"org.jcp.xml.dsig.internal.dom.XMLDSigRI"
"org.jcp.xml.dsig.internal.dom.XMLDSigRI"
}; };
for (String pn : dsigProviderNames) { for (String pn : dsigProviderNames) {
if (pn == null) { if (pn == null) {
if (prov == null) { if (prov == null) {
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!"); throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
} }
return prov; return prov;
} }



+ 119
- 62
src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java View File

_parentPage = parentPage; _parentPage = parentPage;


TextType text = shapeSheet.getText(); TextType text = shapeSheet.getText();
if (text != null)
if (text != null) {
_text = new XDGFText(text, this); _text = new XDGFText(text, this);
}


if (shapeSheet.isSetShapes()) { if (shapeSheet.isSetShapes()) {
_shapes = new ArrayList<>(); _shapes = new ArrayList<>();
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray())
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray()) {
_shapes.add(new XDGFShape(this, shape, parentPage, document)); _shapes.add(new XDGFShape(this, shape, parentPage, document));
}
} }


readProperties(); readProperties();


@Override @Override
public String toString() { public String toString() {
if (_parentPage instanceof XDGFMasterContents)
if (_parentPage instanceof XDGFMasterContents) {
return _parentPage + ": <Shape ID=\"" + getID() + "\">"; return _parentPage + ": <Shape ID=\"" + getID() + "\">";
else
} else {
return "<Shape ID=\"" + getID() + "\">"; return "<Shape ID=\"" + getID() + "\">";
}
} }


protected void readProperties() { protected void readProperties() {


if (obj.isSetMaster()) { if (obj.isSetMaster()) {
_master = pageContents.getMasterById(obj.getMaster()); _master = pageContents.getMasterById(obj.getMaster());
if (_master == null)
if (_master == null) {
throw XDGFException.error("refers to non-existant master " throw XDGFException.error("refers to non-existant master "
+ obj.getMaster(), this); + obj.getMaster(), this);
}


/* /*
* If a master has one top-level shape, a shape that inherits from * If a master has one top-level shape, a shape that inherits from
} }


} else if (obj.isSetMasterShape()) { } 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( throw XDGFException.error(
"refers to non-existant master shape " "refers to non-existant master shape "
+ obj.getMasterShape(), this); + obj.getMasterShape(), this);
}


} }




protected void setupSectionMasters() { protected void setupSectionMasters() {


if (_masterShape == null)
if (_masterShape == null) {
return; return;
}


try { try {
for (Entry<String, XDGFSection> section : _sections.entrySet()) { for (Entry<String, XDGFSection> section : _sections.entrySet()) {
XDGFSection master = _masterShape.getSection(section.getKey()); XDGFSection master = _masterShape.getSection(section.getKey());
if (master != null)
if (master != null) {
section.getValue().setupMaster(master); section.getValue().setupMaster(master);
}
} }


for (Entry<Long, GeometrySection> section : _geometry.entrySet()) { for (Entry<Long, GeometrySection> section : _geometry.entrySet()) {
GeometrySection master = _masterShape.getGeometryByIdx(section GeometrySection master = _masterShape.getGeometryByIdx(section
.getKey()); .getKey());
if (master != null)
if (master != null) {
section.getValue().setupMaster(master); section.getValue().setupMaster(master);
}
} }
} catch (POIXMLException e) { } catch (POIXMLException e) {
throw XDGFException.wrap(this.toString(), e); throw XDGFException.wrap(this.toString(), e);


public String getTextAsString() { public String getTextAsString() {
XDGFText text = getText(); XDGFText text = getText();
if (text == null)
if (text == null) {
return ""; return "";
}


return text.getTextContent(); return text.getTextContent();
} }
} }


/** /**
* 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 // -> May be null
public List<XDGFShape> getShapes() { public List<XDGFShape> getShapes() {
// unique to this shape on the page? // unique to this shape on the page?
public String getName() { public String getName() {
String name = getXmlObject().getName(); String name = getXmlObject().getName();
if (name == null)
if (name == null) {
return ""; return "";
}
return name; return name;
} }


// unique to this shape on the page? // unique to this shape on the page?
public String getShapeType() { public String getShapeType() {
String type = getXmlObject().getType(); String type = getXmlObject().getType();
if (type == null)
if (type == null) {
return ""; return "";
}
return type; return type;
} }


// name of the symbol that this was derived from // name of the symbol that this was derived from
public String getSymbolName() { public String getSymbolName() {


if (_master == null)
if (_master == null) {
return ""; return "";
}


String name = _master.getName(); String name = _master.getName();
if (name == null)
if (name == null) {
return ""; return "";
}


return name; return name;
} }
XDGFShape top = null; XDGFShape top = null;
if (_parent != null) { if (_parent != null) {
top = _parent.getTopmostParentShape(); top = _parent.getTopmostParentShape();
if (top == null)
if (top == null) {
top = _parent; top = _parent;
}
} }


return top; return top;
} }


public XDGFText getText() { public XDGFText getText() {
if (_text == null && _masterShape != null)
if (_text == null && _masterShape != null) {
return _masterShape.getText(); return _masterShape.getText();
}


return _text; return _text;
} }


public Double getPinX() { public Double getPinX() {
if (_pinX == null && _masterShape != null)
if (_pinX == null && _masterShape != null) {
return _masterShape.getPinX(); return _masterShape.getPinX();
}


if (_pinX == null)
if (_pinX == null) {
throw XDGFException.error("PinX not set!", this); throw XDGFException.error("PinX not set!", this);
}


return _pinX; return _pinX;
} }


public Double getPinY() { public Double getPinY() {
if (_pinY == null && _masterShape != null)
if (_pinY == null && _masterShape != null) {
return _masterShape.getPinY(); return _masterShape.getPinY();
}


if (_pinY == null)
if (_pinY == null) {
throw XDGFException.error("PinY not specified!", this); throw XDGFException.error("PinY not specified!", this);
}


return _pinY; return _pinY;
} }


public Double getWidth() { public Double getWidth() {
if (_width == null && _masterShape != null)
if (_width == null && _masterShape != null) {
return _masterShape.getWidth(); return _masterShape.getWidth();
}


if (_width == null)
if (_width == null) {
throw XDGFException.error("Width not specified!", this); throw XDGFException.error("Width not specified!", this);
}


return _width; return _width;
} }


public Double getHeight() { public Double getHeight() {
if (_height == null && _masterShape != null)
if (_height == null && _masterShape != null) {
return _masterShape.getHeight(); return _masterShape.getHeight();
}


if (_height == null)
if (_height == null) {
throw XDGFException.error("Height not specified!", this); throw XDGFException.error("Height not specified!", this);
}


return _height; return _height;
} }


public Double getLocPinX() { public Double getLocPinX() {
if (_locPinX == null && _masterShape != null)
if (_locPinX == null && _masterShape != null) {
return _masterShape.getLocPinX(); return _masterShape.getLocPinX();
}


if (_locPinX == null)
if (_locPinX == null) {
throw XDGFException.error("LocPinX not specified!", this); throw XDGFException.error("LocPinX not specified!", this);
}


return _locPinX; return _locPinX;
} }


public Double getLocPinY() { public Double getLocPinY() {
if (_locPinY == null && _masterShape != null)
if (_locPinY == null && _masterShape != null) {
return _masterShape.getLocPinY(); return _masterShape.getLocPinY();
}


if (_locPinY == null)
if (_locPinY == null) {
throw XDGFException.error("LocPinY not specified!", this); throw XDGFException.error("LocPinY not specified!", this);
}


return _locPinY; return _locPinY;
} }


public Double getBeginX() { public Double getBeginX() {
if (_beginX == null && _masterShape != null)
if (_beginX == null && _masterShape != null) {
return _masterShape.getBeginX(); return _masterShape.getBeginX();
}


return _beginX; return _beginX;
} }


public Double getBeginY() { public Double getBeginY() {
if (_beginY == null && _masterShape != null)
if (_beginY == null && _masterShape != null) {
return _masterShape.getBeginY(); return _masterShape.getBeginY();
}


return _beginY; return _beginY;
} }


public Double getEndX() { public Double getEndX() {
if (_endX == null && _masterShape != null)
if (_endX == null && _masterShape != null) {
return _masterShape.getEndX(); return _masterShape.getEndX();
}


return _endX; return _endX;
} }


public Double getEndY() { public Double getEndY() {
if (_endY == null && _masterShape != null)
if (_endY == null && _masterShape != null) {
return _masterShape.getEndY(); return _masterShape.getEndY();
}


return _endY; return _endY;
} }


public Double getAngle() { public Double getAngle() {
if (_angle == null && _masterShape != null)
if (_angle == null && _masterShape != null) {
return _masterShape.getAngle(); return _masterShape.getAngle();
}


return _angle; return _angle;
} }


public Boolean getFlipX() { public Boolean getFlipX() {
if (_flipX == null && _masterShape != null)
if (_flipX == null && _masterShape != null) {
return _masterShape.getFlipX(); return _masterShape.getFlipX();
}


return _flipX; return _flipX;
} }


public Boolean getFlipY() { public Boolean getFlipY() {
if (_flipY == null && _masterShape != null)
if (_flipY == null && _masterShape != null) {
return _masterShape.getFlipY(); return _masterShape.getFlipY();
}


return _flipY; return _flipY;
} }


public Double getTxtPinX() { public Double getTxtPinX() {
if (_txtPinX == null && _masterShape != null if (_txtPinX == null && _masterShape != null
&& _masterShape._txtPinX != null)
&& _masterShape._txtPinX != null) {
return _masterShape._txtPinX; return _masterShape._txtPinX;
}


if (_txtPinX == null)
if (_txtPinX == null) {
return getWidth() * 0.5; return getWidth() * 0.5;
}


return _txtPinX; return _txtPinX;
} }


public Double getTxtPinY() { public Double getTxtPinY() {
if (_txtLocPinY == null && _masterShape != null if (_txtLocPinY == null && _masterShape != null
&& _masterShape._txtLocPinY != null)
&& _masterShape._txtLocPinY != null) {
return _masterShape._txtLocPinY; return _masterShape._txtLocPinY;
}


if (_txtPinY == null)
if (_txtPinY == null) {
return getHeight() * 0.5; return getHeight() * 0.5;
}


return _txtPinY; return _txtPinY;
} }


public Double getTxtLocPinX() { public Double getTxtLocPinX() {
if (_txtLocPinX == null && _masterShape != null if (_txtLocPinX == null && _masterShape != null
&& _masterShape._txtLocPinX != null)
&& _masterShape._txtLocPinX != null) {
return _masterShape._txtLocPinX; return _masterShape._txtLocPinX;
}


if (_txtLocPinX == null)
if (_txtLocPinX == null) {
return getTxtWidth() * 0.5; return getTxtWidth() * 0.5;
}


return _txtLocPinX; return _txtLocPinX;
} }


public Double getTxtLocPinY() { public Double getTxtLocPinY() {
if (_txtLocPinY == null && _masterShape != null if (_txtLocPinY == null && _masterShape != null
&& _masterShape._txtLocPinY != null)
&& _masterShape._txtLocPinY != null) {
return _masterShape._txtLocPinY; return _masterShape._txtLocPinY;
}


if (_txtLocPinY == null)
if (_txtLocPinY == null) {
return getTxtHeight() * 0.5; return getTxtHeight() * 0.5;
}


return _txtLocPinY; return _txtLocPinY;
} }


public Double getTxtAngle() { public Double getTxtAngle() {
if (_txtAngle == null && _masterShape != null)
if (_txtAngle == null && _masterShape != null) {
return _masterShape.getTxtAngle(); return _masterShape.getTxtAngle();
}


return _txtAngle; return _txtAngle;
} }


public Double getTxtWidth() { public Double getTxtWidth() {
if (_txtWidth == null && _masterShape != null if (_txtWidth == null && _masterShape != null
&& _masterShape._txtWidth != null)
&& _masterShape._txtWidth != null) {
return _masterShape._txtWidth; return _masterShape._txtWidth;
}


if (_txtWidth == null)
if (_txtWidth == null) {
return getWidth(); return getWidth();
}


return _txtWidth; return _txtWidth;
} }


public Double getTxtHeight() { public Double getTxtHeight() {
if (_txtHeight == null && _masterShape != null if (_txtHeight == null && _masterShape != null
&& _masterShape._txtHeight != null)
&& _masterShape._txtHeight != null) {
return _masterShape._txtHeight; return _masterShape._txtHeight;
}


if (_txtHeight == null)
if (_txtHeight == null) {
return getHeight(); return getHeight();
}


return _txtHeight; return _txtHeight;
} }
public Integer getLineCap() { public Integer getLineCap() {


Integer lineCap = super.getLineCap(); Integer lineCap = super.getLineCap();
if (lineCap != null)
if (lineCap != null) {
return lineCap; return lineCap;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Color getLineColor() { public Color getLineColor() {


Color lineColor = super.getLineColor(); Color lineColor = super.getLineColor();
if (lineColor != null)
if (lineColor != null) {
return lineColor; return lineColor;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Integer getLinePattern() { public Integer getLinePattern() {


Integer linePattern = super.getLinePattern(); Integer linePattern = super.getLinePattern();
if (linePattern != null)
if (linePattern != null) {
return linePattern; return linePattern;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Double getLineWeight() { public Double getLineWeight() {


Double lineWeight = super.getLineWeight(); Double lineWeight = super.getLineWeight();
if (lineWeight != null)
if (lineWeight != null) {
return lineWeight; return lineWeight;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Color getFontColor() { public Color getFontColor() {


Color fontColor = super.getFontColor(); Color fontColor = super.getFontColor();
if (fontColor != null)
if (fontColor != null) {
return fontColor; return fontColor;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Double getFontSize() { public Double getFontSize() {


Double fontSize = super.getFontSize(); Double fontSize = super.getFontSize();
if (fontSize != null)
if (fontSize != null) {
return fontSize; return fontSize;
}


// get from master // get from master
if (_masterShape != null) { if (_masterShape != null) {
public Rectangle2D.Double getBounds() { public Rectangle2D.Double getBounds() {
return new Rectangle2D.Double(0, 0, getWidth(), getHeight()); return new Rectangle2D.Double(0, 0, getWidth(), getHeight());
} }
/** /**
* @return returns bounds as a path in local coordinates, which is * @return returns bounds as a path in local coordinates, which is
* userful if you need to transform to global coordinates * userful if you need to transform to global coordinates
*
*
* Warning: Don't use this for 1d objects, and will fail for * Warning: Don't use this for 1d objects, and will fail for
* infinite line objects * infinite line objects
*/ */
*/ */
public Path2D.Double getPath() { public Path2D.Double getPath() {
for (GeometrySection geoSection : getGeometrySections()) { for (GeometrySection geoSection : getGeometrySections()) {
if (geoSection.getNoShow())
if (geoSection.getNoShow()) {
continue; continue;
}


return geoSection.getPath(this); return geoSection.getPath(this);
} }
*/ */
public boolean hasGeometry() { public boolean hasGeometry() {
for (GeometrySection geoSection : getGeometrySections()) { for (GeometrySection geoSection : getGeometrySections()) {
if (!geoSection.getNoShow())
if (!geoSection.getNoShow()) {
return true; return true;
}
} }
return false; return false;
} }
tr.concatenate(getParentTransform()); tr.concatenate(getParentTransform());


try { try {
if (visitor.accept(this))
if (visitor.accept(this)) {
visitor.visit(this, tr, level); visitor.visit(this, tr, level);
}


if (_shapes != null) { if (_shapes != null) {
for (XDGFShape shape : _shapes) { for (XDGFShape shape : _shapes) {
public void visitShapes(ShapeVisitor visitor, int level) { public void visitShapes(ShapeVisitor visitor, int level) {


try { try {
if (visitor.accept(this))
if (visitor.accept(this)) {
visitor.visit(this, null, level); visitor.visit(this, null, level);
}


if (_shapes != null) { if (_shapes != null) {
for (XDGFShape shape : _shapes) { for (XDGFShape shape : _shapes) {

+ 13
- 9
src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFText.java View File

// is a mixed type) // is a mixed type)
return ((TextTypeImpl) _text).getStringValue(); return ((TextTypeImpl) _text).getStringValue();
} }
/** /**
* These are in the shape coordinate system * These are in the shape coordinate system
* *
public Path2D.Double getBoundsAsPath() { public Path2D.Double getBoundsAsPath() {


Rectangle2D.Double rect = getTextBounds(); 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(); Path2D.Double bounds = new Path2D.Double();
bounds.moveTo(0, 0); bounds.moveTo(0, 0);


return bounds; return bounds;
} }
/** /**
* @return Center of text in local coordinates * @return Center of text in local coordinates
*/ */
public void draw(Graphics2D graphics) { public void draw(Graphics2D graphics) {


String textContent = getTextContent(); String textContent = getTextContent();
if (textContent.length() == 0)
if (textContent.length() == 0) {
return; return;
}


Rectangle2D.Double bounds = getTextBounds(); Rectangle2D.Double bounds = getTextBounds();


} }


Double txtAngle = _parent.getTxtAngle(); Double txtAngle = _parent.getTxtAngle();
if (txtAngle != null && Math.abs(txtAngle) > 0.01)
if (txtAngle != null && Math.abs(txtAngle) > 0.01) {
graphics.rotate(txtAngle); graphics.rotate(txtAngle);
}


float nextY = 0; float nextY = 0;
for (String line : lines) { for (String line : lines) {


if (line.length() == 0)
if (line.length() == 0) {
continue; continue;
}


TextLayout layout = new TextLayout(line, font, frc); TextLayout layout = new TextLayout(line, font, frc);


if (layout.isLeftToRight())
if (layout.isLeftToRight()) {
layout.draw(graphics, 0, nextY); layout.draw(graphics, 0, nextY);
else
} else {
layout.draw(graphics, layout.draw(graphics,
(float) (bounds.width - layout.getAdvance()), nextY); (float) (bounds.width - layout.getAdvance()), nextY);
}


nextY += layout.getAscent() + layout.getDescent() nextY += layout.getAscent() + layout.getDescent()
+ layout.getLeading(); + layout.getLeading();

+ 13
- 11
src/ooxml/java/org/apache/poi/xdgf/util/HierarchyPrinter.java View File

import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
public class HierarchyPrinter { public class HierarchyPrinter {


public static void printHierarchy(XDGFPage page, File outDir) public static void printHierarchy(XDGFPage page, File outDir)
throws FileNotFoundException, UnsupportedEncodingException {
throws FileNotFoundException, UnsupportedEncodingException, IOException {


File pageFile = new File(outDir, "page" + page.getPageNumber() + "-" File pageFile = new File(outDir, "page" + page.getPageNumber() + "-"
+ Util.sanitizeFilename(page.getName()) + ".txt"); + 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) { public static void printHierarchy(XDGFPage page, final PrintStream os) {
} }


public static void printHierarchy(XmlVisioDocument document, public static void printHierarchy(XmlVisioDocument document,
String outDirname) throws FileNotFoundException, UnsupportedEncodingException {
String outDirname) throws FileNotFoundException, UnsupportedEncodingException, IOException {


File outDir = new File(outDirname); File outDir = new File(outDirname);


String inFilename = args[0]; String inFilename = args[0];
String outDir = args[1]; 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);
}
} }
} }

+ 10
- 9
src/ooxml/java/org/apache/poi/xdgf/util/VsdxToPng.java View File

import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.image.BufferedImage; 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; import javax.imageio.ImageIO;




/** /**
* Converts a Visio diagram to a PNG file. * Converts a Visio diagram to a PNG file.
*
*
* As more elements and styles are added/supported the output will get * As more elements and styles are added/supported the output will get
* better, but it's very rough right now. * better, but it's very rough right now.
*/ */


graphics.dispose(); graphics.dispose();


OutputStream out = new FileOutputStream(outFile);
try {
try (FileOutputStream out = new FileOutputStream(outFile)) {
ImageIO.write(img, "png", out); ImageIO.write(img, "png", out);
} finally {
out.close();
} }
} }


renderer = new ShapeDebuggerRenderer(); 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);
}
} }
} }

+ 3
- 3
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java View File

import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLException; import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.extractor.POIXMLPropertiesTextExtractor; 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.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.util.LittleEndianConsts; import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.PackageHelper;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId(); CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId();
notesMasterId.setId(rp.getRelationship().getId()); 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) // TODO: check if that list can be replaced by idx = Math.max(idx,themeIdx)
List<Integer> themeIndexList = new ArrayList<>(); List<Integer> themeIndexList = new ArrayList<>();
for (POIXMLDocumentPart p : getRelations()) { for (POIXMLDocumentPart p : getRelations()) {
// TODO: implement! // TODO: implement!
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public POIXMLPropertiesTextExtractor getMetadataTextExtractor() { public POIXMLPropertiesTextExtractor getMetadataTextExtractor() {
return new POIXMLPropertiesTextExtractor(this); return new POIXMLPropertiesTextExtractor(this);

+ 16
- 16
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java View File

@Internal @Internal
public class XSLFColor { public class XSLFColor {
private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class); private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class);
private XmlObject _xmlObject; private XmlObject _xmlObject;
private Color _color; private Color _color;
private CTSchemeColor _phClr; private CTSchemeColor _phClr;
} }
}; };
} }
private Color toColor(XmlObject obj, XSLFTheme theme) { private Color toColor(XmlObject obj, XSLFTheme theme) {
Color color = null; Color color = null;
for (XmlObject ch : obj.selectPath("*")) { for (XmlObject ch : obj.selectPath("*")) {
if (fill.isSetScrgbClr()) { if (fill.isSetScrgbClr()) {
fill.unsetScrgbClr(); fill.unsetScrgbClr();
} }
if (fill.isSetHslClr()) { if (fill.isSetHslClr()) {
fill.unsetHslClr(); fill.unsetHslClr();
} }
if (fill.isSetPrstClr()) { if (fill.isSetPrstClr()) {
fill.unsetPrstClr(); fill.unsetPrstClr();
} }
if (fill.isSetSchemeClr()) { if (fill.isSetSchemeClr()) {
fill.unsetSchemeClr(); fill.unsetSchemeClr();
} }
if (fill.isSetSysClr()) { if (fill.isSetSysClr()) {
fill.unsetSysClr(); fill.unsetSysClr();
} }
float[] rgbaf = color.getRGBComponents(null); float[] rgbaf = color.getRGBComponents(null);
boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f); boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f);
CTPositiveFixedPercentage alphaPct; CTPositiveFixedPercentage alphaPct;
// see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32 // 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])) { if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) {
// sRGB has a gamma of 2.2 // sRGB has a gamma of 2.2
CTSRgbColor rgb = fill.addNewSrgbClr(); CTSRgbColor rgb = fill.addNewSrgbClr();
byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() }; byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() };
rgb.setVal(rgbBytes); rgb.setVal(rgbBytes);
alphaPct = (addAlpha) ? rgb.addNewAlpha() : null; alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
alphaPct.setVal((int)(100000 * rgbaf[3])); alphaPct.setVal((int)(100000 * rgbaf[3]));
} }
} }
/** /**
* @return true, if this is an integer color value * @return true, if this is an integer color value
*/ */
private static boolean isInt(float f) { 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) { private int getRawValue(String elem) {
String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem; String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem;


} }
} }


return -1;
return -1;
} }
/** /**
* Read a perecentage value from the supplied xml bean. * Read a perecentage value from the supplied xml bean.
* Example: * Example:
* or -1 if the value is not set * or -1 if the value is not set
*/ */
int getAlpha(){ int getAlpha(){
return getPercentageValue("alpha");
return getPercentageValue("alpha");
} }


/** /**
/** /**
* specifies the input color with the specific red component, but with the blue and green color * specifies the input color with the specific red component, but with the blue and green color
* components unchanged * components unchanged
*
*
* @return the value of the red component specified as a * @return the value of the red component specified as a
* percentage with 0% indicating minimal blue and 100% indicating maximum * percentage with 0% indicating minimal blue and 100% indicating maximum
* or -1 if the value is not set * or -1 if the value is not set
/** /**
* specifies a darker version of its input color. * specifies a darker version of its input color.
* A 10% shade is 10% of the input color combined with 90% black. * A 10% shade is 10% of the input color combined with 90% black.
*
*
* @return the value of the shade specified as a * @return the value of the shade specified as a
* percentage with 0% indicating minimal shade and 100% indicating maximum * percentage with 0% indicating minimal shade and 100% indicating maximum
* or -1 if the value is not set * or -1 if the value is not set

+ 2
- 4
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFNotes.java View File

* *
* @param part the package part holding the notes data, * @param part the package part holding the notes data,
* the content type must be <code>application/vnd.openxmlformats-officedocument.notes+xml</code> * 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 * @since POI 3.14-Beta1
*/ */
XSLFNotes(PackagePart part) throws IOException, XmlException { XSLFNotes(PackagePart part) throws IOException, XmlException {


@Override @Override
protected String getRootElementName(){ protected String getRootElementName(){
return "notes";
return "notes";
} }


@Override @Override

+ 54
- 39
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java View File

@Beta @Beta
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> { public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main"; static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
private final XmlObject _shape; private final XmlObject _shape;
private final XSLFSheet _sheet; private final XSLFSheet _sheet;
private XSLFShapeContainer _parent; private XSLFShapeContainer _parent;
_shape = shape; _shape = shape;
_sheet = sheet; _sheet = sheet;
} }
/** /**
* @return the xml bean holding this shape's data * @return the xml bean holding this shape's data
*/ */
// the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value
return _shape; return _shape;
} }

@Override
public XSLFSheet getSheet() { public XSLFSheet getSheet() {
return _sheet; return _sheet;
} }
@Override @Override
public String getShapeName(){ public String getShapeName(){
return getCNvPr().getName(); return getCNvPr().getName();
PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this; PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this;
ps.setAnchor(sh.getAnchor()); ps.setAnchor(sh.getAnchor());
} }
} }
public void setParent(XSLFShapeContainer parent) { public void setParent(XSLFShapeContainer parent) {
this._parent = parent; this._parent = parent;
} }

@Override
public XSLFShapeContainer getParent() { public XSLFShapeContainer getParent() {
return this._parent; return this._parent;
} }
protected PaintStyle getFillPaint() { protected PaintStyle getFillPaint() {
final XSLFTheme theme = getSheet().getTheme(); final XSLFTheme theme = getSheet().getTheme();
final boolean hasPlaceholder = getPlaceholder() != null; final boolean hasPlaceholder = getPlaceholder() != null;
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() { PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
@Override
public boolean fetch(XSLFShape shape) { public boolean fetch(XSLFShape shape) {
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties()); XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
if (fp == null) { if (fp == null) {
setValue(null); setValue(null);
return true; return true;
} }
PackagePart pp = shape.getSheet().getPackagePart(); PackagePart pp = shape.getSheet().getPackagePart();
PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder); PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
if (paint != null) { if (paint != null) {
setValue(paint); setValue(paint);
return true; return true;
} }
return false; return false;
} }
}; };
protected CTBackgroundProperties getBgPr() { protected CTBackgroundProperties getBgPr() {
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr"); return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected CTStyleMatrixReference getBgRef() { protected CTStyleMatrixReference getBgRef() {
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef"); return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
} }
protected CTGroupShapeProperties getGrpSpPr() { protected CTGroupShapeProperties getGrpSpPr() {
return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr"); return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
} }
protected CTNonVisualDrawingProps getCNvPr() { protected CTNonVisualDrawingProps getCNvPr() {
if (_nvPr == null) { if (_nvPr == null) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"; String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";
public Placeholder getPlaceholder() { public Placeholder getPlaceholder() {
return getPlaceholderDetails().getPlaceholder(); return getPlaceholderDetails().getPlaceholder();
} }
/** /**
* @see PlaceholderDetails#setPlaceholder(Placeholder) * @see PlaceholderDetails#setPlaceholder(Placeholder)
*/ */
@SuppressWarnings({"unchecked", "WeakerAccess"}) @SuppressWarnings({"unchecked", "WeakerAccess"})
protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) { protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
XmlObject[] rs = getXmlObject().selectPath(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; return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;
} }


* <li>slideLayout * <li>slideLayout
* <li>slideMaster * <li>slideMaster
* </ol> * </ol>
*
*
* Currently themes and their defaults aren't correctly handled * Currently themes and their defaults aren't correctly handled
* *
* @param visitor the object that collects the desired property * @param visitor the object that collects the desired property
return false; return false;
} }
MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet(); MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet();
// try slide layout // try slide layout
if (sm instanceof XSLFSlideLayout) { if (sm instanceof XSLFSlideLayout) {
XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm; XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm;
} }
sm = slideLayout.getMasterSheet(); sm = slideLayout.getMasterSheet();
} }
// try slide master // try slide master
if (sm instanceof XSLFSlideMaster) { if (sm instanceof XSLFSlideMaster) {
XSLFSlideMaster master = (XSLFSlideMaster)sm; XSLFSlideMaster master = (XSLFSlideMaster)sm;
XSLFSimpleShape masterShape = master.getPlaceholderByType(textType); XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
return masterShape != null && visitor.fetch(masterShape); return masterShape != null && visitor.fetch(masterShape);
} }
return false; return false;
} }
private static int getPlaceholderType(CTPlaceholder ph) { private static int getPlaceholderType(CTPlaceholder ph) {
if ( !ph.isSetType()) { if ( !ph.isSetType()) {
return STPlaceholderType.INT_BODY; return STPlaceholderType.INT_BODY;
} }
switch (ph.getType().intValue()) { switch (ph.getType().intValue()) {
case STPlaceholderType.INT_TITLE: case STPlaceholderType.INT_TITLE:
case STPlaceholderType.INT_CTR_TITLE: case STPlaceholderType.INT_CTR_TITLE:
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }

@Override
public InputStream getImageData() { public InputStream getImageData() {
try { try {
return getPart().getInputStream(); return getPart().getInputStream();
} }
} }


@Override
public String getContentType() { public String getContentType() {
/* TOOD: map content-type */ /* TOOD: map content-type */
return getPart().getContentType(); return getPart().getContentType();
} }


@Override
public int getAlpha() { public int getAlpha() {
return (blip.sizeOfAlphaModFixArray() > 0) return (blip.sizeOfAlphaModFixArray() > 0)
? blip.getAlphaModFixArray(0).getAmt() ? blip.getAlphaModFixArray(0).getAmt()
: 100000; : 100000;
} }
};
};
} }


@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();


Arrays.sort(gs, (o1, o2) -> { 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 ColorStyle cs[] = new ColorStyle[gs.length];
final float fractions[] = new float[gs.length]; final float fractions[] = new float[gs.length];
int i=0; int i=0;
for (CTGradientStop cgs : gs) { for (CTGradientStop cgs : gs) {
CTSchemeColor phClrCgs = phClr; CTSchemeColor phClrCgs = phClr;
fractions[i] = cgs.getPos() / 100000.f; fractions[i] = cgs.getPos() / 100000.f;
i++; i++;
} }
return new GradientPaint() { return new GradientPaint() {


@Override
public double getGradientAngle() { public double getGradientAngle() {
return (gradFill.isSetLin()) return (gradFill.isSetLin())
? gradFill.getLin().getAng() / 60000.d ? gradFill.getLin().getAng() / 60000.d
: 0; : 0;
} }


@Override
public ColorStyle[] getGradientColors() { public ColorStyle[] getGradientColors() {
return cs; return cs;
} }


@Override
public float[] getGradientFractions() { public float[] getGradientFractions() {
return fractions; return fractions;
} }


@Override
public boolean isRotatedWithShape() { public boolean isRotatedWithShape() {
return gradFill.getRotWithShape(); return gradFill.getRotWithShape();
} }


@Override
public GradientType getGradientType() { public GradientType getGradientType() {
if (gradFill.isSetLin()) { if (gradFill.isSetLin()) {
return GradientType.linear; return GradientType.linear;
} }
if (gradFill.isSetPath()) { if (gradFill.isSetPath()) {
/* TODO: handle rect path */ /* TODO: handle rect path */
STPathShadeType.Enum ps = gradFill.getPath().getPath(); STPathShadeType.Enum ps = gradFill.getPath().getPath();
return GradientType.shape; return GradientType.shape;
} }
} }
return GradientType.linear; return GradientType.linear;
} }
};
};
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) { 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 // 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. // background fill style within the presentation's style matrix, defined by the fmtScheme element.
// value of 0 or 1000 indicates no background, // value of 0 or 1000 indicates no background,
fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject()); fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
} }
cur.dispose(); cur.dispose();
CTSchemeColor phClr = fillRef.getSchemeClr(); CTSchemeColor phClr = fillRef.getSchemeClr();
PaintStyle res = selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder); PaintStyle res = selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder);
// check for empty placeholder value // check for empty placeholder value
XSLFColor col = new XSLFColor(fillRef, theme, phClr); XSLFColor col = new XSLFColor(fillRef, theme, phClr);
return DrawPaint.createSolidPaint(col.getColorStyle()); return DrawPaint.createSolidPaint(col.getColorStyle());
} }
@Override @Override
public void draw(Graphics2D graphics, Rectangle2D bounds) { public void draw(Graphics2D graphics, Rectangle2D bounds) {
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds); DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
} }
/** /**
* Return the shape specific (visual) properties * Return the shape specific (visual) properties
* *

+ 8
- 8
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java View File

for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) { if (args[i].startsWith("-")) {
if ("-scale".equals(args[i])) { 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])) { } else if ("-slide".equals(args[i])) {
slidenumStr = args[++i];
slidenumStr = args[++i]; // lgtm[java/index-out-of-bounds]
} else if ("-format".equals(args[i])) { } else if ("-format".equals(args[i])) {
format = args[++i];
format = args[++i]; // lgtm[java/index-out-of-bounds]
} else if ("-outdir".equals(args[i])) { } 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])) { } else if ("-quiet".equals(args[i])) {
quiet = true; quiet = true;
} }
usage("Invalid format given"); usage("Invalid format given");
return; return;
} }
if (outdir == null) { if (outdir == null) {
outdir = file.getParentFile(); outdir = file.getParentFile();
} }
if (!"null".equals(format) && (outdir == null || !outdir.exists() || !outdir.isDirectory())) { if (!"null".equals(format) && (outdir == null || !outdir.exists() || !outdir.isDirectory())) {
usage("Output directory doesn't exist"); usage("Output directory doesn't exist");
return; return;
usage("Invalid scale given"); usage("Invalid scale given");
return; return;
} }
if (!quiet) { if (!quiet) {
System.out.println("Processing " + file); System.out.println("Processing " + file);
} }
System.out.println("Done"); System.out.println("Done");
} }
} }
private static Set<Integer> slideIndexes(final int slideCount, String range) { private static Set<Integer> slideIndexes(final int slideCount, String range) {
Set<Integer> slideIdx = new TreeSet<>(); Set<Integer> slideIdx = new TreeSet<>();
if ("-1".equals(range)) { if ("-1".equals(range)) {

+ 1
- 1
src/ooxml/java/org/apache/poi/xssf/binary/XSSFBUtils.java View File

int numBytes = 2*(int)numChars; int numBytes = 2*(int)numChars;
offset += 4; offset += 4;
if (offset+numBytes > data.length) { 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); "offset="+offset+", numBytes="+numBytes+", data.length="+data.length);
} }
sb.append(new String(data, offset, numBytes, StandardCharsets.UTF_16LE)); sb.append(new String(data, offset, numBytes, StandardCharsets.UTF_16LE));

+ 24
- 20
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFRow.java View File

public class SXSSFRow implements Row, Comparable<SXSSFRow> public class SXSSFRow implements Row, Comparable<SXSSFRow>
{ {
private static final Boolean UNDEFINED = null; private static final Boolean UNDEFINED = null;
private final SXSSFSheet _sheet; // parent sheet private final SXSSFSheet _sheet; // parent sheet
private final SortedMap<Integer, SXSSFCell> _cells = new TreeMap<>(); private final SortedMap<Integer, SXSSFCell> _cells = new TreeMap<>();
private short _style = -1; // index of cell style in style table private short _style = -1; // index of cell style in style table
private short _height = -1; // row height in twips (1/20 point) 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 boolean _zHeight; // row zero-height (this is somehow different than being hidden)
private int _outlineLevel; // Outlining level of the row, when outlining is on 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 _hidden = UNDEFINED;
private Boolean _collapsed = UNDEFINED; private Boolean _collapsed = UNDEFINED;
public SXSSFRow(SXSSFSheet sheet) public SXSSFRow(SXSSFSheet sheet)
{ {
_sheet=sheet; _sheet=sheet;
} }
public Iterator<Cell> allCellsIterator() public Iterator<Cell> allCellsIterator()
{ {
return new CellIterator(); return new CellIterator();
void setOutlineLevel(int level){ void setOutlineLevel(int level){
_outlineLevel = level; _outlineLevel = level;
} }
/** /**
* get row hidden state: Hidden (true), Unhidden (false), Undefined (null) * get row hidden state: Hidden (true), Unhidden (false), Undefined (null)
* *
public SXSSFCell getCell(int cellnum, MissingCellPolicy policy) public SXSSFCell getCell(int cellnum, MissingCellPolicy policy)
{ {
checkBounds(cellnum); checkBounds(cellnum);
final SXSSFCell cell = _cells.get(cellnum); final SXSSFCell cell = _cells.get(cellnum);
switch (policy) { switch (policy) {
case RETURN_NULL_AND_BLANK: case RETURN_NULL_AND_BLANK:
@Override @Override
public void setHeightInPoints(float height) public void setHeightInPoints(float height)
{ {
if(height==-1)
if(height==-1) {
_height=-1; _height=-1;
else
} else {
_height=(short)(height*20); _height=(short)(height*20);
}
} }


/** /**
{ {
return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():_height/20.0); return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():_height/20.0);
} }
/** /**
* Is this row formatted? Most aren't, but some rows * Is this row formatted? Most aren't, but some rows
* do have whole-row styles. For those that do, you * do have whole-row styles. For those that do, you
*/ */
@Override @Override
public CellStyle getRowStyle() { public CellStyle getRowStyle() {
if(!isFormatted()) return null;
if(!isFormatted()) {
return null;
}

return getSheet().getWorkbook().getCellStyleAt(_style); return getSheet().getWorkbook().getCellStyleAt(_style);
} }
@Internal @Internal
/*package*/ int getRowStyleIndex() { /*package*/ int getRowStyleIndex() {
return _style; return _style;
} }
/** /**
* Applies a whole-row cell styling to the row. * Applies a whole-row cell styling to the row.
* The row style can be cleared by passing in <code>null</code>. * The row style can be cleared by passing in <code>null</code>.
/** /**
* Create an iterator over the cells from [0, getLastCellNum()). * Create an iterator over the cells from [0, getLastCellNum()).
* Includes blank cells, excludes empty cells * Includes blank cells, excludes empty cells
*
*
* Returns an iterator over all filled cells (created via Row.createCell()) * Returns an iterator over all filled cells (created via Row.createCell())
* Throws ConcurrentModificationException if cells are added, moved, or * Throws ConcurrentModificationException if cells are added, moved, or
* removed after the iterator is created. * removed after the iterator is created.
@Override @Override
public Cell next() throws NoSuchElementException public Cell next() throws NoSuchElementException
{ {
if (hasNext())
if (hasNext()) {
return _cells.get(pos++); return _cells.get(pos++);
else
} else {
throw new NoSuchElementException(); throw new NoSuchElementException();
}
} }
@Override @Override
public void remove() public void remove()
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
/** /**
* Compares two <code>SXSSFRow</code> objects. Two rows are equal if they belong to the same worksheet and * Compares two <code>SXSSFRow</code> objects. Two rows are equal if they belong to the same worksheet and
* their row indexes are equal. * their row indexes are equal.
throw new IllegalArgumentException("The compared rows must belong to the same sheet"); 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 @Override

+ 1
- 1
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java View File

XSSFSheet sheet = getSheet(); XSSFSheet sheet = getSheet();
XSSFWorkbook wb = sheet.getWorkbook(); XSSFWorkbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet); int sheetIndex = wb.getSheetIndex(sheet);
long shapeId = (sheetIndex + 1) * 1024 + newShapeId();
long shapeId = (sheetIndex + 1L) * 1024 + newShapeId();


// add reference to OLE part // add reference to OLE part
PackagePartName olePN; PackagePartName olePN;

+ 47
- 30
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java View File

import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;


import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.SpreadsheetVersion; 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.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy; import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
_cells.put(colI, cell); _cells.put(colI, cell);
sheet.onReadCell(cell); sheet.onReadCell(cell);
} }
if (! row.isSetR()) { if (! row.isSetR()) {
// Certain file format writers skip the row number // Certain file format writers skip the row number
// Assume no gaps, and give this the next row number // Assume no gaps, and give this the next row number
throw new IllegalArgumentException("The compared rows must belong to the same sheet"); 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 @Override
*/ */
@Override @Override
public XSSFCell getCell(int cellnum, MissingCellPolicy policy) { 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 // 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 final Integer colI = Integer.valueOf(cellnum); // NOSONAR
@Override @Override
public void setHeight(short height) { public void setHeight(short height) {
if (height == -1) { if (height == -1) {
if (_row.isSetHt()) _row.unsetHt();
if (_row.isSetCustomHeight()) _row.unsetCustomHeight();
if (_row.isSetHt()) {
_row.unsetHt();
}
if (_row.isSetCustomHeight()) {
_row.unsetCustomHeight();
}
} else { } else {
_row.setHt((double) height / 20); _row.setHt((double) height / 20);
_row.setCustomHeight(true); _row.setCustomHeight(true);
*/ */
@Override @Override
public XSSFCellStyle getRowStyle() { public XSSFCellStyle getRowStyle() {
if(!isFormatted()) return null;
if(!isFormatted()) {
return null;
}

StylesTable stylesSource = getSheet().getWorkbook().getStylesSource(); StylesTable stylesSource = getSheet().getWorkbook().getStylesSource();
if(stylesSource.getNumCellStyles() > 0) { if(stylesSource.getNumCellStyles() > 0) {
return stylesSource.getStyleAt((int)_row.getS()); return stylesSource.getStyleAt((int)_row.getS());
return null; return null;
} }
} }
/** /**
* Applies a whole-row cell styling to the row. * Applies a whole-row cell styling to the row.
* If the value is null then the style information is removed, * If the value is null then the style information is removed,
} }
} else { } else {
StylesTable styleSource = getSheet().getWorkbook().getStylesSource(); StylesTable styleSource = getSheet().getWorkbook().getStylesSource();
XSSFCellStyle xStyle = (XSSFCellStyle)style; XSSFCellStyle xStyle = (XSSFCellStyle)style;
xStyle.verifyBelongsToStylesSource(styleSource); xStyle.verifyBelongsToStylesSource(styleSource);


_row.setCustomFormat(true); _row.setCustomFormat(true);
} }
} }
/** /**
* Remove the Cell from this row. * Remove the Cell from this row.
* *
int i = 0; int i = 0;
for (XSSFCell xssfCell : _cells.values()) { for (XSSFCell xssfCell : _cells.values()) {
cArray[i] = (CTCell) xssfCell.getCTCell().copy(); 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! // elements as otherwise setCArray below invalidates all the columns!
// see Bug 56170, XMLBeans seems to always release previous objects // see Bug 56170, XMLBeans seems to always release previous objects
// in the CArray, so we need to provide completely new ones here! // in the CArray, so we need to provide completely new ones here!
} }
setRowNum(rownum); setRowNum(rownum);
} }
/** /**
* Copy the cells from srcRow to this row * Copy the cells from srcRow to this row
* If this row is not a blank row, this will merge the two rows, overwriting * If this row is not a blank row, this will merge the two rows, overwriting
final int srcRowNum = srcRow.getRowNum(); final int srcRowNum = srcRow.getRowNum();
final int destRowNum = getRowNum(); final int destRowNum = getRowNum();
final int rowDifference = destRowNum - srcRowNum; final int rowDifference = destRowNum - srcRowNum;
final FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007); final FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007);
final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet); final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet);
rowShifter.updateRowFormulas(this, formulaShifter); rowShifter.updateRowFormulas(this, formulaShifter);
public int getOutlineLevel() { public int getOutlineLevel() {
return _row.getOutlineLevel(); return _row.getOutlineLevel();
} }
/** /**
* Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the right. * Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the right.
* @param firstShiftColumnIndex the column to start shifting * @param firstShiftColumnIndex the column to start shifting
*/ */
@Override @Override
public void shiftCellsRight(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) { public void shiftCellsRight(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
if(step < 0)
if(step < 0) {
throw new IllegalArgumentException("Shifting step may not be negative "); throw new IllegalArgumentException("Shifting step may not be negative ");
if(firstShiftColumnIndex > lastShiftColumnIndex)
}
if(firstShiftColumnIndex > lastShiftColumnIndex) {
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(),
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex)); "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); shiftCell(columnIndex, step);
} }
for (int columnIndex = firstShiftColumnIndex; columnIndex <= firstShiftColumnIndex+step-1; columnIndex++) for (int columnIndex = firstShiftColumnIndex; columnIndex <= firstShiftColumnIndex+step-1; columnIndex++)
{ {
_cells.remove(columnIndex); _cells.remove(columnIndex);
XSSFCell targetCell = getCell(columnIndex); XSSFCell targetCell = getCell(columnIndex);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance()); targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
} }
} }
/** /**
*/ */
@Override @Override
public void shiftCellsLeft(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) { public void shiftCellsLeft(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
if(step < 0)
if(step < 0) {
throw new IllegalArgumentException("Shifting step may not be negative "); throw new IllegalArgumentException("Shifting step may not be negative ");
if(firstShiftColumnIndex > lastShiftColumnIndex)
}
if(firstShiftColumnIndex > lastShiftColumnIndex) {
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(), throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(),
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex)); "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()); 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); shiftCell(columnIndex, -step);
} }
for (int columnIndex = lastShiftColumnIndex-step+1; columnIndex <= lastShiftColumnIndex; columnIndex++){ for (int columnIndex = lastShiftColumnIndex-step+1; columnIndex <= lastShiftColumnIndex; columnIndex++){
_cells.remove(columnIndex); _cells.remove(columnIndex);
XSSFCell targetCell = getCell(columnIndex); XSSFCell targetCell = getCell(columnIndex);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance()); targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
} }
} }
private void shiftCell(int columnIndex, int step/*pass negative value for left shift*/){ 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()); throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(columnIndex + step)).toString());
}

XSSFCell currentCell = getCell(columnIndex); XSSFCell currentCell = getCell(columnIndex);
if(currentCell != null){ if(currentCell != null){
currentCell.setCellNum(columnIndex+step); currentCell.setCellNum(columnIndex+step);
else { else {
_cells.remove(columnIndex+step); _cells.remove(columnIndex+step);
XSSFCell targetCell = getCell(columnIndex+step); XSSFCell targetCell = getCell(columnIndex+step);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance()); targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
} }
} }
} }

+ 11
- 9
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSDTContent.java View File



// private final IBody part; // private final IBody part;
// private final XWPFDocument document; // 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<>(); private List<ISDTContents> bodyElements = new ArrayList<>();


public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) { public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) {
for (CTR ctr : sdtRun.getRArray()) { for (CTR ctr : sdtRun.getRArray()) {
XWPFRun run = new XWPFRun(ctr, parent); XWPFRun run = new XWPFRun(ctr, parent);
runs.add(run);
// runs.add(run);
bodyElements.add(run); bodyElements.add(run);
} }
} }
if (o instanceof CTP) { if (o instanceof CTP) {
XWPFParagraph p = new XWPFParagraph((CTP) o, part); XWPFParagraph p = new XWPFParagraph((CTP) o, part);
bodyElements.add(p); bodyElements.add(p);
paragraphs.add(p);
// paragraphs.add(p);
} else if (o instanceof CTTbl) { } else if (o instanceof CTTbl) {
XWPFTable t = new XWPFTable((CTTbl) o, part); XWPFTable t = new XWPFTable((CTTbl) o, part);
bodyElements.add(t); bodyElements.add(t);
tables.add(t);
// tables.add(t);
} else if (o instanceof CTSdtBlock) { } else if (o instanceof CTSdtBlock) {
XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part); XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part);
bodyElements.add(c); bodyElements.add(c);
contentControls.add(c);
// contentControls.add(c);
} else if (o instanceof CTR) { } else if (o instanceof CTR) {
XWPFRun run = new XWPFRun((CTR) o, parent); XWPFRun run = new XWPFRun((CTR) o, parent);
runs.add(run);
// runs.add(run);
bodyElements.add(run); bodyElements.add(run);
} }
} }
cursor.dispose(); cursor.dispose();
} }


@Override
public String getText() { public String getText() {
StringBuilder text = new StringBuilder(); StringBuilder text = new StringBuilder();
boolean addNewLine = false; boolean addNewLine = false;
} }
} }


@Override
public String toString() { public String toString() {
return getText(); return getText();
} }

+ 57
- 50
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java View File

this.ctTbl = table; this.ctTbl = table;


// is an empty table: I add one row and one column as default // is an empty table: I add one row and one column as default
if (table.sizeOfTrArray() == 0)
if (table.sizeOfTrArray() == 0) {
createEmptyTable(table); createEmptyTable(table);
}


for (CTRow row : table.getTrList()) { for (CTRow row : table.getTrList()) {
StringBuilder rowText = new StringBuilder(); StringBuilder rowText = new StringBuilder();
return text.toString(); return text.toString();
} }


/** /**
* This method has existed since 2008 without an implementation. * This method has existed since 2008 without an implementation.
* It will be removed unless an implementation is provided. * It will be removed unless an implementation is provided.
/** /**
* Get the width value as an integer. * 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 * <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 * @return width value as an integer
*/ */
public int getWidth() { public int getWidth() {
} }


/** /**
* 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 * create the element if necessary. If force parameter is false, returns
* null when CTTblPr element is missing. * null when CTTblPr element is missing.
* *
private CTTblBorders getTblBorders(boolean force) { private CTTblBorders getTblBorders(boolean force) {
CTTblPr tblPr = getTblPr(force); CTTblPr tblPr = getTblPr(force);
return tblPr == null ? null return tblPr == null ? null
: tblPr.isSetTblBorders() ? tblPr.getTblBorders()
: tblPr.isSetTblBorders() ? tblPr.getTblBorders()
: force ? tblPr.addNewTblBorders() : force ? tblPr.addNewTblBorders()
: null; : null;
} }
: tPr.isSetJc() ? TableRowAlign.valueOf(tPr.getJc().getVal().intValue()) : tPr.isSetJc() ? TableRowAlign.valueOf(tPr.getJc().getVal().intValue())
: null; : null;
} }
/** /**
* Set table alignment to specified {@link TableRowAlign} * Set table alignment to specified {@link TableRowAlign}
* *
* @param ha {@link TableRowAlign} to set
* @param tra {@link TableRowAlign} to set
*/ */
public void setTableAlignment(TableRowAlign tra) { public void setTableAlignment(TableRowAlign tra) {
CTTblPr tPr = getTblPr(true); CTTblPr tPr = getTblPr(true);
CTJc jc = tPr.isSetJc() ? tPr.getJc() : tPr.addNewJc(); CTJc jc = tPr.isSetJc() ? tPr.getJc() : tPr.addNewJc();
jc.setVal(STJc.Enum.forInt(tra.getValue())); jc.setVal(STJc.Enum.forInt(tra.getValue()));
} }
/** /**
* Removes the table alignment attribute from a table * Removes the table alignment attribute from a table
*/ */
tPr.unsetJc(); tPr.unsetJc();
} }
} }
private void addColumn(XWPFTableRow tabRow, int sizeCol) { private void addColumn(XWPFTableRow tabRow, int sizeCol) {
if (sizeCol > 0) { if (sizeCol > 0) {
for (int i = 0; i < sizeCol; i++) { for (int i = 0; i < sizeCol; i++) {


/** /**
* Get inside horizontal border size * Get inside horizontal border size
*
*
* @return The width of the Inside Horizontal borders in 1/8th points, * @return The width of the Inside Horizontal borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get inside horizontal border spacing * Get inside horizontal border spacing
*
*
* @return The offset to the Inside Horizontal borders in points, * @return The offset to the Inside Horizontal borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get inside horizontal border color * Get inside horizontal border color
*
*
* @return The color of the Inside Horizontal borders, null if missing. * @return The color of the Inside Horizontal borders, null if missing.
*/ */
public String getInsideHBorderColor() { public String getInsideHBorderColor() {


/** /**
* Get inside vertical border size * Get inside vertical border size
*
*
* @return The width of the Inside vertical borders in 1/8th points, * @return The width of the Inside vertical borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get inside vertical border spacing * Get inside vertical border spacing
*
*
* @return The offset to the Inside vertical borders in points, * @return The offset to the Inside vertical borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get inside vertical border color * Get inside vertical border color
*
*
* @return The color of the Inside vertical borders, null if missing. * @return The color of the Inside vertical borders, null if missing.
*/ */
public String getInsideVBorderColor() { public String getInsideVBorderColor() {


/** /**
* Get top border size * Get top border size
*
*
* @return The width of the top borders in 1/8th points, * @return The width of the top borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get top border spacing * Get top border spacing
*
*
* @return The offset to the top borders in points, * @return The offset to the top borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get top border color * Get top border color
*
*
* @return The color of the top borders, null if missing. * @return The color of the top borders, null if missing.
*/ */
public String getTopBorderColor() { public String getTopBorderColor() {


/** /**
* Get bottom border size * Get bottom border size
*
*
* @return The width of the bottom borders in 1/8th points, * @return The width of the bottom borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get bottom border spacing * Get bottom border spacing
*
*
* @return The offset to the bottom borders in points, * @return The offset to the bottom borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get bottom border color * Get bottom border color
*
*
* @return The color of the bottom borders, null if missing. * @return The color of the bottom borders, null if missing.
*/ */
public String getBottomBorderColor() { public String getBottomBorderColor() {


/** /**
* Get Left border size * Get Left border size
*
*
* @return The width of the Left borders in 1/8th points, * @return The width of the Left borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get Left border spacing * Get Left border spacing
*
*
* @return The offset to the Left borders in points, * @return The offset to the Left borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get Left border color * Get Left border color
*
*
* @return The color of the Left borders, null if missing. * @return The color of the Left borders, null if missing.
*/ */
public String getLeftBorderColor() { public String getLeftBorderColor() {


/** /**
* Get Right border size * Get Right border size
*
*
* @return The width of the Right borders in 1/8th points, * @return The width of the Right borders in 1/8th points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get Right border spacing * Get Right border spacing
*
*
* @return The offset to the Right borders in points, * @return The offset to the Right borders in points,
* -1 if missing. * -1 if missing.
*/ */


/** /**
* Get Right border color * Get Right border color
*
*
* @return The color of the Right borders, null if missing. * @return The color of the Right borders, null if missing.
*/ */
public String getRightBorderColor() { public String getRightBorderColor() {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setTopBorder(XWPFBorderType type, int size, int space, String rgbColor) {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setBottomBorder(XWPFBorderType type, int size, int space, String rgbColor) {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setLeftBorder(XWPFBorderType type, int size, int space, String rgbColor) {
* of a point) and a maximum value of 96 (twelve points). Any values outside this * of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value. * 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 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. * 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) { public void setRightBorder(XWPFBorderType type, int size, int space, String rgbColor) {
public void removeInsideHBorder() { public void removeInsideHBorder() {
removeBorder(Border.INSIDE_H); removeBorder(Border.INSIDE_H);
} }
/** /**
* Remove inside vertical borders for table * Remove inside vertical borders for table
*/ */
public void removeInsideVBorder() { public void removeInsideVBorder() {
removeBorder(Border.INSIDE_V); removeBorder(Border.INSIDE_V);
} }
/** /**
* Remove top borders for table * Remove top borders for table
*/ */
public void removeBottomBorder() { public void removeBottomBorder() {
removeBorder(Border.BOTTOM); removeBorder(Border.BOTTOM);
} }
/** /**
* Remove left borders for table * Remove left borders for table
*/ */
public void removeLeftBorder() { public void removeLeftBorder() {
removeBorder(Border.LEFT); removeBorder(Border.LEFT);
} }
/** /**
* Remove right borders for table * Remove right borders for table
*/ */
public void removeRightBorder() { public void removeRightBorder() {
removeBorder(Border.RIGHT); removeBorder(Border.RIGHT);
} }
/** /**
* Remove all borders from table * Remove all borders from table
*/ */
} }


/** /**
* removes the Borders node from Table properties if there are
* removes the Borders node from Table properties if there are
* no border elements * no border elements
*/ */
private void cleanupTblBorders() { private void cleanupTblBorders() {
} }
} }
} }
public int getCellMarginTop() { public int getCellMarginTop() {
return getCellMargin(CTTblCellMar::getTop); return getCellMargin(CTTblCellMar::getTop);
} }
* *
* @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType() * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
*/ */
@Override
public BodyElementType getElementType() { public BodyElementType getElementType() {
return BodyElementType.TABLE; return BodyElementType.TABLE;
} }


@Override
public IBody getBody() { public IBody getBody() {
return part; return part;
} }
* *
* @see org.apache.poi.xwpf.usermodel.IBody#getPart() * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/ */
@Override
public POIXMLDocumentPart getPart() { public POIXMLDocumentPart getPart() {
if (part != null) { if (part != null) {
return part.getPart(); return part.getPart();
* *
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType() * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
*/ */
@Override
public BodyType getPartType() { public BodyType getPartType() {
return part.getPartType(); return part.getPartType();
} }
*/ */
public XWPFTableRow getRow(CTRow row) { public XWPFTableRow getRow(CTRow row) {
for (int i = 0; i < getRows().size(); i++) { 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; return null;
} }
/** /**
* Get the table width as a decimal value. * Get the table width as a decimal value.
* <p>If the width type is DXA or AUTO, then the value will always have * <p>If the width type is DXA or AUTO, then the value will always have
protected static double getWidthDecimal(CTTblWidth ctWidth) { protected static double getWidthDecimal(CTTblWidth ctWidth) {
double result = 0.0; double result = 0.0;
STTblWidth.Enum typeValue = ctWidth.getType(); STTblWidth.Enum typeValue = ctWidth.getType();
if (typeValue == STTblWidth.DXA
|| typeValue == STTblWidth.AUTO
if (typeValue == STTblWidth.DXA
|| typeValue == STTblWidth.AUTO
|| typeValue == STTblWidth.NIL) { || typeValue == STTblWidth.NIL) {
result = 0.0 + ctWidth.getW().intValue(); result = 0.0 + ctWidth.getW().intValue();
} else if (typeValue == STTblWidth.PCT) { } else if (typeValue == STTblWidth.PCT) {
// Percentage values are stored as integers that are 50 times // Percentage values are stored as integers that are 50 times
// percentage. // percentage.
result = ctWidth.getW().intValue() / 50.0;
result = ctWidth.getW().intValue() / 50.0;
} else { } else {
// Should never get here // Should never get here
} }
protected static void setWidthValue(String widthValue, CTTblWidth ctWidth) { protected static void setWidthValue(String widthValue, CTTblWidth ctWidth) {
if (!widthValue.matches(REGEX_WIDTH_VALUE)) { if (!widthValue.matches(REGEX_WIDTH_VALUE)) {
throw new RuntimeException("Table width value \"" + widthValue + "\" " 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")) { if (widthValue.matches("auto")) {
ctWidth.setType(STTblWidth.AUTO); ctWidth.setType(STTblWidth.AUTO);
} else { } else {
// Must be an integer // Must be an integer
ctWidth.setW(new BigInteger(widthValue)); ctWidth.setW(new BigInteger(widthValue));
ctWidth.setType(STTblWidth.DXA);
ctWidth.setType(STTblWidth.DXA);
} }
} }


/** /**
* Set the underlying table width value to a percentage value. * 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, * @param widthValue String width value in form "33.3%" or an integer that is 50 times desired percentage value (e.g,
* 2500 for 50%) * 2500 for 50%)
* @since 4.0.0 * @since 4.0.0
String numberPart = widthValue.substring(0, widthValue.length() - 1); String numberPart = widthValue.substring(0, widthValue.length() - 1);
double percentage = Double.parseDouble(numberPart) * 50; double percentage = Double.parseDouble(numberPart) * 50;
long intValue = Math.round(percentage); long intValue = Math.round(percentage);
ctWidth.setW(BigInteger.valueOf(intValue));
ctWidth.setW(BigInteger.valueOf(intValue));
} else if (widthValue.matches("[0-9]+")) { } else if (widthValue.matches("[0-9]+")) {
ctWidth.setW(new BigInteger(widthValue)); ctWidth.setW(new BigInteger(widthValue));
} else { } else {
* @since 4.0.0 * @since 4.0.0
*/ */
public void setWidthType(TableWidthType widthType) { public void setWidthType(TableWidthType widthType) {
setWidthType(widthType, getTblPr().getTblW());
setWidthType(widthType, getTblPr().getTblW());
} }


/** /**

Loading…
Cancel
Save