All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dreamhead.moco.matcher.XmlRequestMatcher Maven / Gradle / Ivy

Go to download

Moco is an easy setup stub framework, mainly focusing on testing and integration.

There is a newer version: 1.5.0
Show newest version
package com.github.dreamhead.moco.matcher;

import com.github.dreamhead.moco.MocoConfig;
import com.github.dreamhead.moco.MocoException;
import com.github.dreamhead.moco.Request;
import com.github.dreamhead.moco.RequestMatcher;
import com.github.dreamhead.moco.extractor.ContentRequestExtractor;
import com.github.dreamhead.moco.extractor.XmlExtractorHelper;
import com.github.dreamhead.moco.resource.Resource;
import com.google.common.base.Optional;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;

import static com.google.common.base.Optional.absent;
import static com.google.common.base.Optional.of;
import static com.google.common.base.Strings.isNullOrEmpty;

public class XmlRequestMatcher extends AbstractRequestMatcher {
    private final XmlExtractorHelper helper = new XmlExtractorHelper();
    private final ContentRequestExtractor extractor;
    private final Resource resource;

    public XmlRequestMatcher(final Resource resource) {
        this.extractor = new ContentRequestExtractor();
        this.resource = resource;
    }

    @Override
    public boolean match(final Request request) {
        try {
            Optional requestDocument = extractDocument(request, extractor);
            return requestDocument.isPresent() && tryToMatch(request, requestDocument.get());
        } catch (SAXException e) {
            return false;
        }
    }

    private boolean tryToMatch(final Request request, final Document document) throws SAXException {
        Document resourceDocument = getResourceDocument(request, this.resource);
        return document.isEqualNode(resourceDocument);
    }

    @Override
    @SuppressWarnings("unchecked")
    public RequestMatcher doApply(final MocoConfig config) {
        if (config.isFor(resource.id())) {
            return new XmlRequestMatcher(resource.apply(config));
        }

        return this;
    }

    private Document getResourceDocument(final Request request, final Resource resource) throws SAXException {
        InputStream stream = resource.readFor(of(request)).toInputStream();
        return extractDocument(new InputSource(stream));
    }

    private Optional extractDocument(final Request request, final ContentRequestExtractor extractor) throws SAXException {
        Optional inputSourceOptional = helper.extractAsInputSource(request, extractor);
        if (!inputSourceOptional.isPresent()) {
            return absent();
        }

        return of(extractDocument(inputSourceOptional.get()));
    }

    private void trimChild(final Node node, final Node child) {
        if (child instanceof Text) {
            if (isNullOrEmpty(child.getNodeValue().trim())) {
                node.removeChild(child);
            }
            return;
        }

        if (child instanceof Element) {
            trimNode(child);
        }
    }

    // Whitespace will be kept by DOM parser.
    private void trimNode(final Node node) {
        NodeList children = node.getChildNodes();
        for (int i = children.getLength() - 1; i >= 0; i--) {
            trimChild(node, children.item(i));
        }
    }

    private DocumentBuilder documentBuilder() {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setCoalescing(true);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setIgnoringComments(true);

        try {
            return dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new MocoException(e);
        }
    }

    private Document extractDocument(final InputSource inputSource) throws SAXException {
        try {
            DocumentBuilder builder = documentBuilder();
            Document document = builder.parse(inputSource);
            document.normalizeDocument();
            trimNode(document);
            return document;
        } catch (IOException e) {
            throw new MocoException(e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy