001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.xml;
016    
017    import com.liferay.portal.kernel.xml.Node;
018    import com.liferay.portal.kernel.xml.XPath;
019    import com.liferay.portal.xml.xpath.LiferayFunctionContext;
020    import com.liferay.portal.xml.xpath.LiferayNamespaceContext;
021    
022    import java.util.List;
023    import java.util.Map;
024    
025    import org.jaxen.FunctionContext;
026    import org.jaxen.NamespaceContext;
027    
028    /**
029     * @author Brian Wing Shun Chan
030     */
031    public class XPathImpl implements XPath {
032    
033            public XPathImpl(
034                    org.dom4j.XPath xPath, Map<String, String> namespaceContextMap) {
035    
036                    _xPath = xPath;
037    
038                    _xPath.setFunctionContext(_functionContext);
039    
040                    NamespaceContext namespaceContext = new LiferayNamespaceContext(
041                            namespaceContextMap);
042    
043                    _xPath.setNamespaceContext(namespaceContext);
044            }
045    
046            public boolean booleanValueOf(Object context) {
047                    return _xPath.booleanValueOf(toOldContext(context));
048            }
049    
050            @Override
051            public boolean equals(Object obj) {
052                    org.dom4j.XPath xPath = ((XPathImpl)obj).getWrappedXPath();
053    
054                    return _xPath.equals(xPath);
055            }
056    
057            public Object evaluate(Object context) {
058                    return toNewContext(_xPath.evaluate(toOldContext(context)));
059            }
060    
061            public String getText() {
062                    return _xPath.getText();
063            }
064    
065            public org.dom4j.XPath getWrappedXPath() {
066                    return _xPath;
067            }
068    
069            @Override
070            public int hashCode() {
071                    return _xPath.hashCode();
072            }
073    
074            public boolean matches(Node node) {
075                    NodeImpl nodeImpl = (NodeImpl)node;
076    
077                    return _xPath.matches(nodeImpl.getWrappedNode());
078            }
079    
080            public Number numberValueOf(Object context) {
081                    return _xPath.numberValueOf(toOldContext(context));
082            }
083    
084            public List<Node> selectNodes(Object context) {
085                    return SAXReaderImpl.toNewNodes(
086                            _xPath.selectNodes(toOldContext(context)));
087            }
088    
089            public List<Node> selectNodes(Object context, XPath sortXPath) {
090                    XPathImpl sortXPathImpl = (XPathImpl)sortXPath;
091    
092                    return SAXReaderImpl.toNewNodes(
093                            _xPath.selectNodes(
094                                    toOldContext(context), sortXPathImpl.getWrappedXPath()));
095            }
096    
097            public List<Node> selectNodes(
098                    Object context, XPath sortXPath, boolean distinct) {
099    
100                    XPathImpl sortXPathImpl = (XPathImpl)sortXPath;
101    
102                    return SAXReaderImpl.toNewNodes(
103                            _xPath.selectNodes(
104                                    toOldContext(context), sortXPathImpl.getWrappedXPath(),
105                                    distinct));
106            }
107    
108            public Node selectSingleNode(Object context) {
109                    org.dom4j.Node node = _xPath.selectSingleNode(toOldContext(context));
110    
111                    if (node == null) {
112                            return null;
113                    }
114                    else if (node instanceof org.dom4j.Element) {
115                            return new ElementImpl((org.dom4j.Element)node);
116                    }
117                    else {
118                            return new NodeImpl(node);
119                    }
120            }
121    
122            public void sort(List<Node> nodes) {
123                    _xPath.sort(SAXReaderImpl.toOldNodes(nodes));
124            }
125    
126            public void sort(List<Node> nodes, boolean distinct) {
127                    _xPath.sort(SAXReaderImpl.toOldNodes(nodes), distinct);
128            }
129    
130            @Override
131            public String toString() {
132                    return _xPath.toString();
133            }
134    
135            public String valueOf(Object context) {
136                    return _xPath.valueOf(toOldContext(context));
137            }
138    
139            protected Object toNewContext(Object context) {
140                    if (context == null) {
141                            return null;
142                    }
143                    else if (context instanceof org.dom4j.Document) {
144                            org.dom4j.Document document = (org.dom4j.Document)context;
145    
146                            return new DocumentImpl(document);
147                    }
148                    else if (context instanceof org.dom4j.Node) {
149                            org.dom4j.Node node = (org.dom4j.Node)context;
150    
151                            return new NodeImpl(node);
152                    }
153                    else if (context instanceof List<?>) {
154                            return SAXReaderImpl.toNewNodes((List<org.dom4j.Node>)context);
155                    }
156                    else {
157                            return context;
158                    }
159            }
160    
161            protected Object toOldContext(Object context) {
162                    if (context == null) {
163                            return null;
164                    }
165                    else if (context instanceof DocumentImpl) {
166                            DocumentImpl documentImpl = (DocumentImpl)context;
167    
168                            return documentImpl.getWrappedDocument();
169                    }
170                    else if (context instanceof NodeImpl) {
171                            NodeImpl nodeImpl = (NodeImpl)context;
172    
173                            return nodeImpl.getWrappedNode();
174                    }
175                    else if (context instanceof List<?>) {
176                            return SAXReaderImpl.toOldNodes((List<Node>)context);
177                    }
178                    else {
179                            return context;
180                    }
181            }
182    
183            private static FunctionContext _functionContext =
184                    new LiferayFunctionContext();
185    
186            private org.dom4j.XPath _xPath;
187    
188    }