Package eu.scape_project.planning.services.myexperiment

Source Code of eu.scape_project.planning.services.myexperiment.MyExperimentRESTClient$ComponentQuery

/*******************************************************************************
* Copyright 2006 - 2014 Vienna University of Technology,
* Department of Software Technology and Interactive Systems, IFS
*
* 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 eu.scape_project.planning.services.myexperiment;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;

import org.apache.commons.configuration.Configuration;
import org.apache.jena.atlas.io.IndentedLineBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.NodeFactory;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.shared.PrefixMapping;
import com.hp.hpl.jena.sparql.expr.E_StrContains;
import com.hp.hpl.jena.sparql.expr.ExprVar;
import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueString;
import com.hp.hpl.jena.sparql.serializer.FormatterElement;
import com.hp.hpl.jena.sparql.serializer.SerializationContext;
import com.hp.hpl.jena.sparql.syntax.Element;
import com.hp.hpl.jena.sparql.syntax.ElementFilter;
import com.hp.hpl.jena.sparql.syntax.ElementGroup;
import com.hp.hpl.jena.sparql.syntax.ElementUnion;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

import eu.scape_project.planning.services.PlanningServiceException;
import eu.scape_project.planning.services.myexperiment.domain.SearchResult;
import eu.scape_project.planning.services.myexperiment.domain.WorkflowDescription;
import eu.scape_project.planning.services.myexperiment.domain.WorkflowInfo;
import eu.scape_project.planning.utils.ConfigurationLoader;

/**
* Client to access the REST interface of a myExperiment instance.
*/
public class MyExperimentRESTClient implements Serializable {

    private static final long serialVersionUID = -569647899543358671L;

    private static final Logger LOG = LoggerFactory.getLogger(MyExperimentRESTClient.class);

    /**
     * Elements to request when querying.
     */
    private static final String QUERY_ELEMENTS = "id,title,description,content-uri,content-type";

    /**
     * Elements to request for workflow details.
     */
    private static final String WORKFLOW_ELEMENTS = "id,title,description,type,uploader,preview,svg,license-type,content-uri,content-type,tags,ratings,components";

    private static final int WORKFLOW_URL_GROUP = 1;

    /**
     * Pattern for guessing descriptor URL.
     */
    private static final Pattern WORKFLOW_DL_PATTERN = Pattern
        .compile("(.+\\:\\/\\/.+)workflows\\/(\\d+)(\\.html|/download)(/.+?)?([?&]version=(\\d+))?");

    /**
     * Pattern group number for id.
     */
    private static final int WORKFLOW_PATH_ID_GROUP = 2;

    /**
     * Pattern group number for version.
     */
    private static final int WORKFLOW_PATH_VERSION_GROUP = 4;

    /**
     * Pattern for guessing descriptor URL.
     */
    private static final Pattern WORKFLOW_PATH_PATTERN = Pattern
        .compile("(.+\\:\\/\\/.+)workflows\\/(\\d+)(/versions/(\\d+))?/?");

    /**
     * Pattern group number for id.
     */
    private static final int WORKFLOW_DL_ID_GROUP = 2;

    /**
     * Pattern group number for version.
     */
    private static final int WORKFLOW_DL_VERSION_GROUP = 6;

    /**
     * Describes a query for components using the myExperiment REST endpoint.
     */
    public final class ComponentQuery {
        private static final String PREFIX_NAME = "prefixes";
        private static final String QUERY_NAME = "query";

        private static final String ONTOLOGY_IRI = "http://purl.org/DP/components#";
        private static final String ONTOLOGY_PREFIX = "dpc";

        private static final String WFDESC_IRI = "http://purl.org/wf4ever/wfdesc#";
        private static final String WFDESC_PREFIX = "wfdesc";

        private static final String SKOS_IRI = "http://www.w3.org/2004/02/skos/core#";
        private static final String SKOS_LABEL = SKOS_IRI + "prefLabel";

        private static final String RDF_IRI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
        private static final String RDF_PREFIX = "rdf";
        private static final String TYPE_IRI = RDF_IRI + "type";

