com.noterik.bart.fs.restlet.FSResource.java Source code

Java tutorial

Introduction

Here is the source code for com.noterik.bart.fs.restlet.FSResource.java

Source

/* 
* FSResource.java
* 
* Copyright (c) 2012 Noterik B.V.
* 
* This file is part of smithers, related to the Noterik Springfield project.
*
* Smithers is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Smithers is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Smithers.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.noterik.bart.fs.restlet;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.ext.xml.DomRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.Put;

import com.noterik.bart.fs.fscommand.CommandRequestHandler;
import com.noterik.bart.fs.fsxml.FSXMLRequestHandler;
import com.noterik.bart.fs.fsxml.auth.DecisionEngine;
import com.noterik.bart.fs.fsxml.auth.TicketProxyDecisionEngine;
import com.noterik.bart.fs.script.FSScriptRequestHandler;
import com.noterik.bart.fs.tools.FSXMLHelper;
import com.noterik.bart.fs.type.MimeType;
import com.noterik.springfield.tools.XMLHelper;
import com.noterik.springfield.tools.fs.FSXMLBuilder;
import com.noterik.springfield.tools.fs.URIParser;

/**
 * This class is the first entry point of all the incoming requests.
 * The idea is to filter the requests by mimetype send them to the correct handler.
 *
 * At this point there are two different mimetypes supported:
 *
 * - text/fsxml
 * - application/fscommand
 *
 * The text/fsxml requests are forwared to the FSXMLRequestHandler
 *
 * The application/fscommand requests are forwarded to the CommandRequestHandler
 *
 * TODO (the part below)
 * Besides sending requests to the correct handler, the nodehandler for the current
 * node is fetched (by parsing the current uri). The node handler is responsible for
 * validating whether the current user is allowed to do the operation.
 *
 * @author Jaap Blom
 */

public class FSResource extends FSDefaultResource {
    /** The FSResource's log4j Logger */
    private static Logger logger = Logger.getLogger(FSResource.class);

    /** the decision engine */
    private DecisionEngine decisionEngine;

    /**
     * Called right after constructor of this resource (every request)
     */
    @Override
    public void doInit() {
        super.doInit();
        decisionEngine = getDecisionEngine(getResourceUri());
    }

    // allowed actions: GET, PUT, POST, DELETE
    public boolean allowPut() {
        return true;
    }

    public boolean allowPost() {
        return true;
    }

    public boolean allowGet() {
        return true;
    }

    public boolean allowDelete() {
        return true;
    }

    private boolean httpblocked = true;

    /**
     * Determine decision engine 
     * 
     * @param resourceUri
     * @return
     */
    private DecisionEngine getDecisionEngine(String resourceUri) {
        DecisionEngine dEngine = null;
        String domain = URIParser.getDomainIdFromUri(resourceUri);
        String propUri = "/domain/" + domain + "/config/authorization/properties/decisionengine";
        String engineName = FSXMLRequestHandler.instance().getPropertyValue(propUri);
        if (engineName == null) {
            dEngine = new DecisionEngine();
        } else if (engineName.equals("TicketProxy")) {
            dEngine = new TicketProxyDecisionEngine();
        } else {
            dEngine = new DecisionEngine();
        }
        return dEngine;
    }

    /**
     * Get
     */
    @Get
    public Representation doGet() {
        if (httpblocked)
            return null;
        logger.debug("GET: " + getResourceUri());
        Representation rep = null;
        if (!decisionEngine.decide(getRequest())) {
            String error = FSXMLBuilder.getErrorMessage("403", "Permission denied", "Please log in",
                    "http://teamelements.noterik.com/team");
            rep = new StringRepresentation(error, MediaType.TEXT_XML);
        } else {
            String data = getRequestBodyData(getRequest().getEntity());
            rep = FSXMLRequestHandler.instance().handleGET(getResourceUri(), data);
        }

        //set access control headers to allow cross domain communication
        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
        if (responseHeaders == null) {
            responseHeaders = new Form();
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
        }

        responseHeaders.add("Access-Control-Allow-Origin", "*");
        responseHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
        return rep;
    }

    /**
     * Post
     */
    @Post
    public void doPost(Representation representation) {
        if (httpblocked)
            return;
        logger.debug("POST: " + getResourceUri());

        String data = getRequestBodyData(representation);
        String response = null;
        if (!decisionEngine.decide(getRequest())) {
            String error = FSXMLBuilder.getErrorMessage("403", "Permission denied", "Please log in",
                    "http://teamelements.noterik.com/team");
            Representation rep = new StringRepresentation(error, MediaType.TEXT_XML);
            getResponse().setEntity(rep);
            return;
        }
        if (data == null) {
            response = FSXMLBuilder.getErrorMessage("500", "The request data could not be found",
                    "Please resend with the correct request data", "http://teamelements.noterik.com/team");
        } else {
            logger.debug("Post request: " + data);
            String uri = getResourceUri();
            MimeType mt = FSXMLHelper.getMimeTypeFromXml(data);
            if (mt == MimeType.MIMETYPE_FS_XML) {
                response = FSXMLRequestHandler.instance().handlePOST(uri, data);
            } else if (mt == MimeType.MIMETYPE_FS_COMMAND) {
                response = CommandRequestHandler.instance().handlePOST(uri, data);
            } else if (mt == MimeType.MIMETYPE_FS_SCRIPT) {
                response = FSScriptRequestHandler.instance().handlePOST(uri, data);
            } else {
                response = FSXMLBuilder.getErrorMessage("500", "Posting data of this mimetype is not supported",
                        "Please resend with the correct mimetype (application/fscommand or text/fsxml)",
                        "http://teamelements.noterik.com/team");
            }
        }
        logger.debug("returning response for POST request: " + response);

        // proper UTF-8 encoding of response
        DomRepresentation dr = null;
        try {
            dr = new DomRepresentation(MediaType.TEXT_XML);
            Document doc = DocumentHelper.parseText(response);
            dr.setDocument(XMLHelper.convert(doc));
        } catch (Exception e) {
            logger.error("", e);
            response = FSXMLBuilder.getErrorMessage("500", "Response data not valid", "",
                    "http://teamelements.noterik.com/team");
            getResponse().setEntity(new StringRepresentation(response, MediaType.TEXT_XML));
        }
        getResponse().setEntity(dr);

        //set access control headers to allow cross domain communication
        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
        if (responseHeaders == null) {
            responseHeaders = new Form();
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
        }

        responseHeaders.add("Access-Control-Allow-Origin", "*");
        responseHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
    }

