org.asqatasun.processor.DOMHandlerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.asqatasun.processor.DOMHandlerImpl.java

Source

/*
 * Asqatasun - Automated webpage assessment
 * Copyright (C) 2008-2015  Asqatasun.org
 *
 * This file is part of Asqatasun.
 *
 * Asqatasun is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contact us by mail: asqatasun AT asqatasun DOT org
 */
package org.asqatasun.processor;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.jsoup.select.Selector.SelectorParseException;
import org.asqatasun.entity.audit.ProcessRemark;
import org.asqatasun.entity.audit.SSP;
import org.asqatasun.entity.audit.TestSolution;
import org.asqatasun.entity.subject.WebResource;
import org.asqatasun.exception.IncoherentValueDomainsException;
import org.asqatasun.ruleimplementation.RuleHelper;
import org.asqatasun.service.ProcessRemarkService;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 
 * @author jkowalczyk
 */
public class DOMHandlerImpl implements DOMHandler {

    private static Logger LOGGER = Logger.getLogger(DOMHandlerImpl.class);
    private static final String ATTRIBUTE_MISSING_MSG_CODE = "AttributeMissing";
    private static final String CHILD_NODE_MISSING_MSG_CODE = "ChildNodeMissing";
    private Document document;
    private org.jsoup.nodes.Document jsoupDocument;
    private boolean docInitialised = false;
    private boolean jsoupDocInitialised = false;
    private List<Node> selectedElementList;
    private Elements selectedElements;
    private SSP ssp;
    private XPath xpath;
    private static final Pattern NON_ALPHANUMERIC_PATTERN = Pattern.compile("[^\\p{L}]+");

    private ProcessRemarkService processRemarkService;

    /* the total number of elements of the DOM */
    private int totalNumberOfElement = -1;

    /**
     * The message code defined by the user
     */
    private String messageCode;

    @Override
    public void setMessageCode(String messageCode) {
        this.messageCode = messageCode;
    }

    public DOMHandlerImpl() {
        super();
    }

    public DOMHandlerImpl(SSP ssp) {
        this.ssp = ssp;
    }

    @Override
    public void addSourceCodeRemark(TestSolution processResult, Node node, String messageCode,
            String attributeName) {
        processRemarkService.addSourceCodeRemark(processResult, node, messageCode, attributeName);
    }

    @Override
    public DOMHandler beginXpathSelection() {
        initialize();
        messageCode = null;
        selectedElementList = new LinkedList<Node>();
        // reset the processRemark service when beginning a new selection.
        // means the local collection of processRemark are reset
        processRemarkService.resetService();
        return this;
    }

    /**
     * This method should be called at each first selection of a RuleImplementation
     * to reset all the local collections.
     * 
     * @return the current instance 
     */
    @Override
    public DOMHandler beginCssLikeSelection() {
        // reset the local collection of elements
        selectedElements = new Elements();
        return this;
    }

    /**
     * The initialisation of the document is done only once when the SSP is set
     * to the instance. The Document is created, ready to be traversed, and
     * the processRemarkService is also initialised with the source. 
     */
    private void initializeJSoupDocument() {
        if (jsoupDocInitialised) {
            return;
        }
        String html = ssp.getDOM();
        Date beginDate = null;
        if (LOGGER.isDebugEnabled()) {
            beginDate = new Date();
            LOGGER.debug("Iinitialising Jsoup Document for " + ssp.getURI());
        }
        jsoupDocument = Jsoup.parse(html, ssp.getURI());
        if (LOGGER.isDebugEnabled()) {
            Date endDate = new Date();
            LOGGER.debug("initialisation of Jsoup Document for " + ssp.getURI() + "took "
                    + (endDate.getTime() - beginDate.getTime()) + "ms");
        }
        processRemarkService.initializeService(jsoupDocument, ssp.getDOM());
        jsoupDocInitialised = true;
    }

    private void initialize() {
        if (docInitialised) {
            return;
        }
        XPathFactory xPathfactory = XPathFactory.newInstance();
        xpath = xPathfactory.newXPath();

        try {

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            //@TODO verify the namespace property is necessary in our context
            //            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(new ByteArrayInputStream(ssp.getDOM().getBytes("UTF-8")));
            docInitialised = true;
        } catch (IOException ex) {
            LOGGER.error(ssp.getURI() + "cannot be initialised due to " + ex.getMessage());
            throw new RuntimeException(ex);
        } catch (SAXException ex) {
            LOGGER.error(ssp.getURI() + "cannot be initialised due to " + ex.getMessage());
            throw new RuntimeException(ex);
        } catch (ParserConfigurationException ex) {
            LOGGER.error(ssp.getURI() + "cannot be initialised due to " + ex.getMessage());
            throw new RuntimeException(ex);
        }
        processRemarkService.initializeService(document, ssp.getDOM());
    }