        private static final String RDFS_IRI = "http://www.w3.org/2000/01/rdf-schema#";
        private static final String RDFS_PREFIX = "rdfs";

        private WebResource resource = null;
        private String prefixes = "";
        private PrefixMapping prefixMapping = PrefixMapping.Factory.create();
        private Node wfNode;

        private String migrationPathTargetPattern;
        private String dependencyLabelPattern;

        private ElementGroup query = new ElementGroup();
        private ElementUnion handlesMimetypes = new ElementUnion();

        /**
         * Creates a new component query for the provided web resource.
         *
         * @param resource
         *            a web resource
         */
        private ComponentQuery(WebResource resource) {
            this.resource = resource.path(COMPONENTS_PATH);
            wfNode = NodeFactory.createVariable("w");
            addPrefix(RDF_PREFIX, RDF_IRI);
            addPrefix(ONTOLOGY_PREFIX, ONTOLOGY_IRI);
            // Add prefixes already specified in the myExperiment API
            prefixMapping.setNsPrefix(WFDESC_PREFIX, WFDESC_IRI);
            prefixMapping.setNsPrefix(RDFS_PREFIX, RDFS_IRI);
        }

        /**
         * Adds a prefix to the query.
         *
         * @param prefix
         *            the prefix
         * @param iri
         *            the IRI
         * @return this query
         */
        private ComponentQuery addPrefix(String prefix, String iri) {
            if (prefix != null && !prefix.isEmpty() && iri != null && !iri.isEmpty()) {
                prefixes += "PREFIX " + prefix + ":<" + iri + ">\n";
                prefixMapping.setNsPrefix(prefix, iri);
            }
            return this;
        }

        /**
         * Adds an element to the query.
         *
         * @param element
         *            the element to add
         * @return this query
         */
        public ComponentQuery addElement(Element element) {
            query.addElement(element);
            return this;
        }

        /**
         * Adds a profile restriction to the query.
         *
         * @param profile
         *            the profile
         * @return this query
         */
        public ComponentQuery addProfile(String profile) {
            if (profile != null && !profile.isEmpty()) {
                Triple t = new Triple(wfNode, NodeFactory.createURI(ONTOLOGY_IRI + "fits"),
                    NodeFactory.createURI(profile));
                query.addTriplePattern(t);
            }
            return this;
        }

