KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > xml > XMLHelper


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.ejb.cmp3.xml;
23
24 import java.net.URL JavaDoc;
25
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28
29 import javax.xml.parsers.DocumentBuilder JavaDoc;
30 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
31 import javax.xml.parsers.ParserConfigurationException JavaDoc;
32
33 import org.w3c.dom.Document JavaDoc;
34 import org.w3c.dom.Node JavaDoc;
35 import org.w3c.dom.NodeList JavaDoc;
36
37 import org.xml.sax.SAXException JavaDoc;
38
39 import oracle.toplink.essentials.exceptions.XMLParseException;
40 import oracle.toplink.essentials.exceptions.ValidationException;
41
42 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataHelper;
43 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataLogger;
44
45 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XPathEngine;
46 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLException;
47 import oracle.toplink.essentials.internal.ejb.cmp3.xml.parser.XMLExceptionHandler;
48
49 /**
50  * Utility class used for handling element inspection.
51  * @author Guy Pelletier
52  * @since TopLink EJB 3.0 Reference Implementation
53  */

54 public class XMLHelper {
55     private Document JavaDoc m_document;
56     private ClassLoader JavaDoc m_loader;
57     private String JavaDoc m_documentName;
58     private String JavaDoc m_defaultPackage;
59     private XPathEngine m_xPathEngine;
60     
61     /**
62      * INTERNAL:
63      */

64     protected XMLHelper(Document JavaDoc document, ClassLoader JavaDoc loader) {
65         m_xPathEngine = XPathEngine.getInstance();
66         m_loader = loader;
67         m_document = document;
68         
69         Node JavaDoc node = getNode(document, new String JavaDoc[] {XMLConstants.ENTITY_MAPPINGS, XMLConstants.PACKAGE, XMLConstants.TEXT});
70         
71         if (node != null && node.getNodeValue() != null) {
72             m_defaultPackage = node.getNodeValue();
73         } else {
74             m_defaultPackage = "";
75         }
76     }
77     
78     /**
79      * INTERNAL:
80      */

81     public XMLHelper(InputStream JavaDoc xmlDocStream, String JavaDoc fileName, ClassLoader JavaDoc loader) {
82         this(parseDocument(xmlDocStream, fileName, loader), loader);
83         m_documentName = fileName;
84     }
85     
86     /**
87      * INTERNAL:
88      */

89     public Class JavaDoc getClassForName(String JavaDoc className) {
90         return MetadataHelper.getClassForName(getFullyQualifiedClassName(className), m_loader);
91     }
92
93     /**
94      * INTERNAL:
95      * Return the Class for a given node. This method assumes that the node
96      * requires a class attribute, i.e. entity or mapped-superclass.
97      */

98     public Class JavaDoc getClassForNode(Node JavaDoc node) {
99         return MetadataHelper.getClassForName(getClassNameForNode(node), m_loader);
100     }
101     
102     /**
103      * INTERNAL:
104      * Return the fully qualified class name for a given node. This method
105      * assumes that the node requires a class attribute, i.e. entity or
106      * mapped-superclass.
107      */

108     public String JavaDoc getClassNameForNode(Node JavaDoc node) {
109         return getFullyQualifiedClassName(getNodeValue(node, XMLConstants.ATT_CLASS));
110     }
111     
112     /**
113      * INTERNAL:
114      * Return the instance document associated with this helper.
115      */

116     public Document JavaDoc getDocument() {
117         return m_document;
118     }
119     
120     /**
121      * INTERNAL:
122      * Return the instance document name associated with this helper.
123      */

124     public String JavaDoc getDocumentName() {
125         return m_documentName;
126     }
127
128     /**
129      * INTERNAL:
130      * This convenience method will attempt to fully qualify a class name if
131      * required. This assumes that the className value is non-null, and a
132      * "qualified" class name contains at least one '.'
133      */

134     public String JavaDoc getFullyQualifiedClassName(String JavaDoc className) {
135         return getFullyQualifiedClassName(className, m_defaultPackage);
136     }
137     
138     /**
139      * INTERNAL:
140      * This convenience method will attempt to fully qualify a class name if
141      * required. This assumes that the className value is non-null, and a
142      * "qualified" class name contains at least one '.'
143      */

144     public static String JavaDoc getFullyQualifiedClassName(String JavaDoc className, String JavaDoc packageName) {
145         // if there is no global package defined or the class name is qualified, return className
146
if (packageName.equals("") || className.indexOf(".") != -1) {
147             return className;
148         }
149         
150         // prepend the package to the class name
151
// format of global package is "foo.bar."
152
if (packageName.endsWith(".")) {
153             return (packageName + className);
154         }
155         
156         // format of global package is "foo.bar"
157
return (packageName + "." + className);
158     }
159     
160     /**
161      * INTERNAL:
162      * This convenience method determines the type of relationship mapping the
163      * node represents, and returns the appropriate logging context.
164      */

165     public String JavaDoc getLoggingContextForDefaultMappingReferenceClass(Node JavaDoc mappingNode) {
166         if (mappingNode.getLocalName().equals(XMLConstants.ONE_TO_ONE)) {
167             return MetadataLogger.ONE_TO_ONE_MAPPING_REFERENCE_CLASS;
168         }
169         if (mappingNode.getLocalName().equals(XMLConstants.ONE_TO_MANY)) {
170             return MetadataLogger.ONE_TO_MANY_MAPPING_REFERENCE_CLASS;
171         }
172         if (mappingNode.getLocalName().equals(XMLConstants.MANY_TO_ONE)) {
173             return MetadataLogger.MANY_TO_ONE_MAPPING_REFERENCE_CLASS;
174         }
175         // assume many-to-many
176
return MetadataLogger.MANY_TO_MANY_MAPPING_REFERENCE_CLASS;
177     }
178     
179     /**
180      * INTERNAL:
181      * Get a node off the given node.
182      */

183     public Node JavaDoc getNode(Node JavaDoc node, String JavaDoc xPath) {
184         return getNode(node, new String JavaDoc[] {xPath});
185     }
186     
187     /**
188      * INTERNAL:
189      * Get a node off the given node.
190      */

191     public Node JavaDoc getNode(Node JavaDoc node, String JavaDoc[] xPath) {
192         return m_xPathEngine.selectSingleNode(node, xPath);
193     }
194     
195     /**
196      * INTERNAL:
197      * Get a node off the document node.
198      */

199     public Node JavaDoc getNode(String JavaDoc[] xPath) {
200         return getNode(m_document, xPath);
201     }
202     
203     /**
204      * INTERNAL:
205      * Get the nodes off the given node.
206      */

207     public NodeList JavaDoc getNodes(String JavaDoc xPath1, String JavaDoc xPath2) {
208         return getNodes(m_document, new String JavaDoc[] {xPath1, xPath2});
209     }
210     
211     /**
212      * INTERNAL:
213      * Get the nodes off the given node.
214      */

215     public NodeList JavaDoc getNodes(String JavaDoc[] xPath) {
216         return getNodes(m_document, xPath);
217     }
218     
219     /**
220      * INTERNAL:
221      */

222     public String JavaDoc getNodeTextValue(Node JavaDoc node, String JavaDoc xPath) {
223         return getNodeValue(node, new String JavaDoc[] {xPath, XMLConstants.TEXT});
224     }
225     
226     /**
227      * INTERNAL:
228      */

229     public String JavaDoc getNodeTextValue(String JavaDoc xPath1, String JavaDoc xPath2) {
230         return getNodeValue(m_document, new String JavaDoc[] {xPath1, xPath2, XMLConstants.TEXT});
231     }
232     
233     /**
234      * INTERNAL:
235      */

236     public String JavaDoc getNodeTextValue(String JavaDoc xPath1, String JavaDoc xPath2, String JavaDoc defaultValue) {
237         return getNodeValue(m_document, new String JavaDoc[] {xPath1, xPath2, XMLConstants.TEXT}, defaultValue);
238     }
239     
240     /**
241      * INTERNAL:
242      */

243     public String JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc xPath) {
244         return getNodeValue(node, new String JavaDoc[] {xPath});
245     }
246     
247     /**
248      * INTERNAL:
249      */