    @Override
    public TestSolution checkAttributeExists(String attributeName) {
        if (messageCode == null) {
            messageCode = ATTRIBUTE_MISSING_MSG_CODE;
        }
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution processResult = TestSolution.PASSED;
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute == null) {
                processResult = TestSolution.FAILED;
                addSourceCodeRemark(processResult, workingElement, messageCode, attributeName);
            }
            resultSet.add(processResult);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    @Override
    public TestSolution checkChildNodeExists(String childNodeName) {
        if (messageCode == null) {
            messageCode = CHILD_NODE_MISSING_MSG_CODE;
        }
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            NodeList childNodes = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node childNode = childNodes.item(i);
                if (childNode.getNodeName().equalsIgnoreCase(childNodeName)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                result = TestSolution.FAILED;
                addSourceCodeRemark(result, workingElement, messageCode, childNodeName);
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * 
     * @param childNodeName
     * @param node
     * @return 
     */
    protected boolean checkChildNodeExistsRecursively(String childNodeName, Node node) {// XXX
        if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
            return true;
        }
        NodeList nodes = node.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            if (checkChildNodeExistsRecursively(childNodeName, nodes.item(i))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public TestSolution checkNodeValue(Collection<String> blacklist, Collection<String> whitelist,
            TestSolution testSolution, String erroMessageCode) {
        if (whitelist == null) {
            whitelist = new ArrayList<String>();
        }
        if (blacklist == null) {
            blacklist = new ArrayList<String>();
        }

        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {

            TestSolution result = TestSolution.NEED_MORE_INFO;
            boolean isInBlackList = false;
            boolean isInWhiteList = false;
            String nodeValue = workingElement.getTextContent().trim();

            for (String text : blacklist) {
                if (nodeValue.toLowerCase().equals(text.toLowerCase())) {
                    isInBlackList = true;
                    break;
                }
            }
            for (String text : whitelist) {
                if (nodeValue.toLowerCase().equals(text.toLowerCase())) {
                    isInWhiteList = true;
                    break;
                }
            }
            if (isInBlackList && isInWhiteList) {
                throw new RuntimeException(new IncoherentValueDomainsException());
            }
            if (isInBlackList) {
                result = testSolution;
                addSourceCodeRemark(result, workingElement, erroMessageCode, nodeValue);
            }
            if (isInWhiteList) {
                result = TestSolution.PASSED;
            }
            //            if (result.equals(TestSolution.NEED_MORE_INFO)) {
            //                addSourceCodeRemark(result, workingElement, "VerifyValue",
            //                        nodeValue);
            //            }
            resultSet.add(result);
        }

        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    @Override
    public TestSolution checkTextContentValue(Collection<String> blacklist, Collection<String> whitelist) {

        if (whitelist == null) {
            whitelist = new ArrayList<String>();
        }
        if (blacklist == null) {
            blacklist = new ArrayList<String>();
        }

        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.NEED_MORE_INFO;
            boolean isInBlackList = false;
            boolean isInWhiteList = false;
            String textContent = workingElement.getTextContent();
            for (String text : blacklist) {
                if (textContent.toLowerCase().equals(text.toLowerCase())) {
                    isInBlackList = true;
                    break;
                }
            }
            for (String text : whitelist) {
                if (textContent.toLowerCase().equals(text.toLowerCase())) {
                    isInWhiteList = true;
                    break;
                }
            }
            if (isInBlackList && isInWhiteList) {
                throw new RuntimeException(new IncoherentValueDomainsException());
            }
            if (isInBlackList) {
                result = TestSolution.FAILED;
                addSourceCodeRemark(result, workingElement, "BlackListedValue", textContent);
            }
            if (isInWhiteList) {
                result = TestSolution.PASSED;
            }
            if (result.equals(TestSolution.NEED_MORE_INFO)) {
                addSourceCodeRemark(result, workingElement, "VerifyValue", textContent);
            }
            resultSet.add(result);
        }

        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    protected int getNodeIndex(Node node) {
        NodeList nodeList = document.getElementsByTagName(node.getNodeName());
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node current = nodeList.item(i);
            if (current.equals(node)) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public WebResource getPage() {
        return this.ssp.getPage();
    }

    @Override
    public Collection<ProcessRemark> getRemarkList() {
        return processRemarkService.getRemarkList();
    }

    @Override
    public List<Node> getSelectedElementList() {
        return selectedElementList;
    }

    @Override
    public Elements getSelectedElements() {
        return selectedElements;
    }

    @Override
    public SSP getSSP() {
        return ssp;
    }

    @Override
    public boolean isSelectedElementsEmpty() {
        return selectedElementList.isEmpty();
    }

    @Override
    public DOMHandler keepNodesWithAttribute(String attributeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute != null) {
                elements.add(workingElement);
            }
        }
        selectedElementList = elements;
        return this;
    }

    @Override
    public DOMHandler selectChildNodes(String childNodeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList childNodes = workingElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node childNode = childNodes.item(i);
                if (childNode.getNodeName().equalsIgnoreCase(childNodeName)) {
                    elements.add(childNode);
                }
            }
        }
        selectedElementList = elements;
        return this;
    }

    protected Collection<Node> selectChildNodesRecursively(Collection<String> childNodeNames, Node node) {// XXX
        List<Node> nodes = new ArrayList<Node>();
        for (String childNodeName : childNodeNames) {
            if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
                nodes.add(node);
                break;
            }
        }
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            nodes.addAll(selectChildNodesRecursively(childNodeNames, childNodes.item(i)));
        }
        return nodes;
    }

    @Override
    public DOMHandler selectChildNodesRecursively(String childNodeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList childNodes = workingElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                elements.addAll(selectChildNodesRecursively(childNodeName, childNodes.item(i)));
            }
        }
        selectedElementList = elements;
        return this;
    }

    protected Collection<Node> selectChildNodesRecursively(String childNodeName, Node node) {// XXX
        Collection<Node> nodes = new ArrayList<Node>();
        if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
            nodes.add(node);
        }
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            nodes.addAll(selectChildNodesRecursively(childNodeName, childNodes.item(i)));
        }
        return nodes;
    }

    protected Collection<Node> selectChildNodeWithAttributeRecursively(String attributeName, Node node) {// XXX
        Collection<Node> nodes = new ArrayList<Node>();
        NamedNodeMap attributes = node.getAttributes();
        if (attributes != null) {
            Node attribute = attributes.getNamedItem(attributeName);
            if (attribute != null) {
                nodes.add(node);
            }
        }
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            nodes.addAll(selectChildNodeWithAttributeRecursively(attributeName, childNodes.item(i)));
        }
        return nodes;
    }

    @Override
    public DOMHandler selectDocumentNodes(Collection<String> labels) {
        for (String label : labels) {
            NodeList nodeList = document.getElementsByTagName(label);
            for (int j = 0; j < nodeList.getLength(); j++) {
                selectedElementList.add(nodeList.item(j));
            }
        }
        return this;
    }

    @Override
    public DOMHandler selectDocumentNodes(String tagName) {
        NodeList nodeList = document.getElementsByTagName(tagName);
        for (int j = 0; j < nodeList.getLength(); j++) {
            selectedElementList.add(nodeList.item(j));
        }
        return this;
    }

    /**
     * http://www.ibm.com/developerworks/library/x-javaxpathapi.html
     *
     * @param expr
     * @return
     */
    @Override
    public DOMHandler xPathSelectNodeSet(String expr) {
        try {
            XPathExpression xPathExpression = xpath.compile(expr);
            Object result = xPathExpression.evaluate(document, XPathConstants.NODESET);
            NodeList nodeList = (NodeList) result;
            for (int j = 0; j < nodeList.getLength(); j++) {
                selectedElementList.add(nodeList.item(j));
            }
        } catch (XPathExpressionException ex) {
            throw new RuntimeException(ex);
        }
        return this;
    }

    /**
     * http://www.ibm.com/developerworks/library/x-javaxpathapi.html
     *
     * @param expr
     * @return
     */
    @Override
    public DOMHandler cssLikeSelectNodeSet(String expr) {
        if (StringUtils.isNotBlank(expr)) {
            try {
                selectedElements = jsoupDocument.select(expr);
            } catch (SelectorParseException spe) {
            } catch (IllegalArgumentException iae) {
            }
        }
        return this;
    }

    @Override
    public void setSelectedElementList(List<Node> selectedElementList) {
        this.selectedElementList = selectedElementList;
    }

    @Override
    public void setSSP(SSP ssp) {
        this.ssp = ssp;
        // when a new ssp is set to the handler, the doc needs to be 
        // reinitialised.
        jsoupDocInitialised = false;
        initializeJSoupDocument();
    }

    /**
     * This method checks whether an attribute only contains
     * non alphanumeric characters.
     * 
     * @param attribute
     * @param workingElement
     * @param testSolution
     * @param remarkMessage
     * 
     * @return whether the current element only contains non alphanumerical 
     * characters
     */
    @Override
    public TestSolution checkAttributeOnlyContainsNonAlphanumericCharacters(Node attribute, Node workingElement,
            TestSolution testSolution, String remarkMessage) {
        String attributeContent;
        if (attribute.getNodeName().equalsIgnoreCase("#text")) {
            attributeContent = attribute.getTextContent().toLowerCase();
        } else {
            attributeContent = attribute.getNodeValue().toLowerCase();
        }
        if (NON_ALPHANUMERIC_PATTERN.matcher(attributeContent).matches()) {
            addSourceCodeRemark(testSolution, workingElement, remarkMessage, attribute.getNodeName());
            return testSolution;
        } else {
            return TestSolution.PASSED;
        }
    }

    /**
     * This method checks whether an attribute only contains
     * non alphanumeric characters
     * 
     * @param attributeContent
     * @param workingElement
     * @param testSolution
     * @param remarkMessage
     * 
     * @return whether the current element only contains non alphanumerical 
     * characters
     */
    @Override
    public TestSolution checkAttributeOnlyContainsNonAlphanumericCharacters(String attributeContent,
            Node workingElement, TestSolution testSolution, String remarkMessage) {
        processRemarkService.addEvidenceElement("href");
        if (NON_ALPHANUMERIC_PATTERN.matcher(attributeContent).matches()) {
            addSourceCodeRemark(testSolution, workingElement, remarkMessage, attributeContent);
            return testSolution;
        } else {
            return TestSolution.PASSED;
        }
    }

    @Override
    public int getSelectedElementNumber() {
        if (selectedElementList != null && selectedElementList.size() > 0) {
            return selectedElementList.size();
        } else if (selectedElements != null && selectedElements.size() > 0) {
            return selectedElements.size();
        }
        return 0;
    }

    @Override
    public int getTotalNumberOfElements() {
        if (totalNumberOfElement == -1) {
            totalNumberOfElement = cssLikeSelectNodeSet("*").getSelectedElementNumber();
            selectedElements = new Elements();
        }
        return totalNumberOfElement;
    }

    @Override
    public void setProcessRemarkService(ProcessRemarkService processRemarkService) {
        this.processRemarkService = processRemarkService;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @return
     */
    @Override
    @Deprecated
    public String getMessageCode() {
        return messageCode;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to check
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler selectDocumentNodesWithAttribute(String attributeName) {
        List<Node> elements = new ArrayList<Node>();
        NodeList childNodes = document.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            elements.addAll(selectChildNodeWithAttributeRecursively(attributeName, childNodes.item(i)));
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to check
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkAttributeValueIsEmpty(String attributeName) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute != null) {
                if (attribute.getNodeValue().length() != 0) {
                    result = TestSolution.FAILED;
                    addSourceCodeRemark(result, workingElement, "ValueNotEmpty", attributeName);
                }
            } else {
                result = TestSolution.NOT_APPLICABLE;
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeNames
     *            the names of the childnodes to select recursively
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler selectChildNodesRecursively(Collection<String> childNodeNames) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList childNodes = workingElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                elements.addAll(selectChildNodesRecursively(childNodeNames, childNodes.item(i)));
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeNames
     *            the names of the childnodes to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithoutChildNode(Collection<String> childNodeNames) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList nodeList = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < nodeList.getLength() && !found; i++) {
                Node node = nodeList.item(i);
                for (String childNodeName : childNodeNames) {
                    if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                elements.add(workingElement);
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeName
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithoutChildNode(String childNodeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList nodeList = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                elements.add(workingElement);
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param name
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler selectAttributeByName(String name) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(name);
            if (attribute != null) {
                elements.add(attribute);
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeNames
     *            the names of the childNodes to select
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler selectChildNodes(Collection<String> childNodeNames) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList childNodes = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < childNodes.getLength() && !found; i++) {
                Node childNode = childNodes.item(i);
                for (String childNodeName : childNodeNames) {
                    if (childNode.getNodeName().equalsIgnoreCase(childNodeName)) {
                        elements.add(childNode);
                        found = true;
                        break;
                    }
                }
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to filter
     * @param values
     *            the values of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithAttributeValueEquals(String attributeName, Collection<String> values) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute == null) {
                continue;
            }
            for (String value : values) {
                if (attribute.getNodeValue().equalsIgnoreCase(value)) {
                    elements.add(workingElement);
                    break;
                }
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithAttributeValueNonEmpty(String attributeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute != null && attribute.getNodeValue().length() > 0) {
                elements.add(workingElement);
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to be filteterd
     * @param values
     *            the values of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithAttributeValueStartingWith(String attributeName, Collection<String> values) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute == null) {
                continue;
            }
            for (String value : values) {
                if (attribute.getNodeValue().toLowerCase().startsWith(value.toLowerCase())) {
                    elements.add(workingElement);
                    break;
                }
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to filter
     * @param value
     *            the value of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithAttributeValueStartingWith(String attributeName, String value) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute == null) {
                continue;
            }
            if (attribute.getNodeValue().toLowerCase().startsWith(value.toLowerCase())) {
                elements.add(workingElement);
                break;
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @return
     */
    @Override
    @Deprecated
    public List<String> getTextContentValues() {
        List<String> values = new ArrayList<String>();
        for (Node workingElement : selectedElementList) {
            values.add(workingElement.getTextContent());
        }
        return values;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param length
     *            the length of the text content to check
     * @param defaultFailResult
     *            the default return value if the check processing fails
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkTextContentValueLengthLower(int length, TestSolution defaultFailResult) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            String textContent = workingElement.getTextContent();
            if (textContent.length() > length) {
                result = defaultFailResult;
                addSourceCodeRemark(result, workingElement, "LengthTooLong", textContent);
            }
            resultSet.add(result);
        }

        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkTextContentValueNotEmpty() {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            if (workingElement.getTextContent().length() == 0) {
                result = TestSolution.FAILED;
                addSourceCodeRemark(result, workingElement, "ValueEmpty", workingElement.getNodeValue());
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler excludeNodesWithAttribute(String attributeName) {
        List<Node> nodes = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute == null) {
                nodes.add(workingElement);
            }
        }
        selectedElementList = nodes;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeNames
     *            the names of the childnodes to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler excludeNodesWithChildNode(ArrayList<String> childNodeNames) {
        List<Node> nodes = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList nodeList = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < childNodeNames.size() && !found; i++) {
                String childNodeName = childNodeNames.get(i);
                for (int j = 0; j < nodeList.getLength(); j++) {
                    if (nodeList.item(j).getNodeName().equalsIgnoreCase(childNodeName)) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                nodes.add(workingElement);
            }
        }
        selectedElementList = nodes;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeName
     *            the name of the childNode to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler excludeNodesWithChildNode(String childNodeName) {
        List<Node> nodes = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList nodeList = workingElement.getChildNodes();
            boolean found = false;
            for (int i = 0; i < nodeList.getLength(); i++) {
                if (nodeList.item(i).getNodeName().equalsIgnoreCase(childNodeName)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                nodes.add(workingElement);
            }
        }
        selectedElementList = nodes;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute targeted
     * @return
     */
    @Override
    @Deprecated
    public List<String> getAttributeValues(String attributeName) {
        List<String> values = new ArrayList<String>();
        for (Node workingElement : selectedElementList) {
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute != null) {
                values.add(attribute.getNodeValue());
            }
        }
        return values;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     * @param blacklist
     *            the list of prevented values
     * @param whitelist
     *            the list of granted values
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkTextContentAndAttributeValue(String attributeName, Collection<String> blacklist,
            Collection<String> whitelist) {
        if (whitelist == null) {
            whitelist = new ArrayList<String>();
        }
        if (blacklist == null) {
            blacklist = new ArrayList<String>();
        }

        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.NEED_MORE_INFO;
            boolean isInWhiteList = false;
            boolean isInBlackList = false;
            String textContent = workingElement.getTextContent();
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            for (String text : blacklist) {
                if (textContent.toLowerCase().equals(text.toLowerCase())) {
                    isInBlackList = true;
                    addSourceCodeRemark(result, workingElement, "BlackListedValue", textContent);
                    break;
                }
                if (attribute != null) {
                    if (attribute.getNodeValue().toLowerCase().equals(text.toLowerCase())) {
                        isInBlackList = true;
                        addSourceCodeRemark(result, workingElement, "BlackListedValue", attributeName);
                        break;
                    }
                }
            }
            for (String text : whitelist) {
                if (textContent.toLowerCase().equals(text.toLowerCase())) {
                    isInWhiteList = true;
                    break;
                }
                if (attribute != null) {
                    if (attribute.getNodeValue().toLowerCase().equals(text.toLowerCase())) {
                        isInWhiteList = true;
                        break;
                    }
                }
            }
            if (isInBlackList && isInWhiteList) {
                throw new RuntimeException(new IncoherentValueDomainsException());
            }
            if (isInWhiteList) {
                result = TestSolution.PASSED;
            }
            if (isInBlackList) {
                result = TestSolution.FAILED;
            }
            if (result.equals(TestSolution.NEED_MORE_INFO)) {
                addSourceCodeRemark(result, workingElement, "VerifyValue", attributeName);
            }
            resultSet.add(result);
        }

        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeName
     *            the name of the attribute to filter
     * @return
     */
    @Override
    @Deprecated
    public DOMHandler keepNodesWithChildNode(String childNodeName) {
        List<Node> elements = new ArrayList<Node>();
        for (Node workingElement : selectedElementList) {
            NodeList nodeList = workingElement.getChildNodes();
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                if (node.getNodeName().equalsIgnoreCase(childNodeName)) {
                    elements.add(workingElement);
                }
            }
        }
        selectedElementList = elements;
        return this;
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param childNodeName
     *            the name of the childnode to check
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkChildNodeExistsRecursively(String childNodeName) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            boolean found = false;
            NodeList childNodes = workingElement.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                if (checkChildNodeExistsRecursively(childNodeName, childNodes.item(i))) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                result = TestSolution.FAILED;
                addSourceCodeRemark(result, workingElement, "ChildNodeMissing", childNodeName);
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkContentNotEmpty() {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            if (workingElement.getTextContent().trim().isEmpty() && (workingElement.getChildNodes().getLength() == 0
                    || (workingElement.getChildNodes().getLength() == 1
                            && workingElement.getChildNodes().item(0).getNodeName().equalsIgnoreCase("#text")))) {
                result = TestSolution.FAILED;
                addSourceCodeRemark(result, workingElement, "ValueEmpty", workingElement.getNodeName());
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param expr
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkEachWithXpath(String expr) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node node : selectedElementList) {
            TestSolution tempResult = TestSolution.PASSED;
            try {
                XPathExpression xPathExpression = xpath.compile(expr);
                Boolean check = (Boolean) xPathExpression.evaluate(node, XPathConstants.BOOLEAN);
                if (!check.booleanValue()) {
                    tempResult = TestSolution.FAILED;
                    // addSourceCodeRemark(result, node,
                    // "wrong value, does not respect xpath expression : " +
                    // expr, node.getNodeValue());
                }
            } catch (XPathExpressionException ex) {
                LOGGER.error(ex.getMessage() + " occured requesting " + expr + " on " + ssp.getURI());
                throw new RuntimeException(ex);
            }
            resultSet.add(tempResult);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to check
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkAttributeValueNotEmpty(String attributeName) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            Node attribute = workingElement.getAttributes().getNamedItem(attributeName);
            if (attribute != null) {
                if (attribute.getNodeValue().length() == 0) {
                    result = TestSolution.FAILED;
                    addSourceCodeRemark(result, workingElement, "ValueEmpty", attributeName);
                }
            } else {
                result = TestSolution.NOT_APPLICABLE;
            }
            resultSet.add(result);
        }
        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param blacklist
     *            the list of prevented values
     * @param whitelist
     *            the list of granted values
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkNodeValue(Collection<String> blacklist, Collection<String> whitelist) {
        return checkNodeValue(blacklist, whitelist, TestSolution.FAILED, "BlackListedValue");
    }

    /**
     * @deprecated Kept for backward compatibility.
     * @param attributeName
     *            the name of the attribute to check
     * @param length
     *            the length of the attribute value to check
     * @param defaultFailResult
     *            the default return value if the check processing fails
     * @return
     */
    @Override
    @Deprecated
    public TestSolution checkAttributeValueLengthLower(String attributeName, int length,
            TestSolution defaultFailResult) {
        Collection<TestSolution> resultSet = new ArrayList<TestSolution>();
        for (Node workingElement : selectedElementList) {
            TestSolution result = TestSolution.PASSED;
            String textContent = workingElement.getTextContent();
            if (textContent.length() > length) {
                result = defaultFailResult;
                addSourceCodeRemark(result, workingElement, "LengthTooLong", textContent);
            }
            resultSet.add(result);
        }

        return RuleHelper.synthesizeTestSolutionCollection(resultSet);
    }

}