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