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

org.treetank.service.jaxrx.util.RestXPathProcessor Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * * Neither the name of the University of Konstanz nor the
 * names of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * 
 */
package org.treetank.service.jaxrx.util;

import java.io.IOException;
import java.io.OutputStream;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;

import org.treetank.access.NodeReadTrx;
import org.treetank.access.conf.SessionConfiguration;
import org.treetank.access.conf.StandardSettings;
import org.treetank.api.INodeReadTrx;
import org.treetank.api.ISession;
import org.treetank.api.IStorage;
import org.treetank.axis.AbsAxis;
import org.treetank.exception.TTException;
import org.treetank.service.xml.xpath.XPathAxis;

/**
 * This class is responsible to offer XPath processing functions for REST.
 * 
 * @author Patrick Lang, Lukas Lewandowski, University of Konstanz.
 * 
 */
public class RestXPathProcessor {

    /**
     * This field the begin result element of a XQuery or XPath expression.
     */
    private static transient String beginResult = "";

    /**
     * This field the end result element of a XQuery or XPath expression.
     */
    private static transient String endResult = "";

    /**
     * Path to storage.
     */
    private final IStorage mDatabase;

    /**
     * 
     * Constructor.
     * 
     * @param pDatabase
     *            path to the storage
     */
    public RestXPathProcessor(final IStorage pDatabase) {
        mDatabase = pDatabase;
    }

    /**
     * Getting part of the XML based on a XPath query
     * 
     * @param resourceName
     *            where the content should be extracted
     * @param xpath
     *            contains XPath query
     * @param nodeid
     *            To response the resource with a restid for each node ( true) or without (
     *            false).
     * @param revision
     *            The revision of the requested resource. If null,
     *            than response the latest revision.
     * @param output
     *            The OutputStream reference which have to be modified and
     *            returned
     * @return the queried XML fragment
     * @throws IOException
     *             The exception occurred.
     * @throws TTException
     */
    public OutputStream getXpathResource(final String resourceName, final String xpath, final boolean nodeid,
        final Long revision, final OutputStream output, final boolean wrapResult) throws IOException,
        TTException {

        // work around because of query root char '/'
        String qQuery = xpath;
        if (xpath.charAt(0) == '/')
            qQuery = ".".concat(xpath);
        if (mDatabase.existsResource(resourceName)) {
            if (wrapResult) {
                output.write(beginResult.getBytes());
                doXPathRes(resourceName, revision, output, nodeid, qQuery);
                output.write(endResult.getBytes());
            } else {
                doXPathRes(resourceName, revision, output, nodeid, qQuery);
            }

        } else {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
        return output;
    }

    /**
     * Getting part of the XML based on a XPath query
     * 
     * @param resourceName
     *            where the content should be extracted
     * 
     * @param query
     *            contains XPath query
     * @param rId
     *            To response the resource with a restid for each node ( true) or without (
     *            false).
     * @param doRevision
     *            The revision of the requested resource. If null,
     *            than response the latest revision.
     * @param output
     *            The OutputStream reference which have to be modified and
     *            returned
     * @param doNodeId
     *            specifies whether node id should be shown
     * @param doWrap
     *            output of result elements
     * @throws TTException
     */
    public void getXpathResource(final String resourceName, final long rId, final String query,
        final boolean doNodeId, final Long doRevision, final OutputStream output, final boolean doWrap)
        throws TTException {

        // work around because of query root char '/'
        String qQuery = query;
        if (query.charAt(0) == '/')
            qQuery = ".".concat(query);

        ISession session = null;
        INodeReadTrx rtx = null;
        try {
            if (mDatabase.existsResource(resourceName)) {
                session = mDatabase.getSession(new SessionConfiguration(resourceName, StandardSettings.KEY));
                // Creating a transaction

                if (doRevision == null) {
                    rtx = new NodeReadTrx(session.beginBucketRtx(session.getMostRecentVersion()));
                } else {
                    rtx = new NodeReadTrx(session.beginBucketRtx(doRevision));
                }

                final boolean exist = rtx.moveTo(rId);
                if (exist) {
                    final AbsAxis axis = new XPathAxis(rtx, qQuery);
                    if (doWrap) {
                        output.write(beginResult.getBytes());
                        for (final long key : axis) {
                            WorkerHelper.serializeXML(session, output, false, doNodeId, key, doRevision)
                                .call();
                        }

                        output.write(endResult.getBytes());
                    } else {
                        for (final long key : axis) {
                            WorkerHelper.serializeXML(session, output, false, doNodeId, key, doRevision)
                                .call();
                        }

                    }
                } else {
                    throw new WebApplicationException(404);
                }
            }

        } catch (final Exception globExcep) {
            throw new WebApplicationException(globExcep, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * This method performs an XPath evaluation and writes it to a given output
     * stream.
     * 
     * @param resource
     *            The existing resource.
     * @param revision
     *            The revision of the requested document.
     * @param output
     *            The output stream where the results are written.
     * @param nodeid
     *            true if node id's have to be delivered. false otherwise.
     * @param xpath
     *            The XPath expression.
     * @throws TTException
     */
    private void doXPathRes(final String resource, final Long revision, final OutputStream output,
        final boolean nodeid, final String xpath) throws TTException {
        // Storage connection to treetank
        ISession session = null;
        INodeReadTrx rtx = null;
        try {
            if (mDatabase.existsResource(resource)) {
                session = mDatabase.getSession(new SessionConfiguration(resource, StandardSettings.KEY));
                // Creating a transaction
                if (revision == null) {
                    rtx = new NodeReadTrx(session.beginBucketRtx(session.getMostRecentVersion()));
                } else {
                    rtx = new NodeReadTrx(session.beginBucketRtx(revision));
                }

                final AbsAxis axis = new XPathAxis(rtx, xpath);
                for (final long key : axis) {
                    WorkerHelper.serializeXML(session, output, false, nodeid, key, revision).call();
                }
            }
        } catch (final Exception globExcep) {
            throw new WebApplicationException(globExcep, Response.Status.INTERNAL_SERVER_ERROR);
        } finally {
            WorkerHelper.closeRTX(rtx, session);

        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy