com.c4om.autoconf.ulysses.extra.svrlinterpreter.SVRLInterpreterProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.c4om.autoconf.ulysses.extra.svrlinterpreter.SVRLInterpreterProcessor.java

Source

/*
Copyright 2014 Universidad Politcnica de Madrid - Center for Open Middleware (http://www.centeropenmiddleware.com)
    
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 com.c4om.autoconf.ulysses.extra.svrlinterpreter;

import static com.c4om.utils.xmlutils.JDOMUtils.*;
import static com.c4om.utils.xmlutils.XMLLibsShortcuts.*;
import static com.c4om.utils.xmlutils.XPathUtils.*;
import static com.c4om.utils.xmlutils.constants.AutoconfXMLConstants.*;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.saxon.s9api.SaxonApiException;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Namespace;
import org.jdom2.input.SAXBuilder;

/**
 * This class is intended to process the information extracted by {@link SVRLInterpreterExtractor}, to produce results.
 * 
 * @author Pablo Alonso Rodriguez (Center for Open Middleware)
 */
public class SVRLInterpreterProcessor {

    /**
     * Constructor
     */
    public SVRLInterpreterProcessor() {

    }

    /**
     * Given a list of lists (List&lt;List&lt;<i>something</i>&gt;&gt;), it returns a list 
     * built by taking the index-th element of the list stored at each position of the list 
     * of lists.
     * @param listOfLists the list of lists
     * @param index the index to filter from
     * @return the list, as described
     * @throws ArrayIndexOutOfBoundsException if there is no element at index <i>index</i> on any of the stored lists.
     */
    private static <E> List<E> listOfListsToSingleList(List<List<E>> listOfLists, int index) {
        List<E> result = new ArrayList<>(listOfLists.size());
        for (int i = 0; i < listOfLists.size(); i++) {
            result.add(listOfLists.get(i).get(index));
        }
        return result;
    }

    /**
     * Method that performs and caches into a Map all the XPath queries for metamodel suggestions
     * @param queries a list of queries to perform
     * @return a map between queries and their resulting elements (as JDOM2 {@link Element} objects)
     * @throws IOException If there are I/O problems
     * @throws JDOMException If there are problems at XML parsing
     */
    private Map<String, List<Element>> performXPathMetamodelSuggestionQueries(List<String> queries)
            throws JDOMException, IOException {
        Map<String, List<Element>> queryCache = new HashMap<>(queries.size());
        Map<String, Document> docs = new HashMap<>();
        for (String query : queries) {
            //Remember: doc=pathAndDoc[0] and path=pathAndDoc[1]
            String[] pathAndDoc = divideDocAndPath(query);
            if (!docs.containsKey(pathAndDoc[0])) {
                Document document = loadJDOMDocumentFromFile(new File(pathAndDoc[0]));
                docs.put(pathAndDoc[0], document);
            }
            Document currentDoc = docs.get(pathAndDoc[0]);
            List<Element> queryResultsFromDoc = performJAXENXPath(pathAndDoc[1], currentDoc);
            queryCache.put(query, queryResultsFromDoc);
        }
        return queryCache;
    }

    /**
     * This method:
     * <ol>
     * <li>Takes an attribute from a source element</li>
     * <li>Detaches it</li>
     * <li>Removes its namespace</li>
     * <li>Attaches it to a destination element</li>
     * </ol>
     * @param sourceElement source element
     * @param destinationElement destination element
     * @param attrName the name of the attribute
     * @param attrNamespace the namespace of the source attribute (it will be removed at destination)
     */
    private static void moveAndRemoveNSOfAttr(Element sourceElement, Element destinationElement, String attrName,
            Namespace attrNamespace) {
        Attribute mandatoryPathAttribute = sourceElement.getAttribute(attrName, attrNamespace);
        if (mandatoryPathAttribute != null) {
            mandatoryPathAttribute.detach();
            mandatoryPathAttribute.setNamespace(Namespace.NO_NAMESPACE);
            destinationElement.setAttribute(mandatoryPathAttribute);
        }
    }

    /**
     * Method that actually performs the process
     * @param intermediateResults a list of intermediate results.
     * @return the resulting report
     * @throws SaxonApiException if a XQuery query fails.
     * @throws IOException required by internal methods, but it will never be thrown (normally)
     * @throws JDOMException if there are problems at XML Parsing
     */
    public Document process(List<List<String>> intermediateResults)
            throws SaxonApiException, JDOMException, IOException {
        SAXBuilder builder = new SAXBuilder();
        Element rootElement = new Element("report", NAMESPACE_SVRL_INTERPETER_REPORT);
        Document result = new Document(rootElement);
        Map<String, List<Element>> queryCache = performXPathMetamodelSuggestionQueries(
                listOfListsToSingleList(intermediateResults, 0));
        for (int i = 0; i < intermediateResults.size(); i++) {
            List<String> intermediateResult = intermediateResults.get(i);
            Element currentDiscrepancyElement = new Element("discrepancy", NAMESPACE_SVRL_INTERPETER_REPORT);
            rootElement.addContent(currentDiscrepancyElement);

            String partialNodeString = saxonQuery(intermediateResult.get(1));
            Reader partialNodeStringReader = new StringReader(partialNodeString);
            Document partialNodeDoc = builder.build(partialNodeStringReader);
            Element partialNode = partialNodeDoc.getRootElement().detach();

            Element currentInterestingPathsElement = new Element("interestingPaths",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            moveAndRemoveNSOfAttr(partialNode, currentInterestingPathsElement, "mandatory-path",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            moveAndRemoveNSOfAttr(partialNode, currentInterestingPathsElement, "base-path",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            moveAndRemoveNSOfAttr(partialNode, currentInterestingPathsElement, "key-subpath",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            moveAndRemoveNSOfAttr(partialNode, currentInterestingPathsElement, "search-path",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            currentDiscrepancyElement.addContent(currentInterestingPathsElement);

            Element currentSuggestedPartialNodeElement = new Element("suggestedPartialNode",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            currentDiscrepancyElement.addContent(currentSuggestedPartialNodeElement);

            currentSuggestedPartialNodeElement.addContent(partialNode);

            Element currentMetamodelSuggestionsElement = new Element("metamodelSuggestions",
                    NAMESPACE_SVRL_INTERPETER_REPORT);
            currentDiscrepancyElement.addContent(currentMetamodelSuggestionsElement);

            List<Element> queryResults = queryCache.get(intermediateResult.get(0));
            for (Element queryResult : queryResults) {
                currentMetamodelSuggestionsElement.addContent(queryResult.clone());
            }

        }
        return result;
    }

}