250     public boolean getNodeValue(Node JavaDoc node, String JavaDoc xPath, boolean defaultValue) {
251         return getNodeValue(node, new String JavaDoc[] {xPath}, defaultValue);
252     }
253     
254     /**
255      * INTERNAL:
256      */

257     public Class JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc xPath, Class JavaDoc defaultValue) {
258         return getNodeValue(node, new String JavaDoc[] {xPath}, defaultValue);
259     }
260     
261     /**
262      * INTERNAL:
263      */

264     public int getNodeValue(Node JavaDoc node, String JavaDoc xPath, int defaultValue) {
265         return getNodeValue(node, new String JavaDoc[] {xPath}, defaultValue);
266     }
267     
268     /**
269      * INTERNAL:
270      */

271     public String JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc xPath, String JavaDoc defaultValue) {
272         return getNodeValue(node, new String JavaDoc[] {xPath}, defaultValue);
273     }
274
275     /**
276      * INTERNAL:
277      */

278     public NodeList JavaDoc getNodes(Node JavaDoc node, String JavaDoc xPath) {
279         return getNodes(node, new String JavaDoc[] {xPath});
280     }
281     
282     /**
283      * INTERNAL:
284      */

285     public NodeList JavaDoc getNodes(Node JavaDoc node, String JavaDoc xPath1, String JavaDoc xPath2) {
286         return getNodes(node, new String JavaDoc[] {xPath1, xPath2});
287     }
288     
289     /**
290      * INTERNAL:
291      */