    /**
     * Put
     */
    @Put
    public void doPut(Representation representation) {
        if (httpblocked)
            return;
        logger.debug("PUT: " + getResourceUri());

        String data = getRequestBodyData(representation);
        String response = null;
        if (!decisionEngine.decide(getRequest())) {
            String error = FSXMLBuilder.getErrorMessage("403", "Permission denied", "Please log in",
                    "http://teamelements.noterik.com/team");
            Representation rep = new StringRepresentation(error, MediaType.TEXT_XML);
            getResponse().setEntity(rep);
            return;
        }
        if (data == null) {
            response = FSXMLBuilder.getErrorMessage("500", "The request data could not be found",
                    "Please resend with the correct request data", "http://teamelements.noterik.com/team");
        } else {
            logger.debug("Put request: " + data);
            MimeType mt = FSXMLHelper.getMimeTypeFromXml(data);
            if (mt == MimeType.MIMETYPE_FS_XML) {
                response = FSXMLRequestHandler.instance().handlePUT(getResourceUri(), data);
            } else if (mt == MimeType.MIMETYPE_FS_SCRIPT) {
                response = FSScriptRequestHandler.instance().handlePUT(getResourceUri(), data);
            } else {
                response = FSXMLBuilder.getErrorMessage("403", "You can only PUT data of the mimetype text/fsxml",
                        "Please resend with the correct mimetype", "http://teamelements.noterik.com/team");
            }
        }
        logger.debug("returning response for PUT request: " + response);

        // proper UTF-8 encoding of response
        DomRepresentation dr = null;
        try {
            dr = new DomRepresentation(MediaType.TEXT_XML);
            Document doc = DocumentHelper.parseText(response);
            dr.setDocument(XMLHelper.convert(doc));
        } catch (Exception e) {
            logger.error("", e);
            response = FSXMLBuilder.getErrorMessage("500", "Response data not valid", "",
                    "http://teamelements.noterik.com/team");
            getResponse().setEntity(new StringRepresentation(response, MediaType.TEXT_XML));
        }
        getResponse().setEntity(dr);

        //set access control headers to allow cross domain communication
        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
        if (responseHeaders == null) {
            responseHeaders = new Form();
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
        }

        responseHeaders.add("Access-Control-Allow-Origin", "*");
        responseHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
    }

    /**
     * Delete
     */
    @Delete
    public void doDelete() {
        if (httpblocked)
            return;

        logger.debug("DELETE: " + getResourceUri());

        if (!decisionEngine.decide(getRequest())) {
            String error = FSXMLBuilder.getErrorMessage("403", "Permission denied", "Please log in",
                    "http://teamelements.noterik.com/team");
            Representation rep = new StringRepresentation(error, MediaType.TEXT_XML);
            getResponse().setEntity(rep);
            return;
        }
        String data = getRequestBodyData(getRequest().getEntity());
        FSScriptRequestHandler.instance().handleDELETE(getResourceUri());
        String response = FSXMLRequestHandler.instance().handleDELETE(getResourceUri(), data);
        logger.debug("returning response for DELETE request: " + response);

        // proper UTF-8 encoding of response
        DomRepresentation dr = null;
        try {
            dr = new DomRepresentation(MediaType.TEXT_XML);
            Document doc = DocumentHelper.parseText(response);
            dr.setDocument(XMLHelper.convert(doc));
        } catch (Exception e) {
            logger.error("", e);
            response = FSXMLBuilder.getErrorMessage("500", "Response data not valid", "",
                    "http://teamelements.noterik.com/team");
            getResponse().setEntity(new StringRepresentation(response, MediaType.TEXT_XML));
        }
        getResponse().setEntity(dr);

        //set access control headers to allow cross domain communication
        Form responseHeaders = (Form) getResponse().getAttributes().get("org.restlet.http.headers");
        if (responseHeaders == null) {
            responseHeaders = new Form();
            getResponse().getAttributes().put("org.restlet.http.headers", responseHeaders);
        }

        responseHeaders.add("Access-Control-Allow-Origin", "*");
        responseHeaders.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        responseHeaders.add("Access-Control-Allow-Headers", "Content-Type");
    }

}