org.docx4j.convert.out.common.writer.AbstractHyperlinkWriterModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docx4j Show documentation
Show all versions of docx4j Show documentation
docx4j is a library which helps you to work with the Office Open
XML file format as used in docx
documents, pptx presentations, and xlsx spreadsheets.
package org.docx4j.convert.out.common.writer;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.docx4j.convert.out.ConversionHyperlinkHandler;
import org.docx4j.convert.out.common.AbstractWmlConversionContext;
import org.docx4j.model.fields.FldSimpleModel;
import org.docx4j.model.fields.FormattingSwitchHelper;
import org.docx4j.openpackaging.parts.relationships.Namespaces;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.P;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
/** Model for the hyperlink tag.
*/
public class AbstractHyperlinkWriterModel implements ConversionHyperlinkHandler.Model {
private static Logger log = LoggerFactory.getLogger(AbstractHyperlinkWriterModel.class);
protected Node content = null;
/** field-argument of the Hyperlink field or the targetUri of the relationship.
* corresponds to switch \l field-argument, the \l switch might be omitted.
*/
protected String target = null;
/** Only avaiable if the information is read from a relationship.
* Otherwise always false.
*/
protected boolean external = false;
/**
* Specifies the name of a bookmark in the current document which shall be the target of
* this hyperlink.
* If this attribute is omitted, then the default behavior shall be to navigate to the start of
* the document. If a hyperlink target is also specified using the r:id attribute, then this
* attribute shall be ignored.
*/
protected String anchor = null;
/**
* Specifies a location in the target of the hyperlink that has no bookmarks. The method by
* which the contents of this attribute are linked to document text is outside the scope of
* ECMA-376.
*/
protected String docLocation = null;
//history - ignored
/**
* Specifies the ID of the relationship whose target shall be used as the target for this
* hyperlink.
*/
protected String rId = null;
/**
* Specifies a frame within the parent HTML frameset for the target of the parent hyperlink
* when one exists.
* corresponds to switch \t field-argument
* corresponds to switch \n with tgtFrame = "_blank"
*/
protected String tgtFrame = null;
/**
* Specifies a string which can be surfaced in a user interface as associated with the parent
* hyperlink.
* corresponds to switch \o field-argument
*/
protected String tooltip = null;
// imageMapCoordinates switch \m ignored - requires a ismap attribute in an embedded img
// P.Hyperlink pHyperlink;
// /**
// * Where this model was built with a P.Hyperlink,
// * here it is. Useful for debugging.
// * @return
// */
// public P.Hyperlink getPHyperlink() {
// return pHyperlink;
// }
/** Default build method, get's called with a P.Hyperlink.
*/
public void build(AbstractWmlConversionContext conversionContext, Object node, Node content) throws TransformerException {
Relationship relationship = null;
RelationshipsPart rPart = null;
P.Hyperlink pHyperlink = (P.Hyperlink)node;
// log.debug(XmlUtils.marshaltoString(hyperlink, true, true));
this.content = content;
setAnchor(pHyperlink.getAnchor());
setDocLocation(pHyperlink.getDocLocation());
setRId(pHyperlink.getId());
setTgtFrame(pHyperlink.getTgtFrame());
setTooltip(pHyperlink.getTooltip());
if (conversionContext.getCurrentPart() == null) {
log.warn("set currentPart (via conversionContext)");
} else if ((getRId() != null) &&
(getRId().length() > 0) ) {
rPart = conversionContext.getCurrentPart().getRelationshipsPart();
if (rPart == null) {
log.error("RelationshipsPart is missing!");
} else {
log.debug("looking for rel" + getRId());
relationship = rPart.getRelationshipByID(getRId());
if ((relationship != null) &&
(Namespaces.HYPERLINK.equals(relationship.getType()))) {
setTarget(relationship.getTarget());
setExternal("External".equals(relationship.getTargetMode()));
}
}
}
}
/** Custom build method, get's used with a FldSimpleModel in those cases
* where the hyperlink is defined within a Field
*/
public void build(AbstractWmlConversionContext conversionContext, FldSimpleModel fldSimpleModel, Node content) throws TransformerException {
int idx = 0;
List parameters = fldSimpleModel.getFldParameters();
String parameter = null;
boolean isSwitch = false;
char switchChar = '\0';
String switchParameter = null;
this.content = content;
while (idx < parameters.size()) {
parameter = parameters.get(idx);
if ((parameter != null) && (parameter.length() > 0)) {//should allways be true
isSwitch = ((parameter.charAt(0) == '\\') && (parameter.length() == 2));
if (isSwitch) {
switchChar = Character.toLowerCase(parameter.charAt(1));
switch (switchChar) {
case 'l': //target
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTarget(switchParameter);
idx++;
}
break;
case 't': //target frame name
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTgtFrame(switchParameter);
idx++;
}
break;
case 'n': //target frame = "_blank"
setTgtFrame("_blank");
break;
case 'o': //tooltip
switchParameter = FormattingSwitchHelper.getSwitchValue(idx + 1, parameters);
if (switchParameter != null) {
setTooltip(switchParameter);
idx++;
}
break;
case 'm': //image map coordinates
break;
}
}
else {
//should only happen once with the first value, all others should be preceeded by a switch
if (idx == 0) {
setTarget(FormattingSwitchHelper.getSwitchValue(idx, parameters));
}
}
}
idx++;
}
if ((getTarget() != null) &&
(getTarget().length() > 0) &&
((getTarget().indexOf('/') > -1) ||
(getTarget().indexOf('\\') > -1) ||
(getTarget().indexOf('.') > -1) ||
(getTarget().indexOf(':') > -1))) {
/* Don't know if this is correct: assume an external target if it contains
* one of the following characters: \/:.
*/
setExternal(true);
}
}
public String getExternalTarget() {
return (isExternal() ? getTarget() : null);
}
public String getInternalTarget() {
String ret = (isExternal() ? null : getTarget());
if (ret == null) {
ret = getAnchor(); // this is a target, see http://webapp.docx4java.org/OnlineDemo/ecma376/WordML/hyperlink_2.html
}
if (ret == null) {
ret = getDocLocation();
}
return ret;
}
@Override
public String getTarget() {
return target;
}
@Override
public void setTarget(String target) {
this.target = target;
}
@Override
public boolean isExternal() {
return external;
}
@Override
public void setExternal(boolean external) {
this.external = external;
}
@Override
public String getAnchor() {
return anchor;
}
@Override
public void setAnchor(String anchor) {
this.anchor = anchor;
}
@Override
public String getDocLocation() {
return docLocation;
}
@Override
public void setDocLocation(String docLocation) {
this.docLocation = docLocation;
}
@Override
public String getRId() {
return rId;
}
@Override
public void setRId(String rId) {
this.rId = rId;
}
@Override
public String getTgtFrame() {
return tgtFrame;
}
@Override
public void setTgtFrame(String tgtFrame) {
this.tgtFrame = tgtFrame;
}
@Override
public String getTooltip() {
return tooltip;
}
@Override
public void setTooltip(String tooltip) {
this.tooltip = tooltip;
}
@Override
public Node getContent() {
return content;
}
@Override
public String toString() {
return "HyperlinkModel [target=" + target + ", external=" + external
+ ", anchor=" + anchor + ", docLocation=" + docLocation
+ ", rId=" + rId + ", tgtFrame=" + tgtFrame + "]";
}
}