292     public NodeList JavaDoc getNodes(Node JavaDoc node, String JavaDoc[] xPath) {
293         return m_xPathEngine.selectNodes(node, xPath);
294     }
295     
296     /**
297      * INTERNAL:
298      */

299     public boolean getNodeValue(Node JavaDoc node, String JavaDoc[] xPath, boolean defaultValue) {
300         return getValue(getNode(node, xPath), defaultValue);
301     }
302     
303     /**
304      * INTERNAL:
305      */

306     public Class JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc[] xPath, Class JavaDoc defaultValue) {
307         return getValue(getNode(node, xPath), defaultValue);
308     }
309     
310     /**
311      * INTERNAL:
312      */

313     public int getNodeValue(Node JavaDoc node, String JavaDoc[] xPath, int defaultValue) {
314         return getValue(getNode(node, xPath), defaultValue);
315     }
316     
317     /**
318      * INTERNAL:
319      */

320     public String JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc[] xPath, String JavaDoc defaultValue) {
321         return getValue(getNode(node, xPath), defaultValue);
322     }
323     
324     /**
325      * INTERNAL:
326      */

327     public String JavaDoc getNodeValue(Node JavaDoc node, String JavaDoc[] xPath) {
328         return getNodeValue(node, xPath, "");
329     }
330     
331     /**
332      * INTERNAL:
333      */

334     public String JavaDoc getNodeValue(String JavaDoc[] xPath) {
335         return getNodeValue(xPath, "");
336     }
337     
338     /**
339      * INTERNAL:
340      */

341     public int getNodeValue(String JavaDoc[] xPath, int defaultValue) {
342         return getValue(getNode(xPath), defaultValue);
343     }
344     
345     /**
346      * INTERNAL:
347      */

348     public String JavaDoc getNodeValue(String JavaDoc[] xPath, String JavaDoc defaultValue) {
349         return getValue(getNode(xPath), defaultValue);
350     }
351
352     /**
353      * INTERNAL:
354      */

355     public String JavaDoc getPackage() {
356         return m_defaultPackage;
357     }
358     
359     /**
360      * INTERNAL:
361      */

362     public NodeList JavaDoc getTextColumnNodes(Node JavaDoc node) {
363         return getNodes(node, new String JavaDoc[] {XMLConstants.COLUMN_NAME, XMLConstants.TEXT});
364     }
365
366     /**
367      * INTERNAL:
368      */

369     private boolean getValue(Node JavaDoc node, boolean defaultValue) {
370         if (node == null) {
371             return defaultValue;
372         } else {
373             return Boolean.parseBoolean(node.getNodeValue());
374         }
375     }
376     
377     /**
378      * INTERNAL:
379      */

380     private Class JavaDoc getValue(Node JavaDoc node, Class JavaDoc defaultValue) {
381         if (node == null) {
382             return defaultValue;
383         } else {
384             return getClassForName(node.getNodeValue());
385         }
386     }
387     
388     /**
389      * INTERNAL:
390      */

391     private int getValue(Node JavaDoc node, int defaultValue) {
392         if (node == null) {
393             return defaultValue;
394         } else {
395             return Integer.parseInt(node.getNodeValue());
396         }
397     }
398     
399     /**
400      * INTERNAL:
401      */

402     private String JavaDoc getValue(Node JavaDoc node, String JavaDoc defaultValue) {
403         if (node == null) {
404             return defaultValue;
405         } else {
406             String JavaDoc value = node.getNodeValue();
407             if (value == null) {
408                 return defaultValue;
409             } else {
410                 return value;
411             }
412         }
413     }
414     
415     /**
416      * INTERNAL:
417      */

418     public boolean hasNode(Node JavaDoc node, String JavaDoc xPath) {
419         return getNode(node, xPath) != null;
420     }
421     
422     /**
423      * INTERNAL:
424      * Locate a node in the DOM tree for a given class.
425      */

426     public Node JavaDoc locateEmbeddableNode(Class JavaDoc cls) {
427         return locateNode(cls, XMLConstants.EMBEDDABLE);
428     }
429     
430     /**
431      * INTERNAL:
432      * Locate a node in the DOM tree for a given class.
433      */

434     public Node JavaDoc locateEntityNode(Class JavaDoc cls) {
435         return locateNode(cls, XMLConstants.ENTITY);
436     }
437     
438     /**
439      * INTERNAL:
440      * Locate a node in the DOM tree for a given class.
441      */

442     public Node JavaDoc locateMappedSuperclassNode(Class JavaDoc cls) {
443         return locateNode(cls, XMLConstants.MAPPED_SUPERCLASS);
444     }
445     
446     /**
447      * INTERNAL:
448      * Locate a node in the DOM tree for the given class. Will look for
449      * an entity, embeddable, or mapped-superclass node with @class matching
450      * the class name.
451      */

452     public Node JavaDoc locateNode(Class JavaDoc cls) {
453         Node JavaDoc result = null;
454         result = locateEntityNode(cls);
455         
456         if (result == null) {
457             result = locateMappedSuperclassNode(cls);
458         }
459         
460         if (result == null) {
461             result = locateEmbeddableNode(cls);
462         }
463         
464         return result;
465     }
466     
467     /**
468      * INTERNAL:
469      * Locate a node in the DOM tree for a given class.
470      * The search string should be used as follows:
471      * - For an entity: XMLConstants.ENTITY
472      * - For an embeddable: XMLConstants.EMBEDDABLE
473      * - For a mapped superclass: XMLConstants.MAPPED_SUPERCLASS
474      * Or call locateNode which will check them all. For efficiency, it looks
475      * for an entity first.
476      */

477     private Node JavaDoc locateNode(Class JavaDoc cls, String JavaDoc searchString) {
478         NodeList JavaDoc nodes = getNodes(m_document, XMLConstants.ENTITY_MAPPINGS, searchString);
479
480         if (nodes != null) {
481             for (int i = 0; i < nodes.getLength(); i++) {
482                 Node JavaDoc node = nodes.item(i);
483                 // process @class (required)
484
if (getClassNameForNode(node).equals(cls.getName())) {
485                     return node;
486                 }
487             }
488         }
489         
490         return null;
491     }
492
493     /**
494      * INTERNAL:
495      * Locate a node in the DOM tree for a given attribute name.
496      */

497      // WIP - method may go away.
498
public Node JavaDoc locateNodeForAttribute(Node JavaDoc node, String JavaDoc attributeName) {
499         NodeList JavaDoc attributeNodes = getNodes(node, XMLConstants.ATTRIBUTES, XMLConstants.ALL_CHILDREN);
500
501         if (attributeNodes != null) {
502             Node JavaDoc attributeNode;
503             for (int i = 0; i < attributeNodes.getLength(); i++) {
504                 attributeNode = attributeNodes.item(i);
505                 // process @name (required)
506
if (getNodeValue(attributeNode, XMLConstants.ATT_NAME).equals(attributeName)) {
507                     return attributeNode;
508                 }
509             }
510         }
511         
512         return null;
513     }
514
515     /**
516      * INTERNAL:
517      * Return the root entity in an entity class hierarchy
518      */

519     public Class JavaDoc locateRootEntity(Class JavaDoc entityClass) {
520         Class JavaDoc superclass = entityClass.getSuperclass();
521         if (superclass != null) {
522             Node JavaDoc entityNode = locateEntityNode(superclass);
523             
524             if (entityNode != null) {
525                 return locateRootEntity(superclass);
526             }
527         }
528         
529         return entityClass;
530     }
531
532     /**
533      * INTERNAL:
534      * Indicates if a given node has a primary-key-join-column sub-element.
535      */

536     public boolean nodeHasPrimaryKeyJoinColumns(Node JavaDoc node) {
537         if (node == null) {
538             return false;
539         }
540
541         NodeList JavaDoc nodes = getNodes(node, XMLConstants.PK_JOIN_COLUMN);
542         return (nodes != null && nodes.getLength() > 0);
543     }
544     
545     /**
546      * INTERNAL:
547      * Indicates if a given node has a primary-key-join-column sub-element.
548      */

549     public boolean nodeHasJoinColumns(Node JavaDoc node) {
550         if (node == null) {
551             return false;
552         }
553
554         NodeList JavaDoc nodes = getNodes(node, XMLConstants.JOIN_COLUMN);
555         return (nodes != null && nodes.getLength() > 0);
556     }
557     
558     /**
559      * INTERNAL:
560      * Build a DOM from an instance document using the provided URL.
561      */

562     public static Document JavaDoc parseDocument(InputStream JavaDoc xmlDocumentInputStream, String JavaDoc documentName, ClassLoader JavaDoc loader) {
563         DocumentBuilderFactory JavaDoc dbf = DocumentBuilderFactory.newInstance();
564         dbf.setNamespaceAware(true);
565         dbf.setAttribute(XMLConstants.SCHEMA_LANGUAGE, XMLConstants.XML_SCHEMA);
566         dbf.setValidating(true);
567         
568         // attempt to load the schema from the classpath
569
URL JavaDoc schemaURL = loader.getResource(XMLConstants.ORM_SCHEMA_NAME);
570         if (schemaURL != null) {
571             dbf.setAttribute(XMLConstants.JAXP_SCHEMA_SOURCE, schemaURL.toString());
572         }
573         
574         // create a document builder
575
DocumentBuilder JavaDoc db;
576         try {
577             db = dbf.newDocumentBuilder();
578         } catch (ParserConfigurationException JavaDoc pex) {
579             throw XMLParseException.exceptionCreatingDocumentBuilder(documentName, pex);
580         }
581         
582         // set the parse exception handler
583
XMLExceptionHandler xmlExceptionHandler = new XMLExceptionHandler();
584         db.setErrorHandler(xmlExceptionHandler);
585         
586         // parse the document
587
Document JavaDoc doc = null;
588         try {
589             doc = db.parse(xmlDocumentInputStream);
590         } catch (IOException JavaDoc ioex) {
591             throw XMLParseException.exceptionReadingXMLDocument(documentName, ioex);
592         } catch (SAXException JavaDoc saxex) {
593             // XMLExceptionHandler will handle parse exceptions
594
}
595         
596         XMLException xmlEx = xmlExceptionHandler.getXMLException();
597         if (xmlEx != null) {
598             throw ValidationException.invalidEntityMappingsDocument(documentName, xmlEx);
599         }
600         
601         return doc;
602     }
603     
604     /**
605      * INTERNAL:
606      * Update the loader after it changes.
607      */

608     public void setLoader(ClassLoader JavaDoc loader) {
609         m_loader = loader;
610     }
611 }
612
Popular Tags