org.artificer.server.atom.services.StoredQueryResource.java Source code

Java tutorial

Introduction

Here is the source code for org.artificer.server.atom.services.StoredQueryResource.java

Source

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

import org.apache.commons.lang.text.StrSubstitutor;
import org.artificer.atom.ArtificerAtomConstants;
import org.artificer.atom.ArtificerAtomUtils;
import org.artificer.atom.err.ArtificerAtomException;
import org.artificer.common.ArtificerConfig;
import org.artificer.common.MediaType;
import org.artificer.common.error.ArtificerServerException;
import org.artificer.server.i18n.Messages;
import org.jboss.resteasy.plugins.providers.atom.Entry;
import org.jboss.resteasy.plugins.providers.atom.Feed;
import org.jboss.resteasy.plugins.providers.atom.Link;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.StoredQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import java.net.URI;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * A JAX-RS resource that provides Stored Query support.
 *
 * @author Brett Meyer
 */
@Path("/s-ramp/query")
public class StoredQueryResource extends AbstractFeedResource {

    private static Logger logger = LoggerFactory.getLogger(StoredQueryResource.class);

    public StoredQueryResource() {
    }

    @POST
    @Consumes(MediaType.APPLICATION_ATOM_XML_ENTRY)
    @Produces(MediaType.APPLICATION_ATOM_XML_ENTRY)
    public Entry create(@Context HttpServletRequest request, Entry atomEntry) throws ArtificerServerException {
        try {
            String baseUrl = ArtificerConfig.getBaseUrl(request.getRequestURL().toString());
            StoredQuery storedQuery = ArtificerAtomUtils.unwrapStoredQuery(atomEntry);
            storedQuery = queryService.createStoredQuery(storedQuery);

            return wrapStoredQuery(storedQuery, baseUrl);
        } catch (ArtificerServerException e) {
            // Simply re-throw.  Don't allow the following catch it -- ArtificerServerException is mapped to a
            // unique HTTP response type.
            throw e;
        } catch (Exception e) {
            logError(logger, Messages.i18n.format("ERROR_CREATING_STOREDQUERY"), e);
            throw new ArtificerAtomException(e);
        }
    }

    @PUT
    @Path("{queryName}")
    @Consumes(MediaType.APPLICATION_ATOM_XML_ENTRY)
    public void update(@PathParam("queryName") String queryName, Entry atomEntry) throws ArtificerServerException {
        try {
            StoredQuery storedQuery = ArtificerAtomUtils.unwrapStoredQuery(atomEntry);
            queryService.updateStoredQuery(queryName, storedQuery);
        } catch (ArtificerServerException e) {
            // Simply re-throw.  Don't allow the following catch it -- ArtificerServerException is mapped to a unique
            // HTTP response type.
            throw e;
        } catch (Throwable e) {
            logError(logger, Messages.i18n.format("ERROR_UPDATING_STOREDQUERY", queryName), e);
            throw new ArtificerAtomException(e);
        }
    }

    @GET
    @Path("{queryName}")
    @Produces(MediaType.APPLICATION_ATOM_XML_ENTRY)
    public Entry get(@Context HttpServletRequest request, @PathParam("queryName") String queryName)
            throws ArtificerServerException {
        try {
            String baseUrl = ArtificerConfig.getBaseUrl(request.getRequestURL().toString());
            StoredQuery storedQuery = queryService.getStoredQuery(queryName);

            return wrapStoredQuery(storedQuery, baseUrl);
        } catch (ArtificerServerException e) {
            // Simply re-throw.  Don't allow the following catch it -- ArtificerServerException is mapped to a unique
            // HTTP response type.
            throw e;
        } catch (Throwable e) {
            logError(logger, Messages.i18n.format("ERROR_GETTING_STOREDQUERY", queryName), e);
            throw new ArtificerAtomException(e);
        }
    }

    @GET
    @Produces(MediaType.APPLICATION_ATOM_XML_FEED)
    public Feed list(@Context HttpServletRequest request) throws ArtificerAtomException {
        try {
            String baseUrl = ArtificerConfig.getBaseUrl(request.getRequestURL().toString());
            List<StoredQuery> storedQueries = queryService.getStoredQueries();

            Feed feed = new Feed();
            feed.setTitle("S-RAMP Stored Queries Feed");
            feed.setUpdated(new Date());

            for (StoredQuery storedQuery : storedQueries) {
                feed.getEntries().add(wrapStoredQuery(storedQuery, baseUrl));
            }

            return feed;
        } catch (Exception e) {
            logError(logger, Messages.i18n.format("ERROR_GETTING_STOREDQUERIES"), e);
            throw new ArtificerAtomException(e);
        }
    }

