Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/enhydra/xml/dom/DOMAccess.java


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: DOMAccess.java,v 1.1.2.3 2000/12/06 02:05:43 markd Exp $
22   */
23  
24  package org.enhydra.xml.dom;
25  
26  import org.w3c.dom.Document;
27  import org.w3c.dom.DocumentType;
28  import org.w3c.dom.Element;
29  import org.w3c.dom.Attr;
30  import org.w3c.dom.Node;
31  import org.enhydra.xml.lazydom.LazyDocument;
32  import org.enhydra.xml.lazydom.LazyParent;
33  import org.enhydra.xml.lazydom.LazyElement;
34  import org.enhydra.xml.lazydom.LazyNode;
35  import org.enhydra.xml.lazydom.LazyAttr;
36  import org.enhydra.xml.xmlc.XMLObject;
37  
38  // FIXME: Some the the access funtionallity might be better implemented
39  // in the nodes themselves.  Maybe this just belongs in the Document
40  // although they would only be valid in the template document.
41  
42  //FIXME: most of this not really tested, don';t export until tests
43  // are written.
44  
45  /**
46   * Method to support accessing the LazyDOM without expanding it.  This works
47   * both with standard DOMs and LazyDOMs, supporting the development of code
48   * that works with either DOM.
49   * <p> 
50   * Most methods come in two flavors, static ones that take the instance
51   * document as an argument, an instance methods that use a document contained
52   * in an instance of this object.  Great care should be used if the return
53   * nodes are to be modified, as read-only template nodes maybe returned.
54   * These methods also operate on any W3C DOM.
55   */
56  public final class DOMAccess {
57      /** 
58       * Document being accessed.
59       */
60      private Document fDocument;
61  
62      /**
63       * Create a object to access a specific document.
64       *
65       * @param document The document to access. if this is a LazyDOM instance
66       *  document, access will switch between the instance and template
67       *  as appropriate.
68       */
69      public DOMAccess(Document document) {
70          fDocument = document;
71      }
72  
73      /**
74       * Access the document type node.
75       * @param document The instance document object.
76       * @return The document type object, or null if there is none.
77       */
78      public static DocumentType accessDocumentType(Document document) {
79          if (document instanceof LazyDocument) {
80              LazyDocument lazyDoc = (LazyDocument)document;
81              if (lazyDoc.isTemplateNode() || lazyDoc.isDocTypeExpanded()) {
82                  return lazyDoc.getDoctype();
83              } else {
84                  return lazyDoc.getTemplateDocument().getDoctype();
85              }
86          } else {
87              return document.getDoctype();
88          }
89      }
90  
91      /**
92       * Access the document type node.
93       * @return The document type object, or null if there is none.
94       */
95      public DocumentType accessDocumentType() {
96          return accessDocumentType(fDocument);
97      }
98  
99      /**
100      * Access first child of template node, switching to instance document
101      * if child is expanded.
102      */
103     private static Node accessTemplateFirstChild(LazyDocument lazyDoc,
104                                                  LazyParent lazyParent) {
105         LazyNode templateChild = (LazyNode)lazyParent.getFirstChild();
106         if (templateChild == null) {
107             return null; // no child
108         } else if (lazyDoc.isTemplateNode()) {
109             return templateChild;  // Document is a template, not instance
110         } else {
111             LazyNode instanceChild = lazyDoc.getExpandedNode(templateChild.getNodeId());
112             if (instanceChild != null) {
113                 return instanceChild;
114             } else {
115                 return templateChild;
116             }
117         }
118     }
119     
120     /**
121      * Access the first child of a node. 
122      *
123      * @param document The instance document object.
124      * @param parent The parent node of the desired child.
125      * @return The first child or null if there is none.
126      */
127     public static Node accessFirstChild(Document document,
128                                         Node parent) {
129         if (parent instanceof LazyParent) {
130             LazyParent lazyParent = (LazyParent)parent;
131             if (lazyParent.isTemplateNode()) {
132                 // parent is template: check if child is expanded 
133                 return accessTemplateFirstChild((LazyDocument)document,
134                                                 lazyParent);
135             } else if (lazyParent.areChildrenExpanded()) {
136                 // expanded instance children, handle as normal
137                 return lazyParent.getFirstChild();
138             } else {
139                 // switch to template
140                 return lazyParent.getTemplateNode().getFirstChild();
141             }
142         } else {
143             // standard DOM or LazyDOM node that is not a LazyParent
144             return parent.getFirstChild();
145         }
146     }
147 
148     /**
149      * Access the first child of a node. 
150      *
151      * @param parent The parent node of the desired child.
152      * @return The first child or null if there is none.
153      */
154     public Node accessFirstChild(Node parent) {
155         return accessFirstChild(fDocument, parent);
156     }
157 
158     /**
159      * Access next sibling child of template node, switching to instance
160      * document if sibling is expanded.
161      */
162     private static Node accessTemplateNextSibling(LazyDocument lazyDoc,
163                                                   LazyNode templateNode) {
164         LazyNode templateSibling = (LazyNode)templateNode.getNextSibling();
165         if (templateSibling == null) {
166             return null; // no sibling
167         } else {
168             LazyNode instanceSibling = lazyDoc.getExpandedNode(templateSibling.getNodeId());
169             if (instanceSibling != null) {
170                 return instanceSibling;
171             } else {
172                 return templateSibling;
173             }
174         }
175     }
176     
177     /**
178      * Access next sibling child of instance node, switching to template
179      * document if sibling is not expanded.
180      */
181     private static Node accessInstanceNextSibling(LazyDocument lazyDoc,
182                                                   LazyNode instanceNode) {
183         if (instanceNode instanceof LazyParent) {
184             // Node is a LazyParent, sibling will be expanded if parent is
185             // expanded.  It may or may not be expanded if parent is not
186             // expanded.
187             if (((LazyParent)instanceNode).isParentExpanded()) {
188                 return instanceNode.getNextSibling();
189             } else {
190                 // Check if sibling is expanded is expanded
191                 LazyNode templateNode = instanceNode.getTemplateNode();
192                 LazyNode templateSibling = (LazyNode)instanceNode.getNextSibling();
193                 if (templateSibling != null) {
194                     LazyNode instanceSibling = lazyDoc.getExpandedNode(templateSibling.getNodeId());
195                     if (instanceSibling != null) {
196                         return instanceSibling;
197                     } else {
198                         return templateSibling;
199                     } 
200                 } else {
201                     return null;  // No sibling
202                 }
203             }
204         } else {
205             // Node is not a LazyParent, sibling must be expanded
206             return instanceNode.getNextSibling();
207         }
208     }
209 
210     /**
211      * Access the next sibling of a node. 
212      *
213      * @param document The instance document object.
214      * @param node Get the next sibling of this node
215      * @return The first child or null if there is none.
216      */
217     public static Node accessNextSibling(Document document,
218                                          Node node) {
219         if (node instanceof LazyNode) {
220             LazyNode lazyNode = (LazyNode)node;
221             if (lazyNode.isTemplateNode()) {
222                 // node is template: check if sibling is expanded 
223                 return accessTemplateNextSibling((LazyDocument)document,
224                                                  lazyNode);
225             } else {
226                 return accessInstanceNextSibling((LazyDocument)document,
227                                                  lazyNode);
228             }
229         } else {
230             // standard DOM
231             return node.getNextSibling();
232         }
233     }
234 
235     /**
236      * Access the next sibling of a node. 
237      *
238      * @param node Get the next sibling of this node
239      * @return The first child or null if there is none.
240      */
241     public Node accessNextSibling(Node node) {
242         return accessNextSibling(fDocument, node);
243     }
244 
245     /**
246      * Access the document element of a document.
247      *
248      * @param document The instance document object.
249      * @return The document element.
250      */
251     public static Element accessDocumentElement(Document document) {
252         if (document instanceof LazyDocument) {
253             Node child = accessFirstChild(document, document);
254             while (child != null) {
255                 if (child instanceof Element) {
256                     break;
257                 }
258                 child = accessNextSibling(document, child);
259             }
260             return (Element)child;
261         } else {
262             return document.getDocumentElement();
263         }
264     }
265 
266     /**
267      * Access the document element of the document.
268      *
269      * @return The document element.
270      */
271     public Element accessDocumentElement() {
272         return accessDocumentElement(fDocument);
273     }
274 
275     /**
276      * Access an attribute of an Element.
277      *
278      * @param document The instance document object.
279      * @param element The Element node.
280      * @param namespaceURI The namespace URI, or null if there is none.
281      * @param name The name of the attribute.
282      * @return The attribute node, or null if it does not exist.  The value
283      * should be accessed via accessAttributeValue().
284      */
285     public static Attr accessAttribute(Document document,
286                                        Element element,
287                                        String namespaceURI,
288                                        String name) {
289         // Find the element (template or instance) to use to obtain the
290         // attribute
291         Element accessElement;
292         if (element instanceof LazyElement) {
293             LazyElement lazyElement = (LazyElement)element;
294             if (lazyElement.areAttributesExpanded()) {
295                 // template or expanded instance, just get attribute
296                 accessElement = lazyElement;
297             } else {
298                 // instance and attributes not expanded, get from template
299                 accessElement = lazyElement.getTemplateElement();
300             }
301         } else {
302             // not a Lazy DOM, just get attribute
303             accessElement = element;
304         }
305 
306         // Get with or without namespace
307         if (namespaceURI != null) {
308             return accessElement.getAttributeNodeNS(namespaceURI, name);
309         } else {
310             return accessElement.getAttributeNode(name);
311         }
312     }
313 
314     /**
315      * Access an attribute of an Element.
316      *
317      * @param element The Element node.
318      * @param namespaceURI The namespace URI, or null if there is none.
319      * @param name The name of the attribute.
320      * @return The attribute node, or null if it does not exist.  The value
321      * should be accessed via accessAttributeValue().
322      */
323     public Attr accessAttribute(Element element,
324                                 String namespaceURI,
325                                 String name) {
326         return accessAttribute(fDocument, element, namespaceURI, name);
327     }
328 
329     /**
330      * Access the value of an attribute
331      *
332      * @param document The instance document object.
333      * @param attr The Attr node.
334      * @return The value of the attribute, as a string.
335      */
336     public static String accessAttributeValue(Document document,
337                                               Attr attr) {
338         if (attr instanceof LazyAttr) {
339             LazyAttr lazyAttr = (LazyAttr)attr;
340             if (lazyAttr.areChildrenExpanded()) {
341                 // template or expanded instance, just get value
342                 return lazyAttr.getValue();
343             } else {
344                 // instance and children not expanded, get from template
345                 return ((LazyAttr)lazyAttr.getTemplateNode()).getValue();
346             }
347         } else {
348             // not a Lazy DOM, just get the value
349             return attr.getValue();
350         }
351     }
352 
353     /**
354      * Access the value of an attribute
355      *
356      * @param attr The Attr node.
357      * @return The value of the attribute, as a string.
358      */
359     public String accessAttributeValue(Attr attr) {
360         return accessAttributeValue(fDocument, attr);
361     }
362 
363     /**
364      * If a Node is a LazyDOM template node, expand it.
365      *
366      * @param document The instance document object.
367      * @param node A node of the document or it's template.
368      * @return The expanded node, or the node unchanged
369      *  if it is not a LazyDOM template.
370      */
371     public static Node getExpandedNode(Document document,
372                                        Node node) {
373         if ((node instanceof LazyNode) && ((LazyNode)node).isTemplateNode()) {
374             return (Node)((LazyDocument)document).getNodeById(((LazyNode)node).getNodeId());
375         } else {
376             return node;
377         }
378     }
379 
380     /**
381      * If a Node is a LazyDOM template node, expand it.
382      *
383      * @param node A node of the document or it's template.
384      * @return The expanded node, or the node unchanged
385      *  if it is not a LazyDOM template.
386      */
387     public Node getExpandedNode(Node node) {
388         return getExpandedNode(fDocument, node);
389     }
390 
391     /**
392      * If an Element node is a LazyDOM template, expand it.
393      * This is a special case of <tt>getExpandedNode()</tt>.
394      *
395      * @param document The instance document object.
396      * @param element An element of the document or it's template.
397      * @return The expanded element, or the element unchanged
398      *  if it is not a LazyDOM template.
399      */
400     public static Element getExpandedElement(Document document,
401                                              Element element) {
402         if ((element instanceof LazyElement) && ((LazyElement)element).isTemplateNode()) {
403             return (Element)((LazyDocument)document).getNodeById(((LazyElement)element).getNodeId());
404         } else {
405             return element;
406         }
407     }
408 
409     /**
410      * If an Element node is a LazyDOM template, expand it
411      * This is a special case of <tt>getExpandedNode()</tt>.
412      *
413      * @param element An element of the document or template.
414      * @return The expanded element, or the element unchanged
415      *  if it is not a LazyDOM template.
416      */
417     public Element getExpandedElement(Element element) {
418         return getExpandedElement(fDocument, element);
419     }
420 
421 }