001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
018 */
019
020package org.nuxeo.ecm.platform.ui.web.restAPI;
021
022import java.io.IOException;
023import java.io.OutputStream;
024import java.security.Principal;
025
026import javax.servlet.http.HttpServletRequest;
027import javax.servlet.http.HttpServletResponse;
028
029import org.dom4j.dom.DOMDocument;
030import org.dom4j.dom.DOMDocumentFactory;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.io.download.DownloadService;
033import org.nuxeo.ecm.core.io.download.DownloadService.ByteRange;
034import org.nuxeo.runtime.api.Framework;
035import org.restlet.Restlet;
036import org.restlet.data.CharacterSet;
037import org.restlet.data.MediaType;
038import org.restlet.data.Request;
039import org.restlet.data.Response;
040import org.restlet.resource.OutputRepresentation;
041import org.restlet.resource.Representation;
042import org.restlet.resource.StringRepresentation;
043import org.w3c.dom.Element;
044
045import com.noelios.restlet.ext.servlet.ServletCall;
046import com.noelios.restlet.http.HttpCall;
047import com.noelios.restlet.http.HttpRequest;
048import com.noelios.restlet.http.HttpResponse;
049
050/**
051 * Base class for Nuxeo Restlet.
052 * <p>
053 * Provides utility methods:
054 * <ul>
055 * <li>error handling
056 * <li>authentication
057 * <li>http request/response retrieval
058 * </ul>
059 *
060 * @author tiry
061 */
062public class BaseNuxeoRestlet extends Restlet {
063
064    // error handling
065
066    protected static void handleError(Response res, String message) {
067        DOMDocumentFactory domFactory = new DOMDocumentFactory();
068        DOMDocument result = (DOMDocument) domFactory.createDocument();
069        handleError(result, res, message);
070    }
071
072    protected static void handleError(Response res, Exception e) {
073        DOMDocumentFactory domFactory = new DOMDocumentFactory();
074        DOMDocument result = (DOMDocument) domFactory.createDocument();
075        handleError(result, res, e.getMessage(), e.getClass().getCanonicalName());
076    }
077
078    protected static void handleError(DOMDocument result, Response res, Exception e) {
079        handleError(result, res, e.getMessage(), e.getClass().getCanonicalName());
080    }
081
082    protected static void handleError(DOMDocument result, Response res, String message) {
083        handleError(result, res, message, null);
084    }
085
086    private static void handleError(DOMDocument result, Response res, String message, String classMessage) {
087        Element error = result.createElement("error");
088        result.setRootElement((org.dom4j.Element) error);
089        error.setAttribute("message", message);
090        if (classMessage != null) {
091            error.setAttribute("class", classMessage);
092        }
093        result.setRootElement((org.dom4j.Element) error);
094
095        Representation rep = new StringRepresentation(result.asXML(), MediaType.APPLICATION_XML);
096        rep.setCharacterSet(CharacterSet.UTF_8);
097        res.setEntity(rep);
098    }
099
100    protected static HttpServletRequest getHttpRequest(Request req) {
101        if (req instanceof HttpRequest) {
102            HttpRequest httpRequest = (HttpRequest) req;
103            HttpCall httpCall = httpRequest.getHttpCall();
104            if (httpCall instanceof ServletCall) {
105                return ((ServletCall) httpCall).getRequest();
106            }
107        }
108        return null;
109    }
110
111    protected static HttpServletResponse getHttpResponse(Response res) {
112        if (res instanceof HttpResponse) {
113            HttpResponse httpResponse = (HttpResponse) res;
114            HttpCall httpCall = httpResponse.getHttpCall();
115            if (httpCall instanceof ServletCall) {
116                return ((ServletCall) httpCall).getResponse();
117            }
118        }
119        return null;
120    }
121
122    protected static Principal getUserPrincipal(Request req) {
123        HttpServletRequest httpServletRequest = getHttpRequest(req);
124        if (httpServletRequest == null) {
125            return null;
126        }
127        return httpServletRequest.getUserPrincipal();
128    }
129
130    protected static String getRestletFullUrl(Request request) {
131        String url = getHttpRequest(request).getRequestURL().toString();
132        String qs = getHttpRequest(request).getQueryString();
133        if (qs != null) {
134            return url + '?' + qs;
135        } else {
136            return url;
137        }
138    }
139
140    protected static String getQueryParamValue(Request req, String paramName, String defaultValue) {
141        return req.getResourceRef().getQueryAsForm().getFirstValue(paramName, defaultValue);
142    }
143
144    /**
145     * Sets the response entity to a representation that will write the blob.
146     *
147     * @param blob the blob
148     * @param byteRange the byte range
149     * @param res the response
150     * @since 7.10
151     */
152    public void setEntityToBlobOutput(Blob blob, ByteRange byteRange, Response res) {
153        res.setEntity(new OutputRepresentation(null) {
154            @Override
155            public void write(OutputStream out) throws IOException {
156                DownloadService downloadService = Framework.getService(DownloadService.class);
157                downloadService.transferBlobWithByteRange(blob, byteRange, () -> out);
158            }
159        });
160    }
161
162}