    @GET
    @Path("{queryName}/results")
    @Produces(MediaType.APPLICATION_ATOM_XML_FEED)
    public Feed getResults(@Context HttpServletRequest request, @PathParam("queryName") String queryName,
            @QueryParam("startPage") Integer startPage, @QueryParam("startIndex") Integer startIndex,
            @QueryParam("count") Integer count, @QueryParam("orderBy") String orderBy,
            @QueryParam("ascending") Boolean asc) throws ArtificerServerException {
        try {
            String baseUrl = ArtificerConfig.getBaseUrl(request.getRequestURL().toString());
            StoredQuery storedQuery = queryService.getStoredQuery(queryName);

            Map<String, String> params = new HashMap<>();
            Enumeration<String> paramNames = request.getParameterNames();
            while (paramNames.hasMoreElements()) {
                String paramName = paramNames.nextElement();
                if (!"startPage".equalsIgnoreCase(paramName) && !"startIndex".equalsIgnoreCase(paramName)
                        && !"count".equalsIgnoreCase(paramName) && !"orderBy".equalsIgnoreCase(paramName)
                        && !"ascending".equalsIgnoreCase(paramName))
                    params.put(paramName, request.getParameter(paramName));
            }
            // Parameter replacement in the query string.  Ex:
            // /s-ramp/core/Document[@uuid = '${uuid}']
            // Map: "uuid" -> 12345
            // queryString == /s-ramp/core/Document[@uuid = '12345']
            String queryString = new StrSubstitutor(params).replace(storedQuery.getQueryExpression());

            // TODO: It may be possible to introduce certain optimizations...

            return createArtifactFeed(queryString, startPage, startIndex, count, orderBy, asc,
                    new HashSet<>(storedQuery.getPropertyName()), baseUrl);
        } catch (ArtificerServerException e) {
            // Simply re-throw.  Don't allow the following catch it -- ArtificerServerException is mapped to a unique
            // HTTP response type.
            throw e;
        } catch (Throwable e) {
            logError(logger, Messages.i18n.format("ERROR_EXECUTING_STOREDQUERY", queryName), e);
            throw new ArtificerAtomException(e);
        }
    }

    @DELETE
    @Path("{queryName}")
    public void delete(@PathParam("queryName") String queryName) throws ArtificerServerException {
        try {
            queryService.deleteStoredQuery(queryName);
        } catch (ArtificerServerException e) {
            // Simply re-throw.  Don't allow the following catch it -- ArtificerServerException is mapped to a unique
            // HTTP response type.
            throw e;
        } catch (Throwable e) {
            logError(logger, Messages.i18n.format("ERROR_DELETING_STOREDQUERY", queryName), e);
            throw new ArtificerAtomException(e);
        }
    }

    private Entry wrapStoredQuery(StoredQuery storedQuery, String baseUrl) throws Exception {
        Entry entry = ArtificerAtomUtils.wrapStoredQuery(storedQuery);
        // TODO
        //        entry.setPublished();
        //        entry.setUpdated();

        String atomLink = baseUrl + "/s-ramp/query/" + storedQuery.getQueryName();

        // self link
        Link linkToSelf = new Link();
        linkToSelf.setType(MediaType.APPLICATION_ATOM_XML_ENTRY_TYPE);
        linkToSelf.setRel("self");
        linkToSelf.setHref(new URI(atomLink));
        entry.getLinks().add(linkToSelf);

        // edit link
        Link linkToEdit = new Link();
        linkToEdit.setType(MediaType.APPLICATION_ATOM_XML_ENTRY_TYPE);
        linkToEdit.setRel("edit");
        linkToEdit.setHref(new URI(atomLink));
        entry.getLinks().add(linkToEdit);

        // results link
        // Note: The spec technically requires this for a POST, but it seems useful in other contexts.
        Link linkToResults = new Link();
        linkToResults.setType(MediaType.APPLICATION_ATOM_XML_FEED_TYPE);
        linkToResults.setRel(ArtificerAtomConstants.X_S_RAMP_QUERY_RESULTS);
        linkToResults.setHref(new URI(atomLink + "/results"));
        entry.getLinks().add(linkToResults);

        return entry;
    }
}