/*
 * Copyright (C) 2010-2014 Hamburg Sud and the contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.aludratest.service.gui.web.selenium.util;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.aludratest.exception.AutomationException;
import org.aludratest.service.locator.element.XPathLocator;
import org.aludratest.util.MostRecentUseCache;
import org.jsoup.Jsoup;
import org.jsoup.helper.W3CDom;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/** Utility class containing a static MRU cache for parsed HTML documents to enable faster XPath evaluations.
 * 
 * @author falbrech */
public final class DocCache {

    private DocCache() {
    }

    private static final MostRecentUseCache.Factory<String, Document> docFactory = new MostRecentUseCache.Factory<String, Document>() {
        @Override
        public Document create(String html) {
            return new W3CDom().fromJsoup(Jsoup.parse(html));
        }
    };

    /* Use an MRU cache for HTML -> DOM mappings. If executing several XPaths on same HTML, this increases performance
     * significantly. */
    private static final MostRecentUseCache<String, Document> docCache = new MostRecentUseCache<String, Document>(docFactory, 50);

    public static NodeList evalXPathInHTML(XPathLocator locator, String html) {
        return evalXPathInHTML(locator.toString(), html);
    }

    public static NodeList evalXPathInHTML(String xpath, String html) {
        try {
            Document document = docCache.get(html);
            XPathExpression expression = XPathFactory.newInstance().newXPath().compile(xpath);
            return (NodeList) expression.evaluate(document, XPathConstants.NODESET);
        }
        catch (XPathExpressionException e) {
            throw new AutomationException("Illegal XPath: " + xpath, e);
        }
    }

    public static String evalXPathInHTMLAsString(String xpath, String html) {
        try {
            Document document = docCache.get(html);
            XPathExpression expression = XPathFactory.newInstance().newXPath().compile(xpath);
            return (String) expression.evaluate(document, XPathConstants.STRING);
        }
        catch (XPathExpressionException e) {
            throw new AutomationException("Illegal XPath: " + xpath, e);
        }
    }

}

@@ -670,16 +670,252 @@
 .util;%0A%0A
+import java.io.ByteArrayInputStream;%0Aimport java.io.File;%0Aimport java.io.IOException;%0Aimport java.io.UnsupportedEncodingException;%0A%0Aimport javax.xml.parsers.DocumentBuilderFactory;%0Aimport javax.xml.parsers.ParserConfigurationException;%0A
 import j
@@ -945,16 +945,16 @@
 stants;%0A
-
 import j
@@ -1232,16 +1232,56 @@
 eCache;%0A
+import org.apache.commons.io.FileUtils;%0A
 import o
@@ -1385,16 +1385,49 @@
 odeList;
+%0Aimport org.xml.sax.SAXException;
 %0A%0A/** Ut
@@ -1836,57 +1836,1059 @@
     
-return new W3CDom().fromJsoup(Jsoup.parse(html));
+W3CDom helper = new W3CDom();%0A            Document doc = helper.fromJsoup(Jsoup.parse(html));%0A%0A            // strip off namespaces%0A            html = helper.asString(doc);%0A            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();%0A            dbf.setNamespaceAware(false);%0A            dbf.setValidating(false);%0A%0A            try %7B%0A                return dbf.newDocumentBuilder().parse(new ByteArrayInputStream(html.getBytes(%22UTF-8%22)));%0A            %7D%0A            catch (UnsupportedEncodingException e) %7B%0A                throw new RuntimeException(%22UTF-8 not supported on this system%22);%0A            %7D%0A            catch (SAXException e) %7B%0A                // ignore parse error; return doc (may cause problems)%0A                return doc;%0A            %7D%0A            catch (IOException e) %7B%0A                throw new RuntimeException(%22Could not read from memory%22);%0A            %7D%0A            catch (ParserConfigurationException e) %7B%0A                throw new RuntimeException(%22No usable XML parser available on this system%22);%0A            %7D
 %0A   
@@ -3761,32 +3761,32 @@
  %22 + xpath, e);%0A
-
         %7D%0A    %7D%0A
@@ -3778,32 +3778,262 @@
        %7D%0A    %7D%0A%0A
+    public static void main(String%5B%5D args) throws IOException %7B%0A        String html = FileUtils.readFileToString(new File(%22test.html%22));%0A        System.out.println(evalXPathInHTMLAsString(%22/html/head/title/text()%22, html));%0A    %7D%0A%0A
     public stati

Remove namespaces when using jsoup for HTML parsing