Configuring a References Resolver
You need to provide a handler for resolving references and obtain the content they reference. In our case the element that has references is ref and the attribute indicating the referenced resource is location. You will have to implement a Java extension class for obtaining the referenced resources.
-
Create the class simple.documentation.framework.ReferencesResolver.
This class must implement the ro.sync.ecss.extensions.api.AuthorReferenceResolver
interface.
import ro.sync.ecss.extensions.api.AuthorReferenceResolver; import ro.sync.ecss.extensions.api.AuthorAccess; import ro.sync.ecss.extensions.api.node.AttrValue; import ro.sync.ecss.extensions.api.node.AuthorElement; import ro.sync.ecss.extensions.api.node.AuthorNode; public class ReferencesResolver implements AuthorReferenceResolver { -
The hasReferences method verifies if the handler considers the node
to have references. It takes as argument an AuthorNode that represents
the node that will be verified. The method will return
trueif the node is considered to have references. In our case, to be a reference the node must be an element with the name ref and it must have an attribute named location.public boolean hasReferences(AuthorNode node) { boolean hasReferences = false; if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) { AuthorElement element = (AuthorElement) node; if ("ref".equals(element.getLocalName())) { AttrValue attrValue = element.getAttribute("location"); hasReferences = attrValue != null; } } return hasReferences; } -
The method getDisplayName returns the display name of the node that
contains the expanded referenced content. It takes as argument an
AuthorNode that represents the node for which the display name is
needed. The referenced content engine will ask this
AuthorReferenceResolver implementation for the display name for each
node that is considered a reference. In our case, the display name is the value of the
location attribute from the ref element.
public String getDisplayName(AuthorNode node) { String displayName = "ref-fragment"; if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) { AuthorElement element = (AuthorElement) node; if ("ref".equals(element.getLocalName())) { AttrValue attrValue = element.getAttribute("location"); if (attrValue != null) { displayName = attrValue.getValue(); } } } return displayName; } -
The method resolveReference resolves the reference of the node and
returns a SAXSource with the parser and its input source. It takes as
arguments an AuthorNode that represents the node for which the
reference needs resolving, the systemID of the node, the
AuthorAccess with access methods to the Author
mode data model and a SAX EntityResolver that resolves resources that
are already opened in another editor or resolve resources through the XML catalog. In the
implementation you need to resolve the reference relative to the
systemID, and create a parser and an input source over the resolved
reference.
public SAXSource resolveReference( AuthorNode node, String systemID, AuthorAccess authorAccess, EntityResolver entityResolver) { SAXSource saxSource = null; if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) { AuthorElement element = (AuthorElement) node; if ("ref".equals(element.getLocalName())) { AttrValue attrValue = element.getAttribute("location"); if (attrValue != null) { String attrStringVal = attrValue.getValue(); try { URL absoluteUrl = new URL(new URL(systemID), authorAccess.getUtilAccess().correctURL(attrStringVal)); InputSource inputSource = entityResolver.resolveEntity(null, absoluteUrl.toString()); if(inputSource == null) { inputSource = new InputSource(absoluteUrl.toString()); } XMLReader xmlReader = authorAccess.newNonValidatingXMLReader(); xmlReader.setEntityResolver(entityResolver); saxSource = new SAXSource(xmlReader, inputSource); } catch (MalformedURLException e) { logger.error(e, e); } catch (SAXException e) { logger.error(e, e); } catch (IOException e) { logger.error(e, e); } } } } return saxSource; } -
The method getReferenceUniqueID should return a unique identifier
for the node reference. The unique identifier is used to avoid resolving the references
recursively. The method takes as argument an AuthorNode that represents
the node with the reference. In the implementation the unique identifier is the value of
the location attribute from the ref element.
public String getReferenceUniqueID(AuthorNode node) { String id = null; if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) { AuthorElement element = (AuthorElement) node; if ("ref".equals(element.getLocalName())) { AttrValue attrValue = element.getAttribute("location"); if (attrValue != null) { id = attrValue.getValue(); } } } return id; } -
The method getReferenceSystemIDshould return the
systemID of the referenced content. It takes as arguments an
AuthorNode that represents the node with the reference and the
AuthorAccess with access methods to the Author
mode data model. In the implementation you use the value of the location attribute
from the ref element and resolve it relatively to the XML base URL of the
node.
public String getReferenceSystemID(AuthorNode node, AuthorAccess authorAccess) { String systemID = null; if (node.getType() == AuthorNode.NODE_TYPE_ELEMENT) { AuthorElement element = (AuthorElement) node; if ("ref".equals(element.getLocalName())) { AttrValue attrValue = element.getAttribute("location"); if (attrValue != null) { String attrStringVal = attrValue.getValue(); try { URL absoluteUrl = new URL(node.getXMLBaseURL(), authorAccess.getUtilAccess().correctURL(attrStringVal)); systemID = absoluteUrl.toString(); } catch (MalformedURLException e) { logger.error(e, e); } } } } return systemID; }Note: The complete source code for the examples can be found in the Simple Documentation Framework project, included in the oxygen-sample-framework module of the Oxygen SDK , available as a Maven archetype on the Oxygen XML Editor website.In the listing below, the XML document contains the ref element:
<ref location="referenced.xml">Reference</ref>
When no reference resolver is specified, the reference has the following layout:
Figure: Reference with no specified reference resolver
When the above implementation is configured, the reference has the expected layout:
Figure: Reference with reference resolver
Note: The complete source code for the examples can be found in the Simple
Documentation Framework project, included in the oxygen-sample-framework module of the
Oxygen SDK , available as a Maven archetype on the Oxygen XML Editor website.