001    
002    package railo.runtime.functions.xml;
003    
004    import javax.xml.transform.TransformerException;
005    
006    import org.apache.xpath.XPathAPI;
007    import org.apache.xpath.objects.XObject;
008    import org.w3c.dom.Node;
009    import org.w3c.dom.NodeList;
010    
011    import railo.commons.lang.StringUtil;
012    import railo.runtime.PageContext;
013    import railo.runtime.exp.PageException;
014    import railo.runtime.ext.function.Function;
015    import railo.runtime.op.Caster;
016    import railo.runtime.text.xml.XMLCaster;
017    import railo.runtime.text.xml.struct.XMLObject;
018    import railo.runtime.text.xml.struct.XMLStruct;
019    import railo.runtime.type.Array;
020    import railo.runtime.type.ArrayImpl;
021    
022    /**
023     * Implements the Cold Fusion Function xmlsearch
024     */
025    public final class XmlSearch implements Function {
026    
027            public static Object call(PageContext pc , Node node, String expr) throws PageException {
028                    boolean caseSensitive=true;
029                    if(node instanceof XMLObject) {
030                            caseSensitive=((XMLObject)node).getCaseSensitive();
031                    }
032                    if(node instanceof XMLStruct) {
033                            node=((XMLStruct)node).toNode();
034                    }
035                    return _call(node,expr,caseSensitive);
036                    
037            }
038            public static Object _call(Node node, String expr, boolean caseSensitive) throws PageException {
039                    if(StringUtil.endsWith(expr,'/')) 
040                            expr = expr.substring(0,expr.length()-1);
041                    try {
042                            XObject rs = XPathAPI.eval(node,expr);
043                            
044                            switch(rs.getType()){
045                            case XObject.CLASS_NODESET:
046                                    return nodelist(rs,caseSensitive);
047                            case XObject.CLASS_BOOLEAN:
048                                    return Caster.toBoolean(rs.bool());
049                            case XObject.CLASS_NULL:
050                                    return "";
051                            case XObject.CLASS_NUMBER:
052                                    return Caster.toDouble(rs.num());
053                            case XObject.CLASS_STRING:
054                                    return rs.str();
055                            default:
056                                    return rs.object();
057                            }
058                    } catch (Throwable e) {
059                            throw Caster.toPageException(e);
060                    }
061                    
062                    
063                    
064            }
065            private static Array nodelist(XObject rs, boolean caseSensitive) throws TransformerException, PageException {
066                    
067                    NodeList list = rs.nodelist();
068                    int len=list.getLength();
069                    Array rtn=new ArrayImpl();
070                    for(int i=0;i<len;i++) {
071                            Node n=list.item(i);
072                            if(n !=null)
073                            rtn.append(XMLCaster.toXMLStruct(n,caseSensitive));
074                    }
075                    return rtn;
076            }
077    }