Source Code Cross Referenced for DOMUtil.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » xml » dom » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » apache lenya 2.0 » org.apache.cocoon.xml.dom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.cocoon.xml.dom;
0018:
0019:        import org.apache.cocoon.ProcessingException;
0020:        import org.apache.cocoon.xml.IncludeXMLConsumer;
0021:        import org.apache.cocoon.xml.XMLUtils;
0022:
0023:        import org.apache.commons.lang.BooleanUtils;
0024:        import org.apache.commons.lang.StringUtils;
0025:        import org.apache.excalibur.source.SourceParameters;
0026:        import org.apache.excalibur.xml.sax.SAXParser;
0027:        import org.apache.excalibur.xml.sax.XMLizable;
0028:        import org.apache.excalibur.xml.xpath.NodeListImpl;
0029:        import org.apache.excalibur.xml.xpath.XPathProcessor;
0030:        import org.apache.excalibur.xml.xpath.XPathUtil;
0031:        import org.apache.xpath.XPathAPI;
0032:        import org.w3c.dom.DOMException;
0033:        import org.w3c.dom.Document;
0034:        import org.w3c.dom.DocumentFragment;
0035:        import org.w3c.dom.Element;
0036:        import org.w3c.dom.NamedNodeMap;
0037:        import org.w3c.dom.Node;
0038:        import org.w3c.dom.NodeList;
0039:        import org.xml.sax.InputSource;
0040:        import org.xml.sax.SAXException;
0041:
0042:        import javax.xml.parsers.DocumentBuilder;
0043:        import javax.xml.parsers.DocumentBuilderFactory;
0044:        import javax.xml.parsers.ParserConfigurationException;
0045:        import javax.xml.transform.OutputKeys;
0046:        import javax.xml.transform.TransformerException;
0047:        import java.io.IOException;
0048:        import java.io.Reader;
0049:        import java.io.StringReader;
0050:        import java.io.StringWriter;
0051:        import java.io.Writer;
0052:        import java.util.Collection;
0053:        import java.util.Iterator;
0054:        import java.util.Map;
0055:        import java.util.Properties;
0056:        import java.util.StringTokenizer;
0057:
0058:        /**
0059:         * This class is a utility class for miscellaneous DOM functions, like getting
0060:         * and setting values of nodes.
0061:         * 
0062:         * @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
0063:         * @version $Id: DOMUtil.java 433543 2006-08-22 06:22:54Z crossley $
0064:         */
0065:        public final class DOMUtil {
0066:
0067:            private static final String XPATH_IS_REQUIRED = "XPath is required.";
0068:
0069:            /**
0070:             * Get the owner of the DOM document belonging to the node. This works even
0071:             * if the node is the document itself.
0072:             * 
0073:             * @param node
0074:             *            The node.
0075:             * @return The corresponding document.
0076:             */
0077:            public static Document getOwnerDocument(Node node) {
0078:                if (node.getNodeType() == Node.DOCUMENT_NODE) {
0079:                    return (Document) node;
0080:                } else {
0081:                    return node.getOwnerDocument();
0082:                }
0083:            }
0084:
0085:            /**
0086:             * Get the value of the node specified by the XPath. This works similar to
0087:             * &lt;xsl:value-of&gt;. If the node does not exist <CODE>null</CODE> is
0088:             * returned.
0089:             * 
0090:             * @param root
0091:             *            The node to start the search.
0092:             * @param path
0093:             *            XPath search expression.
0094:             * @return The value of the node or <CODE>null</CODE>
0095:             */
0096:            public static String getValueOfNode(XPathProcessor processor,
0097:                    Node root, String path) throws ProcessingException {
0098:                if (path == null) {
0099:                    throw new ProcessingException(XPATH_IS_REQUIRED);
0100:                }
0101:                if (root != null) {
0102:                    path = StringUtils.strip(path, "/");
0103:                    Node node = XPathUtil.searchSingleNode(processor, root,
0104:                            path);
0105:                    if (node != null) {
0106:                        return getValueOfNode(node);
0107:                    }
0108:                }
0109:                return null;
0110:            }
0111:
0112:            /**
0113:             * Get the value of the node specified by the XPath. This works similar to
0114:             * &lt;xsl:value-of&gt;. If the node is not found the <CODE>defaultValue</CODE>
0115:             * is returned.
0116:             * 
0117:             * @param root
0118:             *            The node to start the search.
0119:             * @param path
0120:             *            XPath search expression.
0121:             * @param defaultValue
0122:             *            The default value if the node does not exist.
0123:             * @return The value of the node or <CODE>defaultValue</CODE>
0124:             */
0125:            public static String getValueOfNode(XPathProcessor processor,
0126:                    Node root, String path, String defaultValue)
0127:                    throws ProcessingException {
0128:                String value = getValueOfNode(processor, root, path);
0129:                if (value == null)
0130:                    value = defaultValue;
0131:
0132:                return value;
0133:            }
0134:
0135:            /**
0136:             * Get the boolean value of the node specified by the XPath. This works
0137:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
0138:             * value is converted to a boolean, e.g. "true" or "false" as value will
0139:             * result into the corresponding boolean values.
0140:             * 
0141:             * @param root
0142:             *            The node to start the search.
0143:             * @param path
0144:             *            XPath search expression.
0145:             * @return The boolean value of the node.
0146:             * @throws ProcessingException
0147:             *             If the node is not found.
0148:             */
0149:            public static boolean getValueOfNodeAsBoolean(
0150:                    XPathProcessor processor, Node root, String path)
0151:                    throws ProcessingException {
0152:                String value = getValueOfNode(processor, root, path);
0153:                if (value == null) {
0154:                    throw new ProcessingException("No such node: " + path);
0155:                }
0156:                return Boolean.valueOf(value).booleanValue();
0157:            }
0158:
0159:            /**
0160:             * Get the boolean value of the node specified by the XPath. This works
0161:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
0162:             * value is converted to a boolean, e.g. "true" or "false" as value will
0163:             * result into the corresponding boolean values. If the node does not exist,
0164:             * the <CODE>defaultValue</CODE> is returned.
0165:             * 
0166:             * @param root
0167:             *            The node to start the search.
0168:             * @param path
0169:             *            XPath search expression.
0170:             * @param defaultValue
0171:             *            Default boolean value.
0172:             * @return The value of the node or <CODE>defaultValue</CODE>
0173:             */
0174:            public static boolean getValueOfNodeAsBoolean(
0175:                    XPathProcessor processor, Node root, String path,
0176:                    boolean defaultValue) throws ProcessingException {
0177:                String value = getValueOfNode(processor, root, path);
0178:                if (value != null) {
0179:                    return BooleanUtils.toBoolean(value);
0180:                }
0181:                return defaultValue;
0182:            }
0183:
0184:            /**
0185:             * Get the value of the DOM node. The value of a node is the content of the
0186:             * first text node. If the node has no text nodes, <code>null</code> is
0187:             * returned.
0188:             */
0189:            public static String getValueOfNode(Node node) {
0190:                if (node != null) {
0191:                    if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
0192:                        return node.getNodeValue();
0193:                    } else {
0194:                        node.normalize();
0195:                        NodeList childs = node.getChildNodes();
0196:                        int i = 0;
0197:                        int length = childs.getLength();
0198:                        while (i < length) {
0199:                            if (childs.item(i).getNodeType() == Node.TEXT_NODE) {
0200:                                return childs.item(i).getNodeValue().trim();
0201:                            } else {
0202:                                i++;
0203:                            }
0204:                        }
0205:                    }
0206:                }
0207:                return null;
0208:            }
0209:
0210:            /**
0211:             * Get the value of the node. The value of the node is the content of the
0212:             * first text node. If the node has no text nodes the <CODE>defaultValue</CODE>
0213:             * is returned.
0214:             */
0215:            public static String getValueOfNode(Node node, String defaultValue) {
0216:                return StringUtils.defaultString(getValueOfNode(node),
0217:                        defaultValue);
0218:            }
0219:
0220:            /**
0221:             * Set the value of the DOM node. All current children of the node are
0222:             * removed and a new text node with the value is appended.
0223:             */
0224:            public static void setValueOfNode(Node node, String value) {
0225:                if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
0226:                    node.setNodeValue(value);
0227:                } else {
0228:                    while (node.hasChildNodes()) {
0229:                        node.removeChild(node.getFirstChild());
0230:                    }
0231:                    node.appendChild(node.getOwnerDocument().createTextNode(
0232:                            value));
0233:                }
0234:            }
0235:
0236:            /** XML definition for a document */
0237:            private static final String XML_DEFINITION = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
0238:
0239:            private static final String XML_ROOT_DEFINITION = XML_DEFINITION
0240:                    + "<root>";
0241:
0242:            /**
0243:             * Get a document fragment from a <code>Reader</code>. The reader must
0244:             * provide valid XML, but it is allowed that the XML has more than one root
0245:             * node. This xml is parsed by the specified parser instance and a DOM
0246:             * DocumentFragment is created.
0247:             */
0248:            public static DocumentFragment getDocumentFragment(
0249:                    SAXParser parser, Reader stream) throws ProcessingException {
0250:                DocumentFragment frag = null;
0251:
0252:                Writer writer;
0253:                Reader reader;
0254:                boolean removeRoot = true;
0255:
0256:                try {
0257:                    // create a writer,
0258:                    // write the root element, then the input from the
0259:                    // reader
0260:                    writer = new StringWriter();
0261:
0262:                    writer.write(XML_ROOT_DEFINITION);
0263:                    char[] cbuf = new char[16384];
0264:                    int len;
0265:                    do {
0266:                        len = stream.read(cbuf, 0, 16384);
0267:                        if (len != -1) {
0268:                            writer.write(cbuf, 0, len);
0269:                        }
0270:                    } while (len != -1);
0271:                    writer.write("</root>");
0272:
0273:                    // now test if xml input start with <?xml
0274:                    String xml = writer.toString();
0275:                    String searchString = XML_ROOT_DEFINITION + "<?xml ";
0276:                    if (xml.startsWith(searchString)) {
0277:                        // now remove the surrounding root element
0278:                        xml = xml.substring(XML_ROOT_DEFINITION.length(), xml
0279:                                .length() - 7);
0280:                        removeRoot = false;
0281:                    }
0282:
0283:                    reader = new StringReader(xml);
0284:
0285:                    InputSource input = new InputSource(reader);
0286:
0287:                    DOMBuilder builder = new DOMBuilder();
0288:                    builder.startDocument();
0289:                    builder.startElement("", "root", "root",
0290:                            XMLUtils.EMPTY_ATTRIBUTES);
0291:
0292:                    IncludeXMLConsumer filter = new IncludeXMLConsumer(builder,
0293:                            builder);
0294:                    parser.parse(input, filter);
0295:
0296:                    builder.endElement("", "root", "root");
0297:                    builder.endDocument();
0298:
0299:                    // Create Document Fragment, remove <root>
0300:                    final Document doc = builder.getDocument();
0301:                    frag = doc.createDocumentFragment();
0302:                    final Node root = doc.getDocumentElement().getFirstChild();
0303:                    root.normalize();
0304:                    if (removeRoot == false) {
0305:                        root.getParentNode().removeChild(root);
0306:                        frag.appendChild(root);
0307:                    } else {
0308:                        Node child;
0309:                        while (root.hasChildNodes()) {
0310:                            child = root.getFirstChild();
0311:                            root.removeChild(child);
0312:                            frag.appendChild(child);
0313:                        }
0314:                    }
0315:                } catch (SAXException sax) {
0316:                    throw new ProcessingException("SAXException: " + sax, sax);
0317:                } catch (IOException ioe) {
0318:                    throw new ProcessingException("IOException: " + ioe, ioe);
0319:                }
0320:                return frag;
0321:            }
0322:
0323:            /**
0324:             * Create a parameter object from xml. The xml is flat and consists of
0325:             * elements which all have exactly one text node: <parone>value_one<parone>
0326:             * <partwo>value_two<partwo> A parameter can occur more than once with
0327:             * different values. If <CODE>source</CODE> is not specified a new
0328:             * parameter object is created otherwise the parameters are added to source.
0329:             */
0330:            public static SourceParameters createParameters(Node fragment,
0331:                    SourceParameters source) {
0332:                SourceParameters par = (source == null ? new SourceParameters()
0333:                        : source);
0334:                if (fragment != null) {
0335:                    NodeList childs = fragment.getChildNodes();
0336:                    if (childs != null) {
0337:                        Node current;
0338:                        for (int i = 0; i < childs.getLength(); i++) {
0339:                            current = childs.item(i);
0340:
0341:                            // only element nodes
0342:                            if (current.getNodeType() == Node.ELEMENT_NODE) {
0343:                                current.normalize();
0344:                                NodeList valueChilds = current.getChildNodes();
0345:                                String key;
0346:                                StringBuffer valueBuffer;
0347:                                String value;
0348:
0349:                                key = current.getNodeName();
0350:                                valueBuffer = new StringBuffer();
0351:                                for (int m = 0; m < valueChilds.getLength(); m++) {
0352:                                    current = valueChilds.item(m); // attention: current is reused here!
0353:                                    if (current.getNodeType() == Node.TEXT_NODE) { // only text nodes
0354:                                        if (valueBuffer.length() > 0)
0355:                                            valueBuffer.append(' ');
0356:                                        valueBuffer.append(current
0357:                                                .getNodeValue());
0358:                                    }
0359:                                }
0360:                                value = valueBuffer.toString().trim();
0361:                                if (key != null && value.length() > 0) {
0362:                                    par.setParameter(key, value);
0363:                                }
0364:                            }
0365:                        }
0366:                    }
0367:                }
0368:                return par;
0369:            }
0370:
0371:            /**
0372:             * Create a string from a DOM document fragment. Only the top level text
0373:             * nodes are chained together to build the text.
0374:             */
0375:            public static String createText(DocumentFragment fragment) {
0376:                StringBuffer value = new StringBuffer();
0377:                if (fragment != null) {
0378:                    NodeList childs = fragment.getChildNodes();
0379:                    if (childs != null) {
0380:                        Node current;
0381:
0382:                        for (int i = 0; i < childs.getLength(); i++) {
0383:                            current = childs.item(i);
0384:
0385:                            // only text nodes
0386:                            if (current.getNodeType() == Node.TEXT_NODE) {
0387:                                if (value.length() > 0)
0388:                                    value.append(' ');
0389:                                value.append(current.getNodeValue());
0390:                            }
0391:                        }
0392:                    }
0393:                }
0394:                return value.toString().trim();
0395:            }
0396:
0397:            /**
0398:             * Compare all attributes of two elements. This method returns true only if
0399:             * both nodes have the same number of attributes and the same attributes
0400:             * with equal values. Namespace definition nodes are ignored
0401:             */
0402:            public static boolean compareAttributes(Element first,
0403:                    Element second) {
0404:                NamedNodeMap attr1 = first.getAttributes();
0405:                NamedNodeMap attr2 = second.getAttributes();
0406:                String value;
0407:
0408:                if (attr1 == null && attr2 == null)
0409:                    return true;
0410:                int attr1Len = (attr1 == null ? 0 : attr1.getLength());
0411:                int attr2Len = (attr2 == null ? 0 : attr2.getLength());
0412:                if (attr1Len > 0) {
0413:                    int l = attr1.getLength();
0414:                    for (int i = 0; i < l; i++) {
0415:                        if (attr1.item(i).getNodeName().startsWith("xmlns:"))
0416:                            attr1Len--;
0417:                    }
0418:                }
0419:                if (attr2Len > 0) {
0420:                    int l = attr2.getLength();
0421:                    for (int i = 0; i < l; i++) {
0422:                        if (attr2.item(i).getNodeName().startsWith("xmlns:"))
0423:                            attr2Len--;
0424:                    }
0425:                }
0426:                if (attr1Len != attr2Len)
0427:                    return false;
0428:                int i, l;
0429:                int m, l2;
0430:                i = 0;
0431:                l = attr1.getLength();
0432:                l2 = attr2.getLength();
0433:                boolean ok = true;
0434:                // each attribute of first must be in second with the same value
0435:                while (i < l && ok) {
0436:                    value = attr1.item(i).getNodeName();
0437:                    if (value.startsWith("xmlns:") == false) {
0438:                        ok = false;
0439:                        m = 0;
0440:                        while (m < l2 && ok == false) {
0441:                            if (attr2.item(m).getNodeName().equals(value)) {
0442:                                // same name, same value?
0443:                                ok = attr1.item(i).getNodeValue().equals(
0444:                                        attr2.item(m).getNodeValue());
0445:                            }
0446:                            m++;
0447:                        }
0448:                    }
0449:
0450:                    i++;
0451:                }
0452:                return ok;
0453:            }
0454:
0455:            /**
0456:             * Implementation for <code>String</code> : outputs characters
0457:             * representing the value.
0458:             * 
0459:             * @param parent
0460:             *            The node getting the value
0461:             * @param text
0462:             *            the value
0463:             */
0464:            public static void valueOf(Node parent, String text)
0465:                    throws ProcessingException {
0466:                if (text != null) {
0467:                    parent.appendChild(parent.getOwnerDocument()
0468:                            .createTextNode(text));
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Implementation for <code>XMLizable</code> : outputs the value by
0474:             * calling <code>v.toSax(contentHandler)</code>.
0475:             * 
0476:             * @param parent
0477:             *            The node getting the value
0478:             * @param v
0479:             *            the XML fragment
0480:             */
0481:            public static void valueOf(Node parent, XMLizable v)
0482:                    throws ProcessingException {
0483:                if (v != null) {
0484:                    DOMBuilder builder = new DOMBuilder(parent);
0485:                    try {
0486:                        v.toSAX(builder);
0487:                    } catch (SAXException e) {
0488:                        throw new ProcessingException(e);
0489:                    }
0490:                }
0491:            }
0492:
0493:            /**
0494:             * Implementation for <code>org.w3c.dom.Node</code> : converts the Node to
0495:             * a SAX event stream.
0496:             * 
0497:             * @param parent
0498:             *            The node getting the value
0499:             * @param v
0500:             *            the value
0501:             */
0502:            public static void valueOf(Node parent, Node v)
0503:                    throws ProcessingException {
0504:                if (v != null) {
0505:                    parent.appendChild(parent.getOwnerDocument().importNode(v,
0506:                            true));
0507:                }
0508:            }
0509:
0510:            /**
0511:             * Implementation for <code>java.util.Collection</code> : outputs the
0512:             * value by calling {@link #valueOf(Node, Object)} on each element of the
0513:             * collection.
0514:             * 
0515:             * @param parent
0516:             *            The node getting the value
0517:             * @param v
0518:             *            the XML fragment
0519:             */
0520:            public static void valueOf(Node parent, Collection v)
0521:                    throws ProcessingException {
0522:                if (v != null) {
0523:                    Iterator iterator = v.iterator();
0524:                    while (iterator.hasNext()) {
0525:                        valueOf(parent, iterator.next());
0526:                    }
0527:                }
0528:            }
0529:
0530:            /**
0531:             * Implementation for <code>java.util.Map</code> : For each entry an
0532:             * element is created with the childs key and value Outputs the value and
0533:             * the key by calling {@link #valueOf(Node, Object)} on each value and key
0534:             * of the Map.
0535:             * 
0536:             * @param parent
0537:             *            The node getting the value
0538:             * @param v
0539:             *            the Map
0540:             */
0541:            public static void valueOf(Node parent, Map v)
0542:                    throws ProcessingException {
0543:                if (v != null) {
0544:                    Node mapNode = parent.getOwnerDocument().createElementNS(
0545:                            null, "java.util.map");
0546:                    parent.appendChild(mapNode);
0547:                    for (Iterator iter = v.entrySet().iterator(); iter
0548:                            .hasNext();) {
0549:                        Map.Entry me = (Map.Entry) iter.next();
0550:
0551:                        Node entryNode = mapNode.getOwnerDocument()
0552:                                .createElementNS(null, "entry");
0553:                        mapNode.appendChild(entryNode);
0554:
0555:                        Node keyNode = entryNode.getOwnerDocument()
0556:                                .createElementNS(null, "key");
0557:                        entryNode.appendChild(keyNode);
0558:                        valueOf(keyNode, me.getKey());
0559:
0560:                        Node valueNode = entryNode.getOwnerDocument()
0561:                                .createElementNS(null, "value");
0562:                        entryNode.appendChild(valueNode);
0563:                        valueOf(valueNode, me.getValue());
0564:                    }
0565:                }
0566:            }
0567:
0568:            /**
0569:             * Implementation for <code>Object</code> depending on its class :
0570:             * <ul>
0571:             * <li>if it's an array, call {@link #valueOf(Node, Object)} on all its
0572:             * elements,</li>
0573:             * <li>if it's class has a specific {@link #valueOf(Node, Object)}
0574:             * implementation, use it,</li>
0575:             * <li>else, output it's string representation.</li>
0576:             * </ul>
0577:             * 
0578:             * @param parent
0579:             *            The node getting the value
0580:             * @param v
0581:             *            the value
0582:             */
0583:            public static void valueOf(Node parent, Object v)
0584:                    throws ProcessingException {
0585:                if (v == null) {
0586:                    return;
0587:                }
0588:
0589:                // Array: recurse over each element
0590:                if (v.getClass().isArray()) {
0591:                    Object[] elements = (Object[]) v;
0592:
0593:                    for (int i = 0; i < elements.length; i++) {
0594:                        valueOf(parent, elements[i]);
0595:                    }
0596:                    return;
0597:                }
0598:
0599:                // Check handled object types in case they were not typed in the XSP
0600:
0601:                // XMLizable
0602:                if (v instanceof  XMLizable) {
0603:                    valueOf(parent, (XMLizable) v);
0604:                    return;
0605:                }
0606:
0607:                // Node
0608:                if (v instanceof  Node) {
0609:                    valueOf(parent, (Node) v);
0610:                    return;
0611:                }
0612:
0613:                // Collection
0614:                if (v instanceof  Collection) {
0615:                    valueOf(parent, (Collection) v);
0616:                    return;
0617:                }
0618:
0619:                // Map
0620:                if (v instanceof  Map) {
0621:                    valueOf(parent, (Map) v);
0622:                    return;
0623:                }
0624:
0625:                // Give up: hope it's a string or has a meaningful string representation
0626:                valueOf(parent, String.valueOf(v));
0627:            }
0628:
0629:            /**
0630:             * Use an XPath string to select a single node. XPath namespace prefixes are
0631:             * resolved from the context node, which may not be what you want (see the
0632:             * next method).
0633:             * 
0634:             * @param contextNode
0635:             *            The node to start searching from.
0636:             * @param str
0637:             *            A valid XPath string.
0638:             * @param processor
0639:             *            The XPath processor to use
0640:             * @return The first node found that matches the XPath, or null.
0641:             * 
0642:             * @throws TransformerException
0643:             */
0644:            public static Node getSingleNode(Node contextNode, String str,
0645:                    XPathProcessor processor) throws TransformerException {
0646:                String[] pathComponents = buildPathArray(str);
0647:                if (pathComponents == null) {
0648:                    return processor.selectSingleNode(contextNode, str);
0649:                } else {
0650:                    return getFirstNodeFromPath(contextNode, pathComponents,
0651:                            false);
0652:                }
0653:            }
0654:
0655:            /**
0656:             * Use an XPath string to select a single node. XPath namespace prefixes are
0657:             * resolved from the context node, which may not be what you want (see the
0658:             * next method).
0659:             * 
0660:             * @param contextNode
0661:             *            The node to start searching from.
0662:             * @param str
0663:             *            A valid XPath string.
0664:             * @return The first node found that matches the XPath, or null.
0665:             * 
0666:             * @throws TransformerException
0667:             * @deprecated. To be removed in 2.2.
0668:             */
0669:            public static Node getSingleNode(Node contextNode, String str)
0670:                    throws TransformerException {
0671:                String[] pathComponents = buildPathArray(str);
0672:                if (pathComponents == null) {
0673:                    return XPathAPI.selectSingleNode(contextNode, str);
0674:                } else {
0675:                    return getFirstNodeFromPath(contextNode, pathComponents,
0676:                            false);
0677:                }
0678:            }
0679:
0680:            /**
0681:             * Return the <CODE>Node</CODE> from the DOM Node <CODE>rootNode</CODE>
0682:             * using the XPath expression <CODE>path</CODE>. If the node does not
0683:             * exist, it is created and then returned. This is a very simple method for
0684:             * creating new nodes. If the XPath contains selectors ([,,,]) or "*" it is
0685:             * of course not possible to create the new node. So if you use such XPaths
0686:             * the node must exist beforehand. An simple exception is if the expression
0687:             * contains attribute test to values (e.g. [@id = 'du' and
0688:             * 
0689:             * @number = 'you'], the attributes with the given values are added. The
0690:             *         attributes must be separated with 'and'. Another problem are
0691:             *         namespaces: XPath requires sometimes selectors for namespaces,
0692:             *         e.g. : /*[namespace-uri()="uri" and local-name()="name"] Creating
0693:             *         such a node with a namespace is not possible right now as we use
0694:             *         a very simple XPath parser which is not able to parse all kinds
0695:             *         of selectors correctly.
0696:             * 
0697:             * @param rootNode
0698:             *            The node to start the search.
0699:             * @param path
0700:             *            XPath expression for searching the node.
0701:             * @return The node specified by the path.
0702:             * @throws ProcessingException
0703:             *             If no path is specified or the XPath engine fails.
0704:             * @deprecated To be removed in 2.2.
0705:             */
0706:            public static Node selectSingleNode(Node rootNode, String path)
0707:                    throws ProcessingException {
0708:                // Now we have to parse the string
0709:                // First test: path? rootNode?
0710:                if (path == null) {
0711:                    throw new ProcessingException(XPATH_IS_REQUIRED);
0712:                }
0713:                if (rootNode == null)
0714:                    return rootNode;
0715:
0716:                if (path.length() == 0 || path.equals("/"))
0717:                    return rootNode;
0718:
0719:                // now the first "quick" test is if the node exists using the
0720:                // full XPathAPI
0721:                try {
0722:                    Node testNode = getSingleNode(rootNode, path);
0723:                    if (testNode != null)
0724:                        return testNode;
0725:                } catch (TransformerException local) {
0726:                    throw new ProcessingException(
0727:                            "Transforming exception during selectSingleNode with path: '"
0728:                                    + path + "'. Exception: " + local, local);
0729:                }
0730:                // Remove leading "/" on both ends
0731:                path = StringUtils.strip(path, "/");
0732:
0733:                // now step through the nodes!
0734:                Node parent = rootNode;
0735:                int pos;
0736:                int posSelector;
0737:                do {
0738:                    pos = path.indexOf("/"); // get next separator
0739:                    posSelector = path.indexOf("[");
0740:                    if (posSelector != -1 && posSelector < pos) {
0741:                        posSelector = path.indexOf("]");
0742:                        pos = path.indexOf("/", posSelector);
0743:                    }
0744:
0745:                    String nodeName;
0746:                    boolean isAttribute = false;
0747:                    if (pos != -1) { // found separator
0748:                        nodeName = path.substring(0, pos); // string until "/"
0749:                        path = path.substring(pos + 1); // rest of string after "/"
0750:                    } else {
0751:                        nodeName = path;
0752:                    }
0753:
0754:                    // test for attribute spec
0755:                    if (nodeName.startsWith("@")) {
0756:                        isAttribute = true;
0757:                    }
0758:
0759:                    Node singleNode;
0760:                    try {
0761:                        singleNode = getSingleNode(parent, nodeName);
0762:                    } catch (TransformerException localException) {
0763:                        throw new ProcessingException(
0764:                                "XPathUtil.selectSingleNode: "
0765:                                        + localException.getMessage(),
0766:                                localException);
0767:                    }
0768:
0769:                    // create node if necessary
0770:                    if (singleNode == null) {
0771:                        Node newNode;
0772:                        // delete XPath selectors
0773:                        int posSelect = nodeName.indexOf("[");
0774:                        String XPathExp = null;
0775:                        if (posSelect != -1) {
0776:                            XPathExp = nodeName.substring(posSelect + 1,
0777:                                    nodeName.length() - 1);
0778:                            nodeName = nodeName.substring(0, posSelect);
0779:                        }
0780:                        if (isAttribute) {
0781:                            try {
0782:                                newNode = getOwnerDocument(rootNode)
0783:                                        .createAttributeNS(null,
0784:                                                nodeName.substring(1));
0785:                                ((Element) parent)
0786:                                        .setAttributeNodeNS((org.w3c.dom.Attr) newNode);
0787:                                parent = newNode;
0788:                            } catch (DOMException local) {
0789:                                throw new ProcessingException(
0790:                                        "Unable to create new DOM node: '"
0791:                                                + nodeName + "'.", local);
0792:                            }
0793:                        } else {
0794:                            try {
0795:                                newNode = getOwnerDocument(rootNode)
0796:                                        .createElementNS(null, nodeName);
0797:                            } catch (DOMException local) {
0798:                                throw new ProcessingException(
0799:                                        "Unable to create new DOM node: '"
0800:                                                + nodeName + "'.", local);
0801:                            }
0802:                            if (XPathExp != null) {
0803:                                java.util.List attrValuePairs = new java.util.ArrayList(
0804:                                        4);
0805:                                boolean noError = true;
0806:
0807:                                String attr;
0808:                                String value;
0809:                                // scan for attributes
0810:                                StringTokenizer tokenizer = new StringTokenizer(
0811:                                        XPathExp, "= ");
0812:                                while (tokenizer.hasMoreTokens()) {
0813:                                    attr = tokenizer.nextToken();
0814:                                    if (attr.startsWith("@")) {
0815:                                        if (tokenizer.hasMoreTokens()) {
0816:                                            value = tokenizer.nextToken();
0817:                                            if (value.startsWith("'")
0818:                                                    && value.endsWith("'"))
0819:                                                value = value.substring(1,
0820:                                                        value.length() - 1);
0821:                                            if (value.startsWith("\"")
0822:                                                    && value.endsWith("\""))
0823:                                                value = value.substring(1,
0824:                                                        value.length() - 1);
0825:                                            attrValuePairs.add(attr
0826:                                                    .substring(1));
0827:                                            attrValuePairs.add(value);
0828:                                        } else {
0829:                                            noError = false;
0830:                                        }
0831:                                    } else if (attr.trim().equals("and") == false) {
0832:                                        noError = false;
0833:                                    }
0834:                                }
0835:                                if (noError) {
0836:                                    for (int l = 0; l < attrValuePairs.size(); l = l + 2) {
0837:                                        ((Element) newNode).setAttributeNS(
0838:                                                null, (String) attrValuePairs
0839:                                                        .get(l),
0840:                                                (String) attrValuePairs
0841:                                                        .get(l + 1));
0842:                                    }
0843:                                }
0844:                            }
0845:                            parent.appendChild(newNode);
0846:                            parent = newNode;
0847:                        }
0848:                    } else {
0849:                        parent = singleNode;
0850:                    }
0851:                } while (pos != -1);
0852:                return parent;
0853:            }
0854:
0855:            /**
0856:             * Return the <CODE>Node</CODE> from the DOM Node <CODE>rootNode</CODE>
0857:             * using the XPath expression <CODE>path</CODE>. If the node does not
0858:             * exist, it is created and then returned. This is a very simple method for
0859:             * creating new nodes. If the XPath contains selectors ([,,,]) or "*" it is
0860:             * of course not possible to create the new node. So if you use such XPaths
0861:             * the node must exist beforehand. An simple exception is if the expression
0862:             * contains attribute test to values (e.g. [@id = 'du' and
0863:             * 
0864:             * @number = 'you'], the attributes with the given values are added. The
0865:             *         attributes must be separated with 'and'. Another problem are
0866:             *         namespaces: XPath requires sometimes selectors for namespaces,
0867:             *         e.g. : /*[namespace-uri()="uri" and local-name()="name"] Creating
0868:             *         such a node with a namespace is not possible right now as we use
0869:             *         a very simple XPath parser which is not able to parse all kinds
0870:             *         of selectors correctly.
0871:             * 
0872:             * @param rootNode
0873:             *            The node to start the search.
0874:             * @param path
0875:             *            XPath expression for searching the node.
0876:             * @param processor
0877:             *            The XPath processor to use
0878:             * @return The node specified by the path.
0879:             * @throws ProcessingException
0880:             *             If no path is specified or the XPath engine fails.
0881:             */
0882:            public static Node selectSingleNode(Node rootNode, String path,
0883:                    XPathProcessor processor) throws ProcessingException {
0884:                // Now we have to parse the string
0885:                // First test: path? rootNode?
0886:                if (path == null) {
0887:                    throw new ProcessingException(XPATH_IS_REQUIRED);
0888:                }
0889:                if (rootNode == null)
0890:                    return rootNode;
0891:
0892:                if (path.length() == 0 || path.equals("/"))
0893:                    return rootNode;
0894:
0895:                // now the first "quick" test is if the node exists using the
0896:                // full XPathAPI
0897:                try {
0898:                    Node testNode = getSingleNode(rootNode, path, processor);
0899:                    if (testNode != null)
0900:                        return testNode;
0901:                } catch (TransformerException local) {
0902:                    throw new ProcessingException(
0903:                            "Transforming exception during selectSingleNode with path: '"
0904:                                    + path + "'. Exception: " + local, local);
0905:                }
0906:
0907:                // remove leading "/" oon both ends
0908:                path = StringUtils.strip(path, "/");
0909:
0910:                // now step through the nodes!
0911:                Node parent = rootNode;
0912:                int pos;
0913:                int posSelector;
0914:                do {
0915:                    pos = path.indexOf("/"); // get next separator
0916:                    posSelector = path.indexOf("[");
0917:                    if (posSelector != -1 && posSelector < pos) {
0918:                        posSelector = path.indexOf("]");
0919:                        pos = path.indexOf("/", posSelector);
0920:                    }
0921:
0922:                    String nodeName;
0923:                    boolean isAttribute = false;
0924:                    if (pos != -1) { // found separator
0925:                        nodeName = path.substring(0, pos); // string until "/"
0926:                        path = path.substring(pos + 1); // rest of string after "/"
0927:                    } else {
0928:                        nodeName = path;
0929:                    }
0930:
0931:                    // test for attribute spec
0932:                    if (nodeName.startsWith("@")) {
0933:                        isAttribute = true;
0934:                    }
0935:
0936:                    Node singleNode;
0937:                    try {
0938:                        singleNode = getSingleNode(parent, nodeName, processor);
0939:                    } catch (TransformerException localException) {
0940:                        throw new ProcessingException(
0941:                                "XPathUtil.selectSingleNode: "
0942:                                        + localException.getMessage(),
0943:                                localException);
0944:                    }
0945:
0946:                    // create node if necessary
0947:                    if (singleNode == null) {
0948:                        Node newNode;
0949:                        // delete XPath selectors
0950:                        int posSelect = nodeName.indexOf("[");
0951:                        String XPathExp = null;
0952:                        if (posSelect != -1) {
0953:                            XPathExp = nodeName.substring(posSelect + 1,
0954:                                    nodeName.length() - 1);
0955:                            nodeName = nodeName.substring(0, posSelect);
0956:                        }
0957:                        if (isAttribute) {
0958:                            try {
0959:                                newNode = getOwnerDocument(rootNode)
0960:                                        .createAttributeNS(null,
0961:                                                nodeName.substring(1));
0962:                                ((Element) parent)
0963:                                        .setAttributeNodeNS((org.w3c.dom.Attr) newNode);
0964:                                parent = newNode;
0965:                            } catch (DOMException local) {
0966:                                throw new ProcessingException(
0967:                                        "Unable to create new DOM node: '"
0968:                                                + nodeName + "'.", local);
0969:                            }
0970:                        } else {
0971:                            try {
0972:                                newNode = getOwnerDocument(rootNode)
0973:                                        .createElementNS(null, nodeName);
0974:                            } catch (DOMException local) {
0975:                                throw new ProcessingException(
0976:                                        "Unable to create new DOM node: '"
0977:                                                + nodeName + "'.", local);
0978:                            }
0979:                            if (XPathExp != null) {
0980:                                java.util.List attrValuePairs = new java.util.ArrayList(
0981:                                        4);
0982:                                boolean noError = true;
0983:
0984:                                String attr;
0985:                                String value;
0986:                                // scan for attributes
0987:                                StringTokenizer tokenizer = new StringTokenizer(
0988:                                        XPathExp, "= ");
0989:                                while (tokenizer.hasMoreTokens()) {
0990:                                    attr = tokenizer.nextToken();
0991:                                    if (attr.startsWith("@")) {
0992:                                        if (tokenizer.hasMoreTokens()) {
0993:                                            value = tokenizer.nextToken();
0994:                                            if (value.startsWith("'")
0995:                                                    && value.endsWith("'"))
0996:                                                value = value.substring(1,
0997:                                                        value.length() - 1);
0998:                                            if (value.startsWith("\"")
0999:                                                    && value.endsWith("\""))
1000:                                                value = value.substring(1,
1001:                                                        value.length() - 1);
1002:                                            attrValuePairs.add(attr
1003:                                                    .substring(1));
1004:                                            attrValuePairs.add(value);
1005:                                        } else {
1006:                                            noError = false;
1007:                                        }
1008:                                    } else if (attr.trim().equals("and") == false) {
1009:                                        noError = false;
1010:                                    }
1011:                                }
1012:                                if (noError) {
1013:                                    for (int l = 0; l < attrValuePairs.size(); l = l + 2) {
1014:                                        ((Element) newNode).setAttributeNS(
1015:                                                null, (String) attrValuePairs
1016:                                                        .get(l),
1017:                                                (String) attrValuePairs
1018:                                                        .get(l + 1));
1019:                                    }
1020:                                }
1021:                            }
1022:                            parent.appendChild(newNode);
1023:                            parent = newNode;
1024:                        }
1025:                    } else {
1026:                        parent = singleNode;
1027:                    }
1028:                } while (pos != -1);
1029:                return parent;
1030:            }
1031:
1032:            /**
1033:             * Get the value of the node specified by the XPath. This works similar to
1034:             * &lt;xsl:value-of&gt;. If the node does not exist <CODE>null</CODE> is
1035:             * returned.
1036:             * 
1037:             * @param root
1038:             *            The node to start the search.
1039:             * @param path
1040:             *            XPath search expression.
1041:             * @return The value of the node or <CODE>null</CODE>
1042:             * @deprecated To be removed in 2.2.
1043:             */
1044:            public static String getValueOf(Node root, String path)
1045:                    throws ProcessingException {
1046:                if (path == null) {
1047:                    throw new ProcessingException(XPATH_IS_REQUIRED);
1048:                }
1049:                if (root == null)
1050:                    return null;
1051:                path = StringUtils.strip(path, "/");
1052:
1053:                try {
1054:                    Node node = getSingleNode(root, path);
1055:                    if (node != null) {
1056:                        return getValueOfNode(node);
1057:                    }
1058:                } catch (TransformerException localException) {
1059:                    throw new ProcessingException(
1060:                            "XPathUtil.selectSingleNode: "
1061:                                    + localException.getMessage(),
1062:                            localException);
1063:                }
1064:                return null;
1065:            }
1066:
1067:            /**
1068:             * Get the value of the node specified by the XPath. This works similar to
1069:             * &lt;xsl:value-of&gt;. If the node does not exist <CODE>null</CODE> is
1070:             * returned.
1071:             * 
1072:             * @param root
1073:             *            The node to start the search.
1074:             * @param path
1075:             *            XPath search expression.
1076:             * @param processor
1077:             *            The XPath processor to use
1078:             * @return The value of the node or <CODE>null</CODE>
1079:             */
1080:            public static String getValueOf(Node root, String path,
1081:                    XPathProcessor processor) throws ProcessingException {
1082:                if (path == null) {
1083:                    throw new ProcessingException(XPATH_IS_REQUIRED);
1084:                }
1085:                if (root == null)
1086:                    return null;
1087:                path = StringUtils.strip(path, "/");
1088:
1089:                try {
1090:                    Node node = getSingleNode(root, path, processor);
1091:                    if (node != null) {
1092:                        return getValueOfNode(node);
1093:                    }
1094:                } catch (TransformerException localException) {
1095:                    throw new ProcessingException(
1096:                            "XPathUtil.selectSingleNode: "
1097:                                    + localException.getMessage(),
1098:                            localException);
1099:                }
1100:                return null;
1101:            }
1102:
1103:            /**
1104:             * Get the value of the node specified by the XPath. This works similar to
1105:             * &lt;xsl:value-of&gt;. If the node is not found the <CODE>defaultValue</CODE>
1106:             * is returned.
1107:             * 
1108:             * @param root
1109:             *            The node to start the search.
1110:             * @param path
1111:             *            XPath search expression.
1112:             * @param defaultValue
1113:             *            The default value if the node does not exist.
1114:             * @return The value of the node or <CODE>defaultValue</CODE>
1115:             * @deprecated To be removed in 2.2.
1116:             */
1117:            public static String getValueOf(Node root, String path,
1118:                    String defaultValue) throws ProcessingException {
1119:                String value = getValueOf(root, path);
1120:                if (value == null) {
1121:                    value = defaultValue;
1122:                }
1123:                return value;
1124:            }
1125:
1126:            /**
1127:             * Get the value of the node specified by the XPath. This works similar to
1128:             * &lt;xsl:value-of&gt;. If the node is not found the <CODE>defaultValue</CODE>
1129:             * is returned.
1130:             * 
1131:             * @param root
1132:             *            The node to start the search.
1133:             * @param path
1134:             *            XPath search expression.
1135:             * @param defaultValue
1136:             *            The default value if the node does not exist.
1137:             * @param processor
1138:             *            The XPath Processor
1139:             * @return The value of the node or <CODE>defaultValue</CODE>
1140:             */
1141:            public static String getValueOf(Node root, String path,
1142:                    String defaultValue, XPathProcessor processor)
1143:                    throws ProcessingException {
1144:                String value = getValueOf(root, path, processor);
1145:                if (value == null) {
1146:                    value = defaultValue;
1147:                }
1148:                return value;
1149:            }
1150:
1151:            /**
1152:             * Get the boolean value of the node specified by the XPath. This works
1153:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
1154:             * value is converted to a boolean, e.g. "true" or "false" as value will
1155:             * result into the corresponding boolean values.
1156:             * 
1157:             * @param root
1158:             *            The node to start the search.
1159:             * @param path
1160:             *            XPath search expression.
1161:             * @return The boolean value of the node.
1162:             * @throws ProcessingException
1163:             *             If the node is not found.
1164:             * @deprecated To be removed in 2.2.
1165:             */
1166:            public static boolean getValueAsBooleanOf(Node root, String path)
1167:                    throws ProcessingException {
1168:                String value = getValueOf(root, path);
1169:                if (value != null) {
1170:                    return Boolean.valueOf(value).booleanValue();
1171:                } else {
1172:                    throw new ProcessingException("No such node: " + path);
1173:                }
1174:            }
1175:
1176:            /**
1177:             * Get the boolean value of the node specified by the XPath. This works
1178:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
1179:             * value is converted to a boolean, e.g. "true" or "false" as value will
1180:             * result into the corresponding boolean values.
1181:             * 
1182:             * @param root
1183:             *            The node to start the search.
1184:             * @param path
1185:             *            XPath search expression.
1186:             * @param processor
1187:             *            The XPath Processor
1188:             * @return The boolean value of the node.
1189:             * @throws ProcessingException
1190:             *             If the node is not found.
1191:             */
1192:            public static boolean getValueAsBooleanOf(Node root, String path,
1193:                    XPathProcessor processor) throws ProcessingException {
1194:                String value = getValueOf(root, path, processor);
1195:                if (value == null) {
1196:                    throw new ProcessingException("No such node: " + path);
1197:                }
1198:                return Boolean.valueOf(value).booleanValue();
1199:            }
1200:
1201:            /**
1202:             * Get the boolean value of the node specified by the XPath. This works
1203:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
1204:             * value is converted to a boolean, e.g. "true" or "false" as value will
1205:             * result into the corresponding boolean values. If the node does not exist,
1206:             * the <CODE>defaultValue</CODE> is returned.
1207:             * 
1208:             * @param root
1209:             *            The node to start the search.
1210:             * @param path
1211:             *            XPath search expression.
1212:             * @param defaultValue
1213:             *            Default boolean value.
1214:             * @return The value of the node or <CODE>defaultValue</CODE>
1215:             * @deprecated To be removed in 2.2.
1216:             */
1217:            public static boolean getValueAsBooleanOf(Node root, String path,
1218:                    boolean defaultValue) throws ProcessingException {
1219:                String value = getValueOf(root, path);
1220:                if (value != null) {
1221:                    return Boolean.valueOf(value).booleanValue();
1222:                }
1223:                return defaultValue;
1224:            }
1225:
1226:            /**
1227:             * Get the boolean value of the node specified by the XPath. This works
1228:             * similar to &lt;xsl:value-of&gt;. If the node exists and has a value this
1229:             * value is converted to a boolean, e.g. "true" or "false" as value will
1230:             * result into the corresponding boolean values. If the node does not exist,
1231:             * the <CODE>defaultValue</CODE> is returned.
1232:             * 
1233:             * @param root
1234:             *            The node to start the search.
1235:             * @param path
1236:             *            XPath search expression.
1237:             * @param defaultValue
1238:             *            Default boolean value.
1239:             * @param processor
1240:             *            The XPath Processor
1241:             * @return The value of the node or <CODE>defaultValue</CODE>
1242:             */
1243:            public static boolean getValueAsBooleanOf(Node root, String path,
1244:                    boolean defaultValue, XPathProcessor processor)
1245:                    throws ProcessingException {
1246:                String value = getValueOf(root, path, processor);
1247:                if (value != null) {
1248:                    return Boolean.valueOf(value).booleanValue();
1249:                }
1250:                return defaultValue;
1251:            }
1252:
1253:            /**
1254:             * Create a new empty DOM document.
1255:             */
1256:            public static Document createDocument() throws ProcessingException {
1257:                try {
1258:                    DocumentBuilderFactory documentFactory = DocumentBuilderFactory
1259:                            .newInstance();
1260:                    documentFactory.setNamespaceAware(true);
1261:                    documentFactory.setValidating(false);
1262:                    DocumentBuilder docBuilder = documentFactory
1263:                            .newDocumentBuilder();
1264:                    return docBuilder.newDocument();
1265:                } catch (ParserConfigurationException pce) {
1266:                    throw new ProcessingException("Creating document failed.",
1267:                            pce);
1268:                }
1269:            }
1270:
1271:            /**
1272:             * Use an XPath string to select a nodelist. XPath namespace prefixes are
1273:             * resolved from the contextNode.
1274:             * 
1275:             * @param contextNode
1276:             *            The node to start searching from.
1277:             * @param str
1278:             *            A valid XPath string.
1279:             * @return A NodeIterator, should never be null.
1280:             * 
1281:             * @throws TransformerException
1282:             * @deprecated To be removed in 2.2.
1283:             */
1284:            public static NodeList selectNodeList(Node contextNode, String str)
1285:                    throws TransformerException {
1286:                String[] pathComponents = buildPathArray(str);
1287:                if (pathComponents != null) {
1288:                    return getNodeListFromPath(contextNode, pathComponents);
1289:                }
1290:                return XPathAPI.selectNodeList(contextNode, str);
1291:            }
1292:
1293:            /**
1294:             * Use an XPath string to select a nodelist. XPath namespace prefixes are
1295:             * resolved from the contextNode.
1296:             * 
1297:             * @param contextNode
1298:             *            The node to start searching from.
1299:             * @param str
1300:             *            A valid XPath string.
1301:             * @param processor
1302:             *            The XPath Processor
1303:             * @return A NodeIterator, should never be null.
1304:             * 
1305:             * @throws TransformerException
1306:             */
1307:            public static NodeList selectNodeList(Node contextNode, String str,
1308:                    XPathProcessor processor) throws TransformerException {
1309:                String[] pathComponents = buildPathArray(str);
1310:                if (pathComponents != null) {
1311:                    return getNodeListFromPath(contextNode, pathComponents);
1312:                }
1313:                return processor.selectNodeList(contextNode, str);
1314:            }
1315:
1316:            /**
1317:             * Build the input for the get...FromPath methods. If the XPath expression
1318:             * cannot be handled by the methods, <code>null</code> is returned.
1319:             */
1320:            public static String[] buildPathArray(String xpath) {
1321:                String[] result = null;
1322:                if (xpath != null && xpath.charAt(0) != '/') {
1323:                    // test
1324:                    int components = 1;
1325:                    int i, l;
1326:                    l = xpath.length();
1327:                    boolean found = false;
1328:                    i = 0;
1329:                    while (i < l && found == false) {
1330:                        switch (xpath.charAt(i)) {
1331:                        case '[':
1332:                            found = true;
1333:                            break;
1334:                        case '(':
1335:                            found = true;
1336:                            break;
1337:                        case '*':
1338:                            found = true;
1339:                            break;
1340:                        case '@':
1341:                            found = true;
1342:                            break;
1343:                        case ':':
1344:                            found = true;
1345:                            break;
1346:                        case '/':
1347:                            components++;
1348:                        default:
1349:                            i++;
1350:                        }
1351:                    }
1352:                    if (found == false) {
1353:                        result = new String[components];
1354:                        if (components == 1) {
1355:                            result[components - 1] = xpath;
1356:                        } else {
1357:                            i = 0;
1358:                            int start = 0;
1359:                            components = 0;
1360:                            while (i < l) {
1361:                                if (xpath.charAt(i) == '/') {
1362:                                    result[components] = xpath.substring(start,
1363:                                            i);
1364:                                    start = i + 1;
1365:                                    components++;
1366:                                }
1367:                                i++;
1368:                            }
1369:                            result[components] = xpath.substring(start);
1370:                        }
1371:                    }
1372:                }
1373:                return result;
1374:            }
1375:
1376:            /**
1377:             * Use a path to select the first occurence of a node. The namespace of a
1378:             * node is ignored!
1379:             * 
1380:             * @param contextNode
1381:             *            The node starting the search.
1382:             * @param path
1383:             *            The path to search the node. The contextNode is searched for a
1384:             *            child named path[0], this node is searched for a child named
1385:             *            path[1]...
1386:             * @param create
1387:             *            If a child with the corresponding name is not found and create
1388:             *            is set, this node will be created.
1389:             */
1390:            public static Node getFirstNodeFromPath(Node contextNode,
1391:                    final String[] path, final boolean create) {
1392:                if (contextNode == null || path == null || path.length == 0)
1393:                    return contextNode;
1394:                // first test if the node exists
1395:                Node item = getFirstNodeFromPath(contextNode, path, 0);
1396:                if (item == null && create) {
1397:                    int i = 0;
1398:                    NodeList childs;
1399:                    boolean found;
1400:                    int m, l;
1401:                    while (contextNode != null && i < path.length) {
1402:                        childs = contextNode.getChildNodes();
1403:                        found = false;
1404:                        if (childs != null) {
1405:                            m = 0;
1406:                            l = childs.getLength();
1407:                            while (found == false && m < l) {
1408:                                item = childs.item(m);
1409:                                if (item.getNodeType() == Node.ELEMENT_NODE
1410:                                        && item.getLocalName().equals(path[i])) {
1411:                                    found = true;
1412:                                    contextNode = item;
1413:                                }
1414:                                m++;
1415:                            }
1416:                        }
1417:                        if (found == false) {
1418:                            Element e = contextNode.getOwnerDocument()
1419:                                    .createElementNS(null, path[i]);
1420:                            contextNode.appendChild(e);
1421:                            contextNode = e;
1422:                        }
1423:                        i++;
1424:                    }
1425:                    item = contextNode;
1426:                }
1427:                return item;
1428:            }
1429:
1430:            /**
1431:             * Private helper method for getFirstNodeFromPath()
1432:             */
1433:            private static Node getFirstNodeFromPath(final Node contextNode,
1434:                    final String[] path, final int startIndex) {
1435:                int i = 0;
1436:                NodeList childs;
1437:                boolean found;
1438:                int l;
1439:                Node item = null;
1440:
1441:                childs = contextNode.getChildNodes();
1442:                found = false;
1443:                if (childs != null) {
1444:                    i = 0;
1445:                    l = childs.getLength();
1446:                    while (found == false && i < l) {
1447:                        item = childs.item(i);
1448:                        if (item.getNodeType() == Node.ELEMENT_NODE
1449:                                && path[startIndex]
1450:                                        .equals(item.getLocalName() != null ? item
1451:                                                .getLocalName()
1452:                                                : item.getNodeName())) {
1453:                            if (startIndex == path.length - 1) {
1454:                                found = true;
1455:                            } else {
1456:                                item = getFirstNodeFromPath(item, path,
1457:                                        startIndex + 1);
1458:                                if (item != null)
1459:                                    found = true;
1460:                            }
1461:                        }
1462:                        if (found == false) {
1463:                            i++;
1464:                        }
1465:                    }
1466:                    if (found == false) {
1467:                        item = null;
1468:                    }
1469:                }
1470:                return item;
1471:            }
1472:
1473:            /**
1474:             * Use a path to select all occurences of a node. The namespace of a node is
1475:             * ignored!
1476:             * 
1477:             * @param contextNode
1478:             *            The node starting the search.
1479:             * @param path
1480:             *            The path to search the node. The contextNode is searched for a
1481:             *            child named path[0], this node is searched for a child named
1482:             *            path[1]...
1483:             */
1484:            public static NodeList getNodeListFromPath(Node contextNode,
1485:                    String[] path) {
1486:                if (contextNode == null)
1487:                    return new NodeListImpl();
1488:                if (path == null || path.length == 0) {
1489:                    return new NodeListImpl(new Node[] { contextNode });
1490:                }
1491:                NodeListImpl result = new NodeListImpl();
1492:                try {
1493:                    getNodesFromPath(result, contextNode, path, 0);
1494:                } catch (NullPointerException npe) {
1495:                    // this NPE is thrown because the parser is not configured
1496:                    // to use DOM Level 2
1497:                    throw new NullPointerException(
1498:                            "XMLUtil.getNodeListFromPath() did catch a NullPointerException."
1499:                                    + "This might be due to a missconfigured XML parser which does not use DOM Level 2."
1500:                                    + "Make sure that you use the XML parser shipped with Cocoon.");
1501:                }
1502:                return result;
1503:            }
1504:
1505:            /**
1506:             * Helper method for getNodeListFromPath()
1507:             */
1508:            private static void getNodesFromPath(final NodeListImpl result,
1509:                    final Node contextNode, final String[] path,
1510:                    final int startIndex) {
1511:                final NodeList childs = contextNode.getChildNodes();
1512:                int m, l;
1513:                Node item;
1514:                if (startIndex == (path.length - 1)) {
1515:                    if (childs != null) {
1516:                        m = 0;
1517:                        l = childs.getLength();
1518:                        while (m < l) {
1519:                            item = childs.item(m);
1520:                            if (item.getNodeType() == Node.ELEMENT_NODE) {
1521:                                // Work around: org.apache.xerces.dom.ElementImpl
1522:                                // doesn't handle getLocalName() correct
1523:                                if (path[startIndex]
1524:                                        .equals(item.getLocalName() != null ? item
1525:                                                .getLocalName()
1526:                                                : item.getNodeName())) {
1527:                                    result.addNode(item);
1528:                                }
1529:                            }
1530:                            m++;
1531:                        }
1532:                    }
1533:                } else {
1534:                    if (childs != null) {
1535:                        m = 0;
1536:                        l = childs.getLength();
1537:                        while (m < l) {
1538:                            item = childs.item(m);
1539:                            if (item.getNodeType() == Node.ELEMENT_NODE) {
1540:                                // Work around: org.apache.xerces.dom.ElementImpl
1541:                                // doesn't handle getLocalName() correct
1542:                                if (path[startIndex]
1543:                                        .equals(item.getLocalName() != null ? item
1544:                                                .getLocalName()
1545:                                                : item.getNodeName())) {
1546:                                    getNodesFromPath(result, item, path,
1547:                                            startIndex + 1);
1548:                                }
1549:                            }
1550:                            m++;
1551:                        }
1552:                    }
1553:                }
1554:            }
1555:
1556:            /**
1557:             * Converts a org.w3c.dom.Node to a String. Uses
1558:             * {@link javax.xml.transform.Transformer} to convert from a Node to a
1559:             * String.
1560:             * 
1561:             * @param node
1562:             *            a <code>org.w3c.dom.Node</code> value
1563:             * @return String representation of the document
1564:             * @deprecated Use {@link XMLUtils#serializeNodeToXML(Node)} instead. To be
1565:             *             removed in 2.2.
1566:             */
1567:            public static String node2String(Node node) {
1568:                try {
1569:                    return XMLUtils.serializeNodeToXML(node);
1570:                } catch (ProcessingException e) {
1571:                    // Empty
1572:                }
1573:                return "";
1574:            }
1575:
1576:            /**
1577:             * Create a string representation of a org.w3c.dom.Node and any (most)
1578:             * subtypes.
1579:             * 
1580:             * @param node
1581:             *            a <code>org.w3c.dom.Node</code> value
1582:             * @param pretty
1583:             *            a <code>boolean</code> value whether to format the XML
1584:             * @return a <code>String</code> value
1585:             * @deprecated Please use {@link XMLUtils#serializeNode(Node, Properties)}
1586:             *             instead. To be removed in 2.2.
1587:             */
1588:            public static String node2String(Node node, boolean pretty) {
1589:                try {
1590:                    if (pretty) {
1591:                        Properties props = new Properties();
1592:                        props.setProperty(OutputKeys.INDENT, "yes");
1593:                        return XMLUtils.serializeNode(node, props);
1594:                    } else {
1595:                        return XMLUtils.serializeNodeToXML(node);
1596:                    }
1597:                } catch (ProcessingException e) {
1598:                }
1599:                return "";
1600:            }
1601:
1602:            /**
1603:             * Create a string representation of a org.w3c.dom.Node and any (most)
1604:             * subtypes.
1605:             * 
1606:             * @param node
1607:             *            a <code>org.w3c.dom.Node</code> value
1608:             * @return a <code>StringBuffer</code> value
1609:             * @deprecated Please use {@link XMLUtils#serializeNodeToXML(Node)} instead.
1610:             *             To be removed in 2.2.
1611:             */
1612:            public static StringBuffer node2StringBuffer(Node node) {
1613:                return new StringBuffer(node2String(node));
1614:            }
1615:
1616:            /**
1617:             * Create a string representation of a org.w3c.dom.Node and any (most)
1618:             * subtypes.
1619:             * 
1620:             * @param node
1621:             *            a <code>org.w3c.dom.Node</code> value
1622:             * @param pretty
1623:             *            a <code>boolean</code> value whether to format the XML
1624:             * @param indent
1625:             *            a <code>String</code> value containing spaces as initial
1626:             *            indent, if null defaults to empty string.
1627:             * @return a <code>StringBuffer</code> value
1628:             * @deprecated Please use {@link XMLUtils#serializeNode(Node, Properties)}
1629:             *             instead. To be removed in 2.2.
1630:             */
1631:            public static StringBuffer node2StringBuffer(Node node,
1632:                    boolean pretty, String indent) {
1633:                return new StringBuffer(node2String(node, pretty));
1634:            }
1635:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.