001    package railo.runtime.text.xml;
002    
003    import java.io.IOException;
004    import java.io.OutputStream;
005    import java.io.StringReader;
006    import java.io.StringWriter;
007    import java.util.ArrayList;
008    import java.util.Iterator;
009    import java.util.List;
010    import java.util.Map.Entry;
011    
012    import javax.xml.transform.OutputKeys;
013    import javax.xml.transform.Result;
014    import javax.xml.transform.Transformer;
015    import javax.xml.transform.dom.DOMSource;
016    import javax.xml.transform.stream.StreamResult;
017    
018    import org.w3c.dom.Attr;
019    import org.w3c.dom.CDATASection;
020    import org.w3c.dom.CharacterData;
021    import org.w3c.dom.Comment;
022    import org.w3c.dom.Document;
023    import org.w3c.dom.Element;
024    import org.w3c.dom.NamedNodeMap;
025    import org.w3c.dom.Node;
026    import org.w3c.dom.NodeList;
027    import org.w3c.dom.Text;
028    import org.xml.sax.InputSource;
029    
030    import railo.commons.io.IOUtil;
031    import railo.commons.io.res.Resource;
032    import railo.commons.lang.HTMLEntities;
033    import railo.commons.lang.StringUtil;
034    import railo.runtime.PageContext;
035    import railo.runtime.dump.DumpData;
036    import railo.runtime.dump.DumpProperties;
037    import railo.runtime.dump.DumpTable;
038    import railo.runtime.dump.DumpUtil;
039    import railo.runtime.dump.SimpleDumpData;
040    import railo.runtime.exp.CasterException;
041    import railo.runtime.exp.ExpressionException;
042    import railo.runtime.exp.PageException;
043    import railo.runtime.exp.XMLException;
044    import railo.runtime.functions.decision.IsNumeric;
045    import railo.runtime.functions.list.ListLast;
046    import railo.runtime.op.Caster;
047    import railo.runtime.text.xml.struct.XMLStruct;
048    import railo.runtime.text.xml.struct.XMLStructFactory;
049    import railo.runtime.type.Collection;
050    import railo.runtime.type.Collection.Key;
051    import railo.runtime.type.Struct;
052    
053    /**
054     * Cast Objects to XML Objects of different types
055     */
056    public final class XMLCaster {
057    
058        
059        /**
060             * casts a value to a XML Text
061             * @param doc XML Document
062             * @param o Object to cast
063             * @return XML Text Object
064             * @throws PageException
065             */
066            public static Text toText(Document doc, Object o) throws PageException {
067                    if(o instanceof Text) return (Text)o;
068                    else if(o instanceof CharacterData) return doc.createTextNode(((CharacterData)o).getData());
069                    return doc.createTextNode(Caster.toString(o));
070            }
071            
072            public static Text toCDATASection(Document doc, Object o) throws PageException {
073                    if(o instanceof CDATASection) return (CDATASection)o;
074                    else if(o instanceof CharacterData) return doc.createCDATASection(((CharacterData)o).getData());
075                    return doc.createCDATASection(Caster.toString(o));
076            }
077            
078            /**
079             * casts a value to a XML Text Array
080             * @param doc XML Document
081             * @param o Object to cast
082             * @return XML Text Array
083             * @throws PageException
084             */
085            public static Text[] toTextArray(Document doc,Object o) throws PageException {
086            // Node[]
087                    if(o instanceof Node[]) {
088                            Node[] nodes=(Node[])o;
089                            if(_isAllOfSameType(nodes,Node.TEXT_NODE))return (Text[])nodes; 
090                            
091                            Text[] textes=new Text[nodes.length];
092                            for(int i=0;i<nodes.length;i++) {
093                                    textes[i]=toText(doc,nodes[i]);
094                            }
095                            return textes;
096                    }
097            // Collection
098                    else if(o instanceof Collection) {
099                            Collection coll=(Collection)o;
100                            Iterator<Object> it = coll.valueIterator();
101                            List<Text> textes=new ArrayList<Text>();
102                            while(it.hasNext()) {
103                                    textes.add(toText(doc,it.next()));
104                            }
105                            return textes.toArray(new Text[textes.size()]);
106                    }
107            // Node Map and List
108                    Node[] nodes=_toNodeArray(doc,o);
109                    if(nodes!=null) return toTextArray(doc,nodes);
110            // Single Text Node
111                    try {
112                            return new Text[]{toText(doc,o)};
113                    } catch (ExpressionException e) {
114                            throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Text Array");
115                    }
116            }
117            
118            /**
119             * casts a value to a XML Attribute Object
120             * @param doc XML Document
121             * @param o Object to cast
122             * @return XML Comment Object
123             * @throws PageException
124             */
125            public static Attr toAttr(Document doc, Object o) throws PageException {
126                    if(o instanceof Attr) return (Attr)o;
127                    if(o instanceof Struct && ((Struct)o).size()==1) {
128                            Struct sct=(Struct)o;
129                            Entry<Key, Object> e = sct.entryIterator().next();
130                            Attr attr= doc.createAttribute(e.getKey().getString());
131                            attr.setValue(Caster.toString(e.getValue()));
132                            return attr;
133                    }
134                    
135                    throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Attribute");
136            }
137    
138            /**
139             * casts a value to a XML Attr Array
140             * @param doc XML Document
141             * @param o Object to cast
142             * @return XML Attr Array
143             * @throws PageException
144             */
145            public static Attr[] toAttrArray(Document doc,Object o) throws PageException {
146            // Node[]
147                    if(o instanceof Node[]) {
148                            Node[] nodes=(Node[])o;
149                            if(_isAllOfSameType(nodes,Node.ATTRIBUTE_NODE))return (Attr[])nodes; 
150                            
151                            Attr[] attres=new Attr[nodes.length];
152                            for(int i=0;i<nodes.length;i++) {
153                                    attres[i]=toAttr(doc,nodes[i]);
154                            }
155                            return attres;
156                    }
157            // Collection
158                    else if(o instanceof Collection) {
159                            Collection coll=(Collection)o;
160                            Iterator<Entry<Key, Object>> it = coll.entryIterator();
161                            Entry<Key, Object> e;
162                            List<Attr> attres=new ArrayList<Attr>();
163                            Attr attr;
164                            Collection.Key k;
165                            while(it.hasNext()) {
166                                    e = it.next();
167                                    k=e.getKey();
168                                    attr=doc.createAttribute(IsNumeric.call(null,k.getString())?"attribute-"+k.getString():k.getString());
169                                    attr.setValue(Caster.toString(e.getValue()));
170                                    attres.add(attr);
171                            }
172                            return attres.toArray(new Attr[attres.size()]);
173                    }
174            // Node Map and List
175                    Node[] nodes=_toNodeArray(doc,o);
176                    if(nodes!=null) return toAttrArray(doc,nodes);
177            // Single Text Node
178                    try {
179                            return new Attr[]{toAttr(doc,o)};
180                    } catch (ExpressionException e) {
181                            throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Attributes Array");
182                    }
183            }
184    
185            /**
186             * casts a value to a XML Comment Object
187             * @param doc XML Document
188             * @param o Object to cast
189             * @return XML Comment Object
190             * @throws PageException
191             */
192            public static Comment toComment(Document doc,Object o) throws PageException {
193                    if(o instanceof Comment) return (Comment)o;
194                    else if(o instanceof CharacterData) return doc.createComment(((CharacterData)o).getData());
195                    return doc.createComment(Caster.toString(o));
196            }
197            
198            /**
199             * casts a value to a XML Comment Array
200             * @param doc XML Document
201             * @param o Object to cast
202             * @return XML Comment Array
203             * @throws PageException
204             */
205            public static Comment[] toCommentArray(Document doc,Object o) throws PageException {
206            // Node[]
207                    if(o instanceof Node[]) {
208                            Node[] nodes=(Node[])o;
209                            if(_isAllOfSameType(nodes,Node.COMMENT_NODE))return (Comment[])nodes; 
210                            
211                            Comment[] comments=new Comment[nodes.length];
212                            for(int i=0;i<nodes.length;i++) {
213                                    comments[i]=toComment(doc,nodes[i]);
214                            }
215                            return comments;
216                    }
217            // Collection
218                    else if(o instanceof Collection) {
219                            Collection coll=(Collection)o;
220                            Iterator<Object> it = coll.valueIterator();
221                            List<Comment> comments=new ArrayList<Comment>();
222                            while(it.hasNext()) {
223                                    comments.add(toComment(doc,it.next()));
224                            }
225                            return comments.toArray(new Comment[comments.size()]);
226                    }
227            // Node Map and List
228                    Node[] nodes=_toNodeArray(doc,o);
229                    if(nodes!=null) return toCommentArray(doc,nodes);
230            // Single Text Node
231                    try {
232                            return new Comment[]{toComment(doc,o)};
233                    } catch (ExpressionException e) {
234                            throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Comment Array");
235                    }
236            }
237    
238            /**
239             * casts a value to a XML Element
240             * @param doc XML Document
241             * @param o Object to cast
242             * @return XML Element Object
243             * @throws PageException
244             */
245            public static Element toElement(Document doc,Object o) throws PageException {
246                    if(o instanceof Element)return (Element)o;
247                    else if(o instanceof Node)throw new ExpressionException("Object "+Caster.toClassName(o)+" must be a XML Element");
248                    return doc.createElement(Caster.toString(o));
249            }
250            
251            /**
252             * casts a value to a XML Element Array
253             * @param doc XML Document
254             * @param o Object to cast
255             * @return XML Comment Array
256             * @throws PageException
257             */
258            public static Element[] toElementArray(Document doc,Object o) throws PageException {
259            // Node[]
260                    if(o instanceof Node[]) {
261                            Node[] nodes=(Node[])o;
262                            if(_isAllOfSameType(nodes,Node.ELEMENT_NODE))return (Element[])nodes; 
263                            
264                            Element[] elements=new Element[nodes.length];
265                            for(int i=0;i<nodes.length;i++) {
266                                    elements[i]=toElement(doc,nodes[i]);
267                            }
268                            return elements;
269                    }
270            // Collection
271                    else if(o instanceof Collection) {
272                            Collection coll=(Collection)o;
273                            Iterator<Object> it = coll.valueIterator();
274                            List<Element> elements=new ArrayList<Element>();
275                            while(it.hasNext()) {
276                                    elements.add(toElement(doc,it.next()));
277                            }
278                            return elements.toArray(new Element[elements.size()]);
279                    }
280            // Node Map and List
281                    Node[] nodes=_toNodeArray(doc,o);
282                    if(nodes!=null) return toElementArray(doc,nodes);
283            // Single Text Node
284                    try {
285                            return new Element[]{toElement(doc,o)};
286                    } catch (ExpressionException e) {
287                            throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Element Array");
288                    }
289            }
290            
291            /**
292             * casts a value to a XML Node
293             * @param doc XML Document
294             * @param o Object to cast
295             * @return XML Element Object
296             * @throws PageException
297             * @deprecated replaced with toRawNode
298             */
299            public static Node toNode(Object o) throws PageException {
300                    if(o instanceof XMLStruct)return ((XMLStruct)o).toNode();
301                    if(o instanceof Node)return (Node)o;
302                    throw new CasterException(o,"node");
303            }
304            
305            /**
306             * remove railo node wraps (XMLStruct) from node 
307             * @param node
308             * @return raw node (without wrap)
309             */
310            public static Node toRawNode(Node node) {
311                    if(node instanceof XMLStruct)return ((XMLStruct)node).toNode();
312                    return node;
313            }
314            
315            public static Node toNode(Document doc,Object o) throws PageException {
316                    if(o instanceof XMLStruct)return ((XMLStruct)o).toNode();
317                    if(o instanceof Node)return (Node)o;
318                    String nodeName=Caster.toString(o);
319                    if(nodeName.length()==0)nodeName="Empty";
320                    return doc.createElement(nodeName);
321            }
322    
323            
324            /**
325             * casts a value to a XML Element Array
326             * @param doc XML Document
327             * @param o Object to cast
328             * @return XML Comment Array
329             * @throws PageException
330             */
331            public static Node[] toNodeArray(Document doc,Object o) throws PageException {
332                    if(o instanceof Node) return new Node[]{(Node)o};
333            // Node[]
334                    if(o instanceof Node[]) {
335                            return (Node[])o;
336                    }
337            // Collection
338                    else if(o instanceof Collection) {
339                            Collection coll=(Collection)o;
340                            Iterator<Object> it = coll.valueIterator();
341                            List<Node> nodes=new ArrayList<Node>();
342                            while(it.hasNext()) {
343                                    nodes.add(toNode(doc,it.next()));
344                            }
345                            return nodes.toArray(new Node[nodes.size()]);
346                    }
347            // Node Map and List
348                    Node[] nodes=_toNodeArray(doc,o);
349                    if(nodes!=null) return nodes;
350            // Single Text Node
351                    try {
352                            return new Node[]{toNode(doc,o)};
353                    } catch (ExpressionException e) {
354                            throw new XMLException("can't cast Object of type "+Caster.toClassName(o)+" to a XML Node Array");
355                    }
356            }
357            
358    
359    
360    
361            /**
362             * casts a value to a XML Object defined by type parameter
363             * @param doc XML Document
364             * @param o Object to cast
365             * @param type type to cast to
366             * @return XML Text Object
367             * @throws PageException
368             */
369            public static Node toNode(Document doc, Object o, short type) throws PageException {
370                    
371                    if(Node.TEXT_NODE == type) toText(doc, o);
372                    else if(Node.ATTRIBUTE_NODE == type) toAttr(doc, o);
373                    else if(Node.COMMENT_NODE == type) toComment(doc, o);
374                    else if(Node.ELEMENT_NODE == type) toElement(doc, o);
375                    
376                    
377                    throw new ExpressionException("invalid node type definition");
378            }
379    
380            /**
381             * casts a value to a XML Object Array defined by type parameter
382             * @param doc XML Document
383             * @param o Object to cast
384             * @param type type to cast to
385             * @return XML Node Array Object
386             * @throws PageException
387             */
388            public static Node[] toNodeArray(Document doc, Object o, short type) throws PageException {
389                    
390                    if(Node.TEXT_NODE == type) toTextArray(doc, o);
391                    else if(Node.ATTRIBUTE_NODE == type) toAttrArray(doc, o);
392                    else if(Node.COMMENT_NODE == type) toCommentArray(doc, o);
393                    else if(Node.ELEMENT_NODE == type) toElementArray(doc, o);
394                    
395                    
396                    throw new ExpressionException("invalid node type definition");
397            }
398    
399            /* *
400             * cast a xml node to a String
401             * @param node
402             * @return xml node as String
403             * @throws ExpressionException
404             * /
405            public static String toString(Node node) throws ExpressionException  {
406            //Transformer tf;
407                    try {
408                    OutputFormat format = new OutputFormat();
409                    
410                    StringWriter writer = new StringWriter();
411                    XMLSerializer serializer = new XMLSerializer(writer, format);
412                    if(node instanceof Element)serializer.serialize((Element)node);
413                    else serializer.serialize(XMLUtil.getDocument(node));
414                    return writer.toString();
415                    
416                    } catch (Exception e) {
417                        throw ExpressionException.newInstance(e);
418                    }
419            }
420            
421            public static String toString(Node node,String defaultValue)  {
422            //Transformer tf;
423                    try {
424                    OutputFormat format = new OutputFormat();
425                    
426                    StringWriter writer = new StringWriter();
427                    XMLSerializer serializer = new XMLSerializer(writer, format);
428                    if(node instanceof Element)serializer.serialize((Element)node);
429                    else serializer.serialize(XMLUtil.getDocument(node));
430                    return writer.toString();
431                    
432                    } catch (Exception e) {
433                        return defaultValue;
434                    }
435            }*/
436            
437            public static String toHTML(Node node) throws ExpressionException  {
438                    if(Node.DOCUMENT_NODE==node.getNodeType()) 
439                    return toHTML(XMLUtil.getRootElement(node,true));
440                    
441                    StringBuffer sb=new StringBuffer();
442                    toHTML(node, sb);
443                    return sb.toString();
444            }
445        
446        private static void toHTML(Node node,StringBuffer sb) throws ExpressionException  {
447                    short type=node.getNodeType();
448            if(Node.ELEMENT_NODE==type) {
449                    Element el = (Element) node;
450                    String tagName=el.getTagName();
451                    sb.append('<');
452                            sb.append(tagName);
453                            
454                            NamedNodeMap attrs = el.getAttributes();
455                            Attr attr;
456                            int len = attrs.getLength();
457                            for(int i=0;i<len;i++) {
458                                    attr=(Attr) attrs.item(i);
459                                    sb.append(' ');
460                                    sb.append(attr.getName());
461                                    sb.append("=\"");
462                                    sb.append(attr.getValue());
463                                    sb.append('"');
464                            }
465                            NodeList children = el.getChildNodes();
466                            len = children.getLength();
467                            
468                            boolean doEndTag=len!=0 || (tagName.length()==4 && (tagName.equalsIgnoreCase("head") || tagName.equalsIgnoreCase("body")));
469                    
470                    
471                            if(!doEndTag)sb.append(" />");
472                            else sb.append('>');
473                    
474                            for(int i=0;i<len;i++) {
475                                    toHTML(children.item(i),sb);
476                            }
477                    
478                            if(doEndTag) {
479                                    sb.append("</");
480                                    sb.append(el.getTagName());
481                                    sb.append('>');
482                            }
483            }
484            else if(node instanceof CharacterData) {
485                    sb.append(HTMLEntities.escapeHTML(node.getNodeValue()));
486                    }
487            }
488            
489            /**
490             * write a xml Dom to a file
491             * @param node
492             * @param file
493             * @throws PageException
494             */
495            public static void writeTo(Node node, Resource file) throws PageException {
496            OutputStream os=null;
497                    try {
498                            os=IOUtil.toBufferedOutputStream(file.getOutputStream());
499                            writeTo(node, new StreamResult(os),false,false,null,null,null);
500                    }
501                    catch(IOException ioe){
502                            throw Caster.toPageException(ioe);
503                    }
504                    finally {
505                            IOUtil.closeEL(os);
506                    }
507            }
508            
509    
510            public static String toString(Node node) throws PageException {
511                    StringWriter sw=new StringWriter();
512                    try {
513                            writeTo(node, new StreamResult(sw),false,false,null,null,null);
514                    } 
515                    finally {
516                            IOUtil.closeEL(sw);
517                    }
518                    return sw.getBuffer().toString();
519            }
520    
521            public static String toString(Node node,boolean omitXMLDecl, boolean indent) throws PageException {
522                    StringWriter sw=new StringWriter();
523                    try {
524                            writeTo(node, new StreamResult(sw),omitXMLDecl,indent,null,null,null);
525                    } 
526                    finally {
527                            IOUtil.closeEL(sw);
528                    }
529                    return sw.getBuffer().toString();
530            }
531            
532            
533            public static String toString(Node node,boolean omitXMLDecl,boolean indent,String publicId,String systemId,String encoding) throws PageException {
534                    StringWriter sw=new StringWriter();
535                    try {
536                            writeTo(node, new StreamResult(sw),omitXMLDecl,indent,publicId,systemId,encoding);
537                    } 
538                    finally {
539                            IOUtil.closeEL(sw);
540                    }
541                    return sw.getBuffer().toString();
542            }
543            
544            public static String toString(NodeList nodes,boolean omitXMLDecl, boolean indent) throws PageException {
545                    StringWriter sw=new StringWriter();
546                    try {
547                            int len = nodes.getLength();
548                            for(int i=0;i<len;i++){
549                                    writeTo(nodes.item(i), new StreamResult(sw),omitXMLDecl,indent,null,null,null);
550                            }
551                    } 
552                    finally {
553                            IOUtil.closeEL(sw);
554                    }
555                    return sw.getBuffer().toString();
556            }
557            
558            public static String toString(Node node,String defaultValue) {
559                    StringWriter sw=new StringWriter();
560                    try {
561                            writeTo(node, new StreamResult(sw),false,false,null,null,null);
562                    } 
563                    catch(Throwable t){
564                            return defaultValue;
565                    }
566                    finally {
567                            IOUtil.closeEL(sw);
568                    }
569                    return sw.getBuffer().toString();
570            }
571            
572            
573            public static void writeTo(Node node,Result res,boolean omitXMLDecl,boolean indent, String publicId,String systemId,String encoding) throws PageException {
574                    try {
575                            Transformer t = XMLUtil.getTransformerFactory().newTransformer();
576                            t.setOutputProperty(OutputKeys.INDENT,indent?"yes":"no");
577                            t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,omitXMLDecl?"yes":"no");
578                            //t.setOutputProperty("{http://xml.apache.org/xalan}indent-amount", "2"); 
579                            
580                            // optional properties
581                            if(!StringUtil.isEmpty(publicId,true))t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,publicId);
582                            if(!StringUtil.isEmpty(systemId,true))t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,systemId);
583                            if(!StringUtil.isEmpty(encoding,true))t.setOutputProperty(OutputKeys.ENCODING,encoding);
584                            
585                            t.transform(new DOMSource(node), res);
586                    } catch (Exception e) {
587                            throw Caster.toPageException(e);
588                    }
589            }
590            
591    
592        /**
593             * Casts a XML Node to a HTML Presentation
594             * @param node
595             * @param pageContext
596             * @return html output
597             */
598            public static DumpData toDumpData(Node node, PageContext pageContext, int maxlevel, DumpProperties props) {
599                    if(maxlevel<=0) {
600                            return new SimpleDumpData("maximum dump level reached");
601                    }
602                    maxlevel--;
603                    // Document
604                    if(node instanceof Document) {
605                            DumpTable table = new DumpTable("xml","#cc9999","#ffffff","#000000");
606                            table.setTitle("XML Document");
607                            table.appendRow(1,new SimpleDumpData("XmlComment"),new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLCOMMENT,null).toString()));
608                            table.appendRow(1,new SimpleDumpData("XmlRoot"),        DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLROOT,null), pageContext,maxlevel,props));
609                            return table;
610                            
611                    }
612                    // Element
613                    if(node instanceof Element) {
614                            DumpTable table = new DumpTable("xml","#cc9999","#ffffff","#000000");
615                            table.setTitle("XML Element");
616                            table.appendRow(1,new SimpleDumpData("xmlName"),                new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNAME,null).toString()));
617                            table.appendRow(1,new SimpleDumpData("XmlNsPrefix"),    new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNSPREFIX,null).toString()));
618                            table.appendRow(1,new SimpleDumpData("XmlNsURI"),               new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNSURI,null).toString()));
619                            table.appendRow(1,new SimpleDumpData("XmlText"),                DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLTEXT,null), pageContext,maxlevel,props));
620                            table.appendRow(1,new SimpleDumpData("XmlComment"),     new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLCOMMENT,null).toString()));
621                            table.appendRow(1,new SimpleDumpData("XmlAttributes"),DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLATTRIBUTES,null), pageContext,maxlevel,props));
622                            table.appendRow(1,new SimpleDumpData("XmlChildren"),    DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLCHILDREN,null), pageContext,maxlevel,props));
623                            return table;
624                            
625                    }
626                    // Attr
627                    if(node instanceof Attr) {
628                            DumpTable table = new DumpTable("xml","#cc9999","#ffffff","#000000");
629                            table.setTitle("XML Attr");
630                            table.appendRow(1,new SimpleDumpData("xmlName"),                new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNAME,null).toString()));
631                            table.appendRow(1,new SimpleDumpData("XmlValue"),       DumpUtil.toDumpData(((Attr)node).getValue(), pageContext,maxlevel,props));
632                            table.appendRow(1,new SimpleDumpData("XmlType"),        new SimpleDumpData(XMLUtil.getTypeAsString(node,true)));
633                            
634                            return table;
635                            
636                    }
637                    // Node
638                    DumpTable table = new DumpTable("xml","#cc9999","#ffffff","#000000");
639                    table.setTitle("XML Node ("+ListLast.call(null,node.getClass().getName(),".")+")");
640                    table.appendRow(1,new SimpleDumpData("xmlName"),                new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNAME,null).toString()));
641                    table.appendRow(1,new SimpleDumpData("XmlNsPrefix"),    new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNSPREFIX,null).toString()));
642                    table.appendRow(1,new SimpleDumpData("XmlNsURI"),               new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLNSURI,null).toString()));
643                    table.appendRow(1,new SimpleDumpData("XmlText"),                DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLTEXT,null), pageContext,maxlevel,props));
644                    table.appendRow(1,new SimpleDumpData("XmlComment"),     new SimpleDumpData(XMLUtil.getProperty(node,XMLUtil.XMLCOMMENT,null).toString()));
645                    table.appendRow(1,new SimpleDumpData("XmlAttributes"),DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLATTRIBUTES,null), pageContext,maxlevel,props));
646                    table.appendRow(1,new SimpleDumpData("XmlChildren"),    DumpUtil.toDumpData(XMLUtil.getProperty(node,XMLUtil.XMLCHILDREN,null), pageContext,maxlevel,props));
647                            
648                    table.appendRow(1,new SimpleDumpData("XmlType"),        new SimpleDumpData(XMLUtil.getTypeAsString(node,true)));
649                    
650                    return table;   
651            }
652            
653            /**
654             * casts a value to a XML named Node Map
655             * @param doc XML Document
656             * @param o Object to cast
657             * @return XML named Node Map Object
658             */
659            private static Node[] _toNodeArray(Document doc,Object o) {
660                    if(o instanceof Node) return new Node[]{(Node)o};
661            // Node[]
662                    if(o instanceof Node[]) return ((Node[])o);
663            // NamedNodeMap
664                    else if(o instanceof NamedNodeMap) {
665                            NamedNodeMap map=(NamedNodeMap)o;
666                            int len=map.getLength();
667                            Node[] nodes=new Node[len];
668                            for(int i=0;i<len;i++) {
669                                    nodes[i]=map.item(i);
670                            }
671                            return nodes;
672                    }
673            // XMLAttributes
674                    else if(o instanceof XMLAttributes) {
675                            return _toNodeArray(doc, ((XMLAttributes)o).toNamedNodeMap());
676                    }
677            // NodeList
678                    else if(o instanceof NodeList)  {
679                            NodeList list=(NodeList)o;
680                            int len=list.getLength();
681                            Node[] nodes=new Node[len];
682                            for(int i=0;i<nodes.length;i++) {
683                                    nodes[i]=list.item(i);
684                            }
685                            return nodes;
686                    }
687                    return null;
688            }
689            
690            /**
691             * Check if all Node are of the type defnined by para,meter 
692             * @param nodes nodes to check
693             * @param type to compare
694             * @return are all of the same type
695             */
696            private static boolean _isAllOfSameType(Node[] nodes, short type) {
697                    for(int i=0;i<nodes.length;i++) {
698                            if(nodes[i].getNodeType()!=type)return false;
699                    }
700                    return true;
701            }
702    
703            /**
704             * creates a XMLCollection Object from a Node
705             * @param node
706             * @param caseSensitive
707             * @return xmlstruct from node
708             */
709            public static XMLStruct toXMLStruct(Node node, boolean caseSensitive) {
710                return XMLStructFactory.newInstance(node,caseSensitive);
711            }
712            
713            public static Element toRawElement(Object value, Element defaultValue) {
714                    if(value instanceof Node) {
715                            Node node=XMLCaster.toRawNode((Node) value);
716                            if(node instanceof Document) return ((Document) node).getDocumentElement();
717                            if(node instanceof Element) return (Element) node;
718                            return defaultValue;
719                    }
720                    try {
721                            return XMLUtil.parse(new InputSource(new StringReader(Caster.toString(value))),null,false).getDocumentElement();
722                    } catch (Throwable t) {
723                            return defaultValue;
724                    }
725            }
726    
727    }