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