        /**
         * Adds a migration path restriction to the query.
         *
         * @param sourceMimetype
         *            the from mimetype
         * @param targetMimetype
         *            the to mimetype
         * @return this query
         */
        public ComponentQuery addMigrationPath(String sourceMimetype, String targetMimetype) {
            if ((sourceMimetype != null && !sourceMimetype.isEmpty())
                || (targetMimetype != null && !targetMimetype.isEmpty())) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(ONTOLOGY_IRI + "migrates"), node));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(TYPE_IRI), NodeFactory
                    .createURI(ONTOLOGY_IRI + "MigrationPath")));
                if (sourceMimetype != null && !sourceMimetype.isEmpty()) {
                    group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "sourceMimetype"),
                        NodeFactory.createLiteral(sourceMimetype)));
                }
                if (targetMimetype != null && !targetMimetype.isEmpty()) {
                    group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "targetMimetype"),
                        NodeFactory.createLiteral(targetMimetype)));
                }
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds a migration path from restriction to the query.
         *
         * @param sourceMimetype
         *            the from mimetype
         * @return this query
         */
        public ComponentQuery addMigrationPath(String sourceMimetype) {
            return addMigrationPath(sourceMimetype, null);
        }

        /**
         * Sets a migration path pattern for the query.
         *
         * @param pattern
         *            the pattern
         * @return this query
         */
        public ComponentQuery setMigrationPathTargetPattern(String pattern) {
            this.migrationPathTargetPattern = pattern;
            return this;
        }

        /**
         * Adds a handlesMimetype restriction to the query.
         *
         * Note that all mimetypes added using the methods
         * {@link #addHandlesMimetype(String...)},
         * {@link #addHandlesMimetypeWildcard(String...)},
         * {@link #addHandlesMimetypes(String, String)} and
         * {@link #addHandlesMimetypesWildcard(String, String)} will be
         * concatenated using UNION.
         *
         * @param mimetypes
         *            the mimetypes
         * @return this query
         */
        public ComponentQuery addHandlesMimetype(String... mimetypes) {
            if (mimetypes != null && mimetypes.length > 0) {
                ElementGroup elements = new ElementGroup();
                Set<String> mimeset = new HashSet<String>();
                Collections.addAll(mimeset, mimetypes);
                for (String mimetype : mimeset) {
                    if (mimetype != null) {
                        elements.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(ONTOLOGY_IRI
                            + "handlesMimetype"), NodeFactory.createLiteral(mimetype)));
                    }
                }
                handlesMimetypes.addElement(elements);
            }
            return this;
        }

        /**
         * Adds handlesMimetype wildcard restrictions based on the provided
         * mimetypes.
         *
         * Note that all mimetypes added using the methods
         * {@link #addHandlesMimetype(String...)},
         * {@link #addHandlesMimetypeWildcard(String...)},
         * {@link #addHandlesMimetypes(String, String)} and
         * {@link #addHandlesMimetypesWildcard(String, String)} will be
         * concatenated using UNION.
         *
         * @param mimetypes
         *            the base mimetypes
         * @return this query
         */
        public ComponentQuery addHandlesMimetypeWildcard(String... mimetypes) {
            if (mimetypes != null && mimetypes.length > 0) {
                Set<String> wildcards = new HashSet<String>(mimetypes.length);
                for (String mimetype : mimetypes) {
                    wildcards.add(getMimetypeWildcard(mimetype));

                }
                addHandlesMimetype(wildcards.toArray(new String[0]));
            }
            return this;
        }

        /**
         * Adds a handlesMimetypes restriction to the query.
         *
         * Note that all mimetypes added using the methods
         * {@link #addHandlesMimetype(String...)},
         * {@link #addHandlesMimetypeWildcard(String...)},
         * {@link #addHandlesMimetypes(String, String)} and
         * {@link #addHandlesMimetypesWildcard(String, String)} will be
         * concatenated using UNION.
         *
         * @param leftMimetype
         *            the left mimetype
         * @param rightMimetype
         *            the right mimetype
         * @return this query
         */
        public ComponentQuery addHandlesMimetypes(String leftMimetype, String rightMimetype) {
            if (leftMimetype != null && !leftMimetype.isEmpty() && rightMimetype != null && !rightMimetype.isEmpty()) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(ONTOLOGY_IRI + "handlesMimetypes"),
                    node));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(TYPE_IRI), NodeFactory
                    .createURI(ONTOLOGY_IRI + "AcceptedMimetypes")));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "handlesLeftMimetype"),
                    NodeFactory.createLiteral(leftMimetype)));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "handlesRightMimetype"),
                    NodeFactory.createLiteral(rightMimetype)));

                handlesMimetypes.addElement(group);
            }
            return this;
        }

        /**
         * Adds handlesMimetype wildcard restrictions based on the provided
         * mimetypes.
         *
         * Note that all mimetypes added using the methods
         * {@link #addHandlesMimetype(String...)},
         * {@link #addHandlesMimetypeWildcard(String...)},
         * {@link #addHandlesMimetypes(String, String)} and
         * {@link #addHandlesMimetypesWildcard(String, String)} will be
         * concatenated using UNION.
         *
         * @param leftMimetype
         *            the left mimetype
         * @param rightMimetype
         *            the right mimetype
         * @return this query
         */
        public ComponentQuery addHandlesMimetypesWildcard(String leftMimetype, String rightMimetype) {
            if (leftMimetype != null && !leftMimetype.isEmpty() && rightMimetype != null && !rightMimetype.isEmpty()) {
                String leftWildcard = getMimetypeWildcard(leftMimetype);
                String rightWildcard = getMimetypeWildcard(rightMimetype);
                addHandlesMimetypes(leftMimetype, rightWildcard);
                addHandlesMimetypes(leftWildcard, rightMimetype);
                addHandlesMimetypes(leftWildcard, rightWildcard);
            }
            return this;
        }

        /**
         * Adds an input port type restriction to the query.
         *
         * @param accepts
         *            the port type
         * @return this query
         */
        public ComponentQuery addInputPort(String accepts) {
            if (accepts != null && !accepts.isEmpty()) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasInput"), node));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "accepts"), NodeFactory
                    .createURI(accepts)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds a measures input port restriction to the query.
         *
         * @param relatedObject
         *            the object related to the measures
         * @param measure
         *            the measure
         * @return this query
         */
        public ComponentQuery addMeasureInputPort(String relatedObject, String measure) {
            if (measure != null && !measure.isEmpty()) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasInput"), node));
                if (relatedObject != null && !relatedObject.isEmpty()) {
                    group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "relatesTo"),
                        NodeFactory.createURI(ONTOLOGY_IRI + relatedObject)));
                }
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "accepts"), NodeFactory
                    .createURI(measure)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds a measures input port restriction to the query.
         *
         * @param acceptsMeasure
         *            the measures
         * @return this query
         */
        public ComponentQuery addMeasureInputPort(String acceptsMeasure) {
            return addMeasureInputPort(null, acceptsMeasure);
        }

        /**
         * Adds an output port type restriction to the query.
         *
         * @param provides
         *            the port type
         * @return this query
         */
        public ComponentQuery addOutputPort(String provides) {
            if (provides != null && !provides.isEmpty()) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasOutput"), node));
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "provides"), NodeFactory
                    .createURI(provides)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds a measure output port restriction to the query.
         *
         * @param relatedObject
         *            the object related to the measures
         * @param measure
         *            the measure
         * @return this query
         */
        public ComponentQuery addMeasureOutputPort(String relatedObject, String measure) {
            if (measure != null && !measure.isEmpty()) {
                Node node = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasOutput"), node));
                if (relatedObject != null && !relatedObject.isEmpty()) {
                    group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "relatesTo"),
                        NodeFactory.createURI(ONTOLOGY_IRI + relatedObject)));
                }
                group.addTriplePattern(new Triple(node, NodeFactory.createURI(ONTOLOGY_IRI + "provides"), NodeFactory
                    .createURI(measure)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds a measure output port restriction to the query.
         *
         * @param measure
         *            the measure
         * @return this query
         */
        public ComponentQuery addMeasureOutputPort(String measure) {
            return addMeasureOutputPort(null, measure);
        }

        /**
         * Sets the dependency label pattern for the query.
         *
         * @param pattern
         *            the pattern for dependency label
         * @return this query
         */
        public ComponentQuery setDependencyLabelPattern(String pattern) {
            this.dependencyLabelPattern = pattern;
            return this;
        }

        /**
         * Adds an environment restriction to the query.
         *
         * @param environment
         *            the environment
         * @return this query
         */
        public ComponentQuery addInstallationEnvironment(String environment) {
            if (environment != null && !environment.isEmpty()) {
                Node processNode = NodeFactory.createAnon();
                Node installationNode = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasSubProcess"),
                    processNode));
                group.addTriplePattern(new Triple(processNode, NodeFactory.createURI(ONTOLOGY_IRI
                    + "requiresInstallation"), installationNode));
                group.addTriplePattern(new Triple(installationNode, NodeFactory.createURI(ONTOLOGY_IRI
                    + "hasEnvironment"), NodeFactory.createURI(environment)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Adds an environment restriction to the query.
         *
         * @param environmentClass
         *            the environment class
         * @return this query
         */
        public ComponentQuery addInstallationEnvironmentType(String environmentClass) {
            if (environmentClass != null && !environmentClass.isEmpty()) {
                Node processNode = NodeFactory.createAnon();
                Node installationNode = NodeFactory.createAnon();
                Node environmentNode = NodeFactory.createAnon();
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasSubProcess"),
                    processNode));
                group.addTriplePattern(new Triple(processNode, NodeFactory.createURI(ONTOLOGY_IRI
                    + "requiresInstallation"), installationNode));
                group.addTriplePattern(new Triple(installationNode, NodeFactory.createURI(ONTOLOGY_IRI
                    + "hasEnvironment"), environmentNode));
                group.addTriplePattern(new Triple(environmentNode, NodeFactory.createURI(TYPE_IRI), NodeFactory
                    .createURI(environmentClass)));
                query.addElement(group);
            }
            return this;
        }

        /**
         * Finishes the migration path to filter.
         */
        private void finishMigrationPathFilter() {
            if (migrationPathTargetPattern != null && !migrationPathTargetPattern.isEmpty()) {
                Node migrationPath = NodeFactory.createAnon();
                Node toMimetype = NodeFactory.createVariable("migrationPathTarget");
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(ONTOLOGY_IRI + "migrates"),
                    migrationPath));
                group.addTriplePattern(new Triple(migrationPath, NodeFactory.createURI(TYPE_IRI), NodeFactory
                    .createURI(ONTOLOGY_IRI + "MigrationPath")));
                group.addTriplePattern(new Triple(migrationPath,
                    NodeFactory.createURI(ONTOLOGY_IRI + "targetMimetype"), toMimetype));
                query.addElement(group);
                ElementFilter filter = new ElementFilter(new E_StrContains(new ExprVar(toMimetype),
                    new NodeValueString(migrationPathTargetPattern)));
                query.addElementFilter(filter);
            }
        }

        /**
         * Finishes the dependency label filter.
         */
        private void finishDependencyLabelFilter() {
            if (dependencyLabelPattern != null && !dependencyLabelPattern.isEmpty()) {
                Node processNode = NodeFactory.createAnon();
                Node installationNode = NodeFactory.createAnon();
                Node dependencyNode = NodeFactory.createAnon();
                Node dependencyLabel = NodeFactory.createVariable("dependencyLabel");
                ElementGroup group = new ElementGroup();
                group.addTriplePattern(new Triple(wfNode, NodeFactory.createURI(WFDESC_IRI + "hasSubProcess"),
                    processNode));
                group.addTriplePattern(new Triple(processNode, NodeFactory.createURI(ONTOLOGY_IRI
                    + "requiresInstallation"), installationNode));
                group.addTriplePattern(new Triple(installationNode, NodeFactory.createURI(ONTOLOGY_IRI + "dependsOn"),
                    dependencyNode));
                group.addTriplePattern(new Triple(dependencyNode, NodeFactory.createURI(SKOS_LABEL), dependencyLabel));
                query.addElement(group);
                ElementFilter filter = new ElementFilter(new E_StrContains(new ExprVar(dependencyLabel),
                    new NodeValueString(dependencyLabelPattern)));
                query.addElementFilter(filter);
            }
        }

        /**
         * Finishes the dependency label filter.
         */
        private void finishHandlesMimetypes() {
            if (handlesMimetypes != null && !handlesMimetypes.getElements().isEmpty()) {
                if (handlesMimetypes.getElements().size() > 1) {
                    query.addElement(handlesMimetypes);
                } else {
                    query.addElement(handlesMimetypes.getElements().get(0));
                }
            }
        }

        /**
         * Finishes the query for execution.
         */
        public void finishQuery() {
            finishMigrationPathFilter();
            finishDependencyLabelFilter();
            finishHandlesMimetypes();

            IndentedLineBuffer formatBuffer = new IndentedLineBuffer();
            FormatterElement.format(formatBuffer, new SerializationContext(prefixMapping), query);

            try {
                String encqs = URLEncoder.encode(formatBuffer.toString(), "UTF-8");
                String encpf = URLEncoder.encode(prefixes, "UTF-8");
                resource = resource.queryParam(PREFIX_NAME, encpf).queryParam(QUERY_NAME, encqs);
            } catch (UnsupportedEncodingException e) {
                LOG.error("Error encoding query", e);
            }
        }

        /**
         * Creates a wildcard mimetype by using the type of the provided
         * mimetype and '*' as subtype.
         *
         * @param mimetype
         *            the base mimetype
         * @return the wildcard mimetype
         */
        private String getMimetypeWildcard(String mimetype) {
            if (mimetype == null) {
                return null;
            } else if ("".equals(mimetype)) {
                return "";
            }

            int position = mimetype.indexOf('/');
            return mimetype.substring(0, position >= 0 ? position : mimetype.length()) + "/*";
        }
    }

    /**
     * Path to workflow list endpoint.
     */
    private static final String WORKFLOWS_PATH = "workflows.xml";

    /**
     * Path to workflow detail endpoint.
     */
    private static final String WORKFLOW_PATH = "workflow.xml";

    /**
     * Path to query endpoint.
     */
    private static final String COMPONENTS_PATH = "components.xml";

    private static final int NOT_FOUND_STATUS = 404;

    private String myExperimentUri;

    private WebResource myExperiment;

    /**
     * Creates a new rest client for myExperiment.
     */
    public MyExperimentRESTClient() {
        ConfigurationLoader configurationLoader = new ConfigurationLoader();
        Configuration config = configurationLoader.load();
        myExperimentUri = config.getString("myexperiment.rest.uri");

        ClientConfig cc = new DefaultClientConfig();
        Client client = Client.create(cc);

        myExperiment = client.resource(myExperimentUri);
    }

    /**
     * Creates a new rest client for myExperiment.
     *
     * @param myExperiment
     *            web resource to use for requests
     */
    public MyExperimentRESTClient(WebResource myExperiment) {
        this.myExperiment = myExperiment;
    }

    /**
     * Searches for components.
     *
     * @param query
     *            the query to use
     * @return a list of workflows
     * @throws PlanningServiceException
     */
    public List<WorkflowInfo> searchComponents(ComponentQuery query) throws PlanningServiceException {
        GenericType<JAXBElement<SearchResult>> searchResultType = new GenericType<JAXBElement<SearchResult>>() {
        };

        try {
            LOG.debug("Querying myExperiments with [{}]", query.resource.getURI());
            return query.resource.queryParam("elements", QUERY_ELEMENTS).accept(MediaType.APPLICATION_XML_TYPE)
                .get(searchResultType).getValue().getWorkflows();
        } catch (Exception e) {
            throw new PlanningServiceException("Querying myExperiments failed.", e);
        }
    }

    /**
     * Gets the workflow description of a workflow using the default
     * myExperiment URL.
     *
     * @param id
     *            the id of the workflow
     * @param version
     *            the version of the workflow
     * @return a workflow description
     */
    public WorkflowDescription getWorkflow(String id, String version) {
        GenericType<JAXBElement<WorkflowDescription>> workflowType = new GenericType<JAXBElement<WorkflowDescription>>() {
        };
        try {
            LOG.debug("Querying myExperiments for workflow id [{}]", id);
            return myExperiment.path(WORKFLOW_PATH).queryParam("id", id).queryParam("version", version)
                .queryParam("elements", WORKFLOW_ELEMENTS).accept(MediaType.APPLICATION_XML_TYPE).get(workflowType)
                .getValue();
        } catch (UniformInterfaceException e) {
            if (e.getResponse().getStatus() == NOT_FOUND_STATUS) {
                return null;
            } else {
                throw e;
            }
        }
    }

    /**
     * Lists workflows according to the provided tag or with not tag restriction
     * if null is provided.
     *
     * @param tag
     *            the tag to filter or null
     * @return a list of workflows
     */
    public List<WorkflowInfo> listWorkflows(String tag) {
        GenericType<JAXBElement<SearchResult>> searchResultType = new GenericType<JAXBElement<SearchResult>>() {
        };

        WebResource workflows = myExperiment.path(WORKFLOWS_PATH);
        if (tag != null) {
            workflows = workflows.queryParam("tag", tag);
        }
        LOG.debug("Querying myExperiments for workflows with tag [{}]", tag);
        return workflows.queryParam("elements", QUERY_ELEMENTS).accept(MediaType.APPLICATION_XML_TYPE)
            .get(searchResultType).getValue().getWorkflows();
    }

    /**
     * Lists all workflows.
     *
     * @return a list of workflows
     */
    public List<WorkflowInfo> listWorkflows() {
        return listWorkflows(null);
    }

    /**
     * Creates a new component query.
     *
     * @return a query object
     */
    public ComponentQuery createComponentQuery() {
        return new ComponentQuery(myExperiment);
    }

    /**
     * Gets the workflow description of a workflow using the provided workflow
     * descriptor URL.
     *
     * @param descriptor
     *            the descriptor URL of the workflow
     * @return a workflow description
     */
    public static WorkflowDescription getWorkflow(String descriptor) {
        GenericType<JAXBElement<WorkflowDescription>> workflowType = new GenericType<JAXBElement<WorkflowDescription>>() {
        };

        String likelyDescriptor = guessDescriptor(descriptor);
        Client client = Client.create();
        WebResource resource = client.resource(likelyDescriptor).queryParam("elements", WORKFLOW_ELEMENTS);

        try {
            LOG.debug("Querying myExperiments for workflow resource [{}]", likelyDescriptor);
            return resource.accept(MediaType.APPLICATION_XML_TYPE).get(workflowType).getValue();
        } catch (UniformInterfaceException e) {
            if (e.getResponse().getStatus() == NOT_FOUND_STATUS) {
                LOG.debug("Workflow resource [{}] not found", likelyDescriptor);
                return null;
            } else {
                throw e;
            }
        }
    }

    /**
     * Gets the workflow content of a workflow identified by the provided
     * workflowInfo.
     *
     * @param workflowInfo
     *            the workflow info
     * @return the content of the workflow
     */
    public static String getWorkflowContent(WorkflowInfo workflowInfo) {
        try {
            LOG.debug("Querying myExperiment for workflow content for [{}]", workflowInfo.getContentUri());
            return Client.create().resource(workflowInfo.getContentUri()).accept(workflowInfo.getContentType())
                .get(String.class);
        } catch (UniformInterfaceException e) {
            if (e.getResponse().getStatus() == NOT_FOUND_STATUS) {
                LOG.debug("Workflow resource [{}] not found", workflowInfo.getContentUri());
                return null;
            } else {
                throw e;
            }
        }
    }

    /**
     * Creates a descriptor URL based on the provided reference URL to a
     * workflow.
     *
     * @param reference
     *            a URL to a workflow
     * @return the likely descriptor URL or the reference if no match was found
     */
    private static String guessDescriptor(String reference) {
        if (reference.matches("(.+\\:\\/\\/.+workflow.xml)(.*[?&]id=\\d+)")) {
            return reference;
        } else {
            String myExperimentUrl = null;
            String id = null;
            String version = null;

            Matcher dlMatcher = WORKFLOW_DL_PATTERN.matcher(reference);
            if (dlMatcher.matches()) {
                myExperimentUrl = dlMatcher.group(WORKFLOW_URL_GROUP);
                id = dlMatcher.group(WORKFLOW_DL_ID_GROUP);
                version = dlMatcher.group(WORKFLOW_DL_VERSION_GROUP);
            } else {
                Matcher pathMatcher = WORKFLOW_PATH_PATTERN.matcher(reference);
                if (pathMatcher.matches()) {
                    myExperimentUrl = pathMatcher.group(WORKFLOW_URL_GROUP);
                    id = pathMatcher.group(WORKFLOW_PATH_ID_GROUP);
                    version = pathMatcher.group(WORKFLOW_PATH_VERSION_GROUP);
                }
            }

            if (myExperimentUrl != null && id != null) {
                if (version == null) {
                    version = "1";
                }
                return myExperimentUrl + "workflow.xml?id=" + id + "&version=" + version;
            }
        }
        return reference;
    }

}
TOP

Related Classes of eu.scape_project.planning.services.myexperiment.MyExperimentRESTClient$ComponentQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.