
org.enhydra.xml.xmlc.compiler.EditDOM Maven / Gradle / Ivy
The newest version!
/*
* Enhydra Java Application Server Project
*
* The contents of this file are subject to the Enhydra Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License on
* the Enhydra web site ( http://www.enhydra.org/ ).
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific terms governing rights and limitations
* under the License.
*
* The Initial Developer of the Enhydra Application Server is Lutris
* Technologies, Inc. The Enhydra Application Server and portions created
* by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
* All Rights Reserved.
*
* Contributor(s):
*
* $Id: EditDOM.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
*/
package org.enhydra.xml.xmlc.compiler;
import org.enhydra.xml.xmlc.XMLCException;
import org.enhydra.xml.xmlc.dom.XMLCDocument;
import org.enhydra.xml.xmlc.metadata.DOMEdits;
import org.enhydra.xml.xmlc.metadata.DeleteElement;
import org.enhydra.xml.xmlc.metadata.ElementEdit;
import org.enhydra.xml.xmlc.metadata.MetaData;
import org.enhydra.xml.xmlc.metadata.URLMapping;
import org.enhydra.xml.xmlc.metadata.URLRegExpMapping;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* Class to perform edits on a DOM.
*/
public class EditDOM {
/**
* DOM edits metadata.
*/
private DeleteElement[] deleteElements;
private URLMapping[] urlMappings;
private URLRegExpMapping[] urlRegExpMappings;
/**
* Document being edited.
*/
private XMLCDocument xmlcDocument;
/**
* Is this an HTML document?
*/
private boolean isHtml;
/**
* Constructor.
*/
public EditDOM(MetaData metaData) {
DOMEdits domEdits = metaData.getDOMEdits();
if (domEdits != null) {
deleteElements = domEdits.getDeleteElements();
urlMappings = domEdits.getURLMappings();
urlRegExpMappings = domEdits.getURLRegExpMappings();
}
// Default null ones to empty arrays.
if (deleteElements == null) {
deleteElements = new DeleteElement[0];
}
if (urlMappings == null) {
urlMappings = new URLMapping[0];
}
if (urlRegExpMappings == null) {
urlRegExpMappings = new URLRegExpMapping[0];
}
}
/**
* Determine if an element matches an ElementEdit set of constraints.
*/
private boolean elementMatchesConstraints(Element element,
ElementEdit elementEdit) {
if (!elementEdit.matchesElementIdConstraints(getElementId(element))) {
return false;
}
String[] elementClasses = xmlcDocument.getElementClassNames(element);
if (elementClasses == null) {
// Not classes, must be no class constraints
if (!elementEdit.matchesElementClassConstraints(null)) {
return false;
}
} else {
// At least one class must match.
boolean classMatched = false;
for (int idx = 0; (idx < elementClasses.length) && (!classMatched); idx++) {
if (elementEdit.matchesElementClassConstraints(elementClasses[idx])) {
classMatched = true;
}
}
if (!classMatched) {
return false;
}
}
if (!elementEdit.matchesElementTagConstraints(element.getTagName(),
isHtml)) {
return false;
}
// Passed all constraints.
return true;
}
/**
* Process a delete element request on an element,
* @return true if the element is deleted.
*/
private boolean processDeleteElement(Element element,
DeleteElement deleteElement) {
if (elementMatchesConstraints(element, deleteElement)) {
element.getParentNode().removeChild(element);
return true;
}
return false;
}
/**
* Process delete element requests on an element,
* @return true if the element is deleted.
*/
private boolean processDeleteElements(Element element) {
for (int idx = 0; idx < deleteElements.length; idx++) {
if (processDeleteElement(element, deleteElements[idx])) {
return true;
}
}
return false;
}
/**
* Process a URL mapping for an attribute.
*
* @return true if the attribute was modified, false if it was not.
*/
private boolean processURLMapping(Element element,
String attrName,
String oldURL,
URLMapping urlMapping) {
if (elementMatchesConstraints(element, urlMapping)
&& urlMapping.matchesEditAttrConstraints(attrName, isHtml)) {
// Note: unspecified URL matches all
String url = urlMapping.getUrl();
if ((url == null) || url.equals(oldURL)) {
element.setAttribute(attrName, urlMapping.getNewUrl());
return true;
}
}
return false;
}
/**
* Process URL mappings for an attribute.
*
* @return true if the attribute was modified, false if it was not.
*/
private boolean processURLMappings(Element element,
String attrName,
String oldURL) {
for (int idx = 0; idx < urlMappings.length; idx++) {
if (processURLMapping(element, attrName, oldURL, urlMappings[idx])) {
return true;
}
}
return false;
}
/**
* Process a URL regexp mapping for an attribute.
*
* @return true if the attribute was modified, false if it was not.
*/
private boolean processURLRegExpMapping(Element element,
String attrName,
String oldURL,
URLRegExpMapping urlRegExpMapping)
throws XMLCException {
if (elementMatchesConstraints(element, urlRegExpMapping)
&& urlRegExpMapping.matchesEditAttrConstraints(attrName, isHtml)) {
String newURL = urlRegExpMapping.mapURL(oldURL);
if (newURL != null) {
element.setAttribute(attrName, newURL);
return true;
}
}
return false;
}
/**
* Process the URL regexp mappings for an attribute.
*
* @return true if the attribute was modified, false if it was not.
*/
private boolean processURLRegExpMappings(Element element,
String attrName,
String oldURL)
throws XMLCException {
for (int idx = 0; idx < urlRegExpMappings.length; idx++) {
if (processURLRegExpMapping(element, attrName, oldURL,
urlRegExpMappings[idx])) {
return true;
}
}
return false;
}
/**
* Perform URL edits on an attribute element. Trys URLMappings first,
* then URL regexp mappings.
*/
private void editElementURL(Element element,
String attrName) throws XMLCException {
Attr attr = element.getAttributeNode(attrName);
if ((attr != null) && attr.getSpecified()) {
String oldURL = attr.getValue();
if (!processURLMappings(element, attrName, oldURL)) {
processURLRegExpMappings(element, attrName, oldURL);
}
}
}
/**
* Perform URL edits on an element.
*/
private void editElementURLs(Element element) throws XMLCException {
NamedNodeMap attrs = element.getAttributes();
if (attrs != null) {
for (int idx = 0; idx < attrs.getLength(); idx++) {
String name = attrs.item(idx).getNodeName();
if (xmlcDocument.isURLAttribute(element, name)) {
editElementURL(element, name);
}
}
}
}
/**
* Recursively edit nodes.
*/
private void editNodes(Node node)
throws XMLCException {
if (node instanceof Element) {
node = editElement((Element)node);
// Don't process the children if editElement() returned null...
if (node == null) return;
}
// Traverse children
Node child = node.getFirstChild();
while (child != null) {
Node nextChild = child.getNextSibling(); // child might be deleted
editNodes(child);
child = nextChild;
}
}
/**
* Edit a single element. If you override this method, don't
* forget to call super.editElement(element)
to
* perform the standard edits. Derived classes may replace
* element
by another node in their version of
* editElement
. In this case, the
* editElement() method must return the new node in order
* for the editor code to pick up and edit children of this new node.
* @return element
, or null
to indicate
* that the children of this element should not be processed.
*/
protected Node editElement(Element element) throws XMLCException {
// Check for deletion first, as no other work will be done if
// deleted.
if (processDeleteElements(element)) {
return null;
}
editElementURLs(element);
return element;
}
/**
* Edit the nodes of the document.
*/
public void edit(XMLCDocument xmlcDoc)
throws XMLCException {
this.xmlcDocument = xmlcDoc;
isHtml = xmlcDocument.isHtmlDocument();
editNodes(xmlcDoc.getDocument());
}
/** Get the ID of an element */
protected String getElementId(Element element) {
return xmlcDocument.getElementId(element);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy