KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > compiler > EditDOM


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: EditDOM.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.xmlc.compiler;
25
26 import org.enhydra.xml.xmlc.XMLCException;
27 import org.enhydra.xml.xmlc.dom.XMLCDocument;
28 import org.enhydra.xml.xmlc.metadata.DOMEdits;
29 import org.enhydra.xml.xmlc.metadata.DeleteElement;
30 import org.enhydra.xml.xmlc.metadata.ElementEdit;
31 import org.enhydra.xml.xmlc.metadata.MetaData;
32 import org.enhydra.xml.xmlc.metadata.URLMapping;
33 import org.enhydra.xml.xmlc.metadata.URLRegExpMapping;
34 import org.w3c.dom.Attr JavaDoc;
35 import org.w3c.dom.Element JavaDoc;
36 import org.w3c.dom.NamedNodeMap JavaDoc;
37 import org.w3c.dom.Node JavaDoc;
38
39 /**
40  * Class to perform edits on a DOM.
41  */

42 public class EditDOM {
43     /**
44      * DOM edits metadata.
45      */

46     private DeleteElement[] deleteElements;
47     private URLMapping[] urlMappings;
48     private URLRegExpMapping[] urlRegExpMappings;
49
50     /**
51      * Document being edited.
52      */

53     private XMLCDocument xmlcDocument;
54
55     /**
56      * Is this an HTML document?
57      */

58     private boolean isHtml;
59
60     /**
61      * Constructor.
62      */

63     public EditDOM(MetaData metaData) {
64         DOMEdits domEdits = metaData.getDOMEdits();
65         if (domEdits != null) {
66             deleteElements = domEdits.getDeleteElements();
67             urlMappings = domEdits.getURLMappings();
68             urlRegExpMappings = domEdits.getURLRegExpMappings();
69         }
70         // Default null ones to empty arrays.
71
if (deleteElements == null) {
72             deleteElements = new DeleteElement[0];
73         }
74         if (urlMappings == null) {
75             urlMappings = new URLMapping[0];
76         }
77         if (urlRegExpMappings == null) {
78             urlRegExpMappings = new URLRegExpMapping[0];
79         }
80     }
81
82     /**
83      * Determine if an element matches an ElementEdit set of constraints.
84      */

85     private boolean elementMatchesConstraints(Element element,
86                                               ElementEdit elementEdit) {
87         if (!elementEdit.matchesElementIdConstraints(getElementId(element))) {
88             return false;
89         }
90         String JavaDoc[] elementClasses = xmlcDocument.getElementClassNames(element);
91         if (elementClasses == null) {
92             // Not classes, must be no class constraints
93
if (!elementEdit.matchesElementClassConstraints(null)) {
94                 return false;
95             }
96         } else {
97             // At least one class must match.
98
boolean classMatched = false;
99             for (int idx = 0; (idx < elementClasses.length) && (!classMatched); idx++) {
100                 if (elementEdit.matchesElementClassConstraints(elementClasses[idx])) {
101                     classMatched = true;
102                 }
103             }
104             if (!classMatched) {
105                 return false;
106             }
107         }
108         
109         if (!elementEdit.matchesElementTagConstraints(element.getTagName(),
110                                                       isHtml)) {
111             return false;
112         }
113
114         // Passed all constraints.
115
return true;
116     }
117
118     /**
119      * Process a delete element request on an element,
120      * @return true if the element is deleted.
121      */

122     private boolean processDeleteElement(Element element,
123                                          DeleteElement deleteElement) {
124         if (elementMatchesConstraints(element, deleteElement)) {
125             element.getParentNode().removeChild(element);
126             return true;
127         }
128         return false;
129     }
130
131     /**
132      * Process delete element requests on an element,
133      * @return true if the element is deleted.
134      */

135     private boolean processDeleteElements(Element element) {
136         for (int idx = 0; idx < deleteElements.length; idx++) {
137             if (processDeleteElement(element, deleteElements[idx])) {
138                 return true;
139             }
140         }
141         return false;
142     }
143
144     /**
145      * Process a URL mapping for an attribute.
146      *
147      * @return true if the attribute was modified, false if it was not.
148      */

149     private boolean processURLMapping(Element element,
150                                       String JavaDoc attrName,
151                                       String JavaDoc oldURL,
152                                       URLMapping urlMapping) {
153         if (elementMatchesConstraints(element, urlMapping)
154             && urlMapping.matchesEditAttrConstraints(attrName, isHtml)) {
155             // Note: unspecified URL matches all
156
String JavaDoc url = urlMapping.getUrl();
157             if ((url == null) || url.equals(oldURL)) {
158                 element.setAttribute(attrName, urlMapping.getNewUrl());
159                 return true;
160             }
161         }
162         return false;
163     }
164
165     /**
166      * Process URL mappings for an attribute.
167      *
168      * @return true if the attribute was modified, false if it was not.
169      */

170     private boolean processURLMappings(Element element,
171                                        String JavaDoc attrName,
172                                        String JavaDoc oldURL) {
173         for (int idx = 0; idx < urlMappings.length; idx++) {
174             if (processURLMapping(element, attrName, oldURL, urlMappings[idx])) {
175                 return true;
176             }
177         }
178         return false;
179     }
180
181     /**
182      * Process a URL regexp mapping for an attribute.
183      *
184      * @return true if the attribute was modified, false if it was not.
185      */

186     private boolean processURLRegExpMapping(Element element,
187                                             String JavaDoc attrName,
188                                             String JavaDoc oldURL,
189                                             URLRegExpMapping urlRegExpMapping)
190             throws XMLCException {
191         if (elementMatchesConstraints(element, urlRegExpMapping)
192             && urlRegExpMapping.matchesEditAttrConstraints(attrName, isHtml)) {
193             String JavaDoc newURL = urlRegExpMapping.mapURL(oldURL);
194             if (newURL != null) {
195                 element.setAttribute(attrName, newURL);
196                 return true;
197             }
198         }
199         return false;
200     }
201
202     /**
203      * Process the URL regexp mappings for an attribute.
204      *
205      * @return true if the attribute was modified, false if it was not.
206      */

207     private boolean processURLRegExpMappings(Element element,
208                                              String JavaDoc attrName,
209                                              String JavaDoc oldURL)
210             throws XMLCException {
211         for (int idx = 0; idx < urlRegExpMappings.length; idx++) {
212             if (processURLRegExpMapping(element, attrName, oldURL,
213                                         urlRegExpMappings[idx])) {
214                 return true;
215             }
216         }
217         return false;
218     }
219
220     /**
221      * Perform URL edits on an attribute element. Trys URLMappings first,
222      * then URL regexp mappings.
223      */

224     private void editElementURL(Element element,
225                                 String JavaDoc attrName) throws XMLCException {
226         Attr JavaDoc attr = element.getAttributeNode(attrName);
227         if ((attr != null) && attr.getSpecified()) {
228             String JavaDoc oldURL = attr.getValue();
229             if (!processURLMappings(element, attrName, oldURL)) {
230                 processURLRegExpMappings(element, attrName, oldURL);
231             }
232         }
233     }
234
235     /**
236      * Perform URL edits on an element.
237      */

238     private void editElementURLs(Element element) throws XMLCException {
239         NamedNodeMap JavaDoc attrs = element.getAttributes();
240         if (attrs != null) {
241             for (int idx = 0; idx < attrs.getLength(); idx++) {
242                 String JavaDoc name = attrs.item(idx).getNodeName();
243                 if (xmlcDocument.isURLAttribute(element, name)) {
244                     editElementURL(element, name);
245                 }
246             }
247         }
248     }
249
250     /**
251      * Recursively edit nodes.
252      */

253     private void editNodes(Node JavaDoc node)
254             throws XMLCException {
255         if (node instanceof Element) {
256             node = editElement((Element)node);
257         // Don't process the children if editElement() returned null...
258
if (node == null) return;
259         }
260
261         // Traverse children
262
Node JavaDoc child = node.getFirstChild();
263         while (child != null) {
264             Node JavaDoc nextChild = child.getNextSibling(); // child might be deleted
265
editNodes(child);
266             child = nextChild;
267         }
268     }
269
270     /**
271      * Edit a single element. If you override this method, don't
272      * forget to call <code>super.editElement(element)</code> to
273      * perform the standard edits. Derived classes may replace
274      * <code>element</code> by another node in their version of
275      * <code>editElement</code>. In this case, the
276      * <em>editElement()</em> method must return the new node in order
277      * for the editor code to pick up and edit children of this new node.
278      * @return <code>element</code>, or <code>null</code> to indicate
279      * that the children of this element should not be processed.
280      */

281     protected Node JavaDoc editElement(Element element) throws XMLCException {
282     // Check for deletion first, as no other work will be done if
283
// deleted.
284
if (processDeleteElements(element)) {
285         return null;
286     }
287     editElementURLs(element);
288     return element;
289     }
290
291     /**
292      * Edit the nodes of the document.
293      */

294     public void edit(XMLCDocument xmlcDoc)
295             throws XMLCException {
296         this.xmlcDocument = xmlcDoc;
297         isHtml = xmlcDocument.isHtmlDocument();
298         editNodes(xmlcDoc.getDocument());
299     }
300
301     /** Get the ID of an element */
302     protected String JavaDoc getElementId(Element element) {
303     return xmlcDocument.getElementId(element);
304     }
305 }
306
Popular Tags