ramblings/oxygen/js-include/src-java/simple/documentation/framework/extensions/SDFReferencesResolver.java

200 lines
6.4 KiB
Java

package simple.documentation.framework.extensions;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.transform.sax.SAXSource;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import ro.sync.ecss.extensions.api.AuthorAccess;
import ro.sync.ecss.extensions.api.AuthorReferenceResolver;
import ro.sync.ecss.extensions.api.node.AttrValue;
import ro.sync.ecss.extensions.api.node.AuthorElement;
import ro.sync.ecss.extensions.api.node.AuthorNode;
/**
* References resolver for Simple Documentation Framework.
*
*/
public class SDFReferencesResolver implements AuthorReferenceResolver {
/**
* Logger for logging.
*/
private static Logger logger = LogManager.getLogger(
SDFReferencesResolver.class.getName());
/**
* Verifies if the handler considers the node to have references.
*
* @param node The node to be analyzed.
* @return <code>true</code> if it is has references.
*/
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;
}
/**
* Returns the name of the node that contains the expanded referred content.
*
* @param node The node that contains references.
* @return The display name of the node.
*/
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;
}
/**
* Resolve the references of the node.
*
* The returning SAXSource will be used for creating the referred content
* using the parser and source inside it.
*
* @param node The clone of the node.
* @param systemID The system ID of the node with references.
* @param authorAccess The author access implementation.
* @param entityResolver The entity resolver that can be used to resolve:
*
* <ul>
* <li>Resources that are already opened in editor.
* For this case the InputSource will contains the editor content.</li>
* <li>Resources resolved through XML catalog.</li>
* </ul>
*
* @return The SAX source including the parser and the parser's input source.
*/
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();
if (attrStringVal.length() > 0) {
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.getXMLUtilAccess().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;
}
/**
* Get an unique identifier for the node reference.
*
* The unique identifier is used to avoid resolving the references
* recursively.
*
* @param node The node that has reference.
* @return An unique identifier for the reference node.
*/
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;
}
/**
* Return the systemID of the referred content.
*
* @param node The reference node.
* @param authorAccess The author access.
*
* @return The systemID of the referred content.
*/
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;
}
/**
* Verifies if the references of the given node must be refreshed
* when the attribute with the specified name has changed.
*
* @param node The node with the references.
* @param attributeName The name of the changed attribute.
* @return <code>true</code> if the references must be refreshed.
*/
public boolean isReferenceChanged(AuthorNode node, String attributeName) {
return "location".equals(attributeName);
}
/**
* @return The description of the author extension.
*/
public String getDescription() {
return "Resolves the 'ref' references";
}
}