001/*
002 * (C) Copyright 2013 Nuxeo SA (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-2.1.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 *     dmetzler
016 */
017package org.nuxeo.ecm.restapi.jaxrs.io.documents;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.lang.annotation.Annotation;
022import java.lang.reflect.Type;
023
024import javax.servlet.http.HttpServletRequest;
025import javax.ws.rs.WebApplicationException;
026import javax.ws.rs.core.Context;
027import javax.ws.rs.core.MediaType;
028import javax.ws.rs.core.MultivaluedMap;
029import javax.ws.rs.core.Response;
030import javax.ws.rs.ext.MessageBodyReader;
031
032import org.apache.commons.io.IOUtils;
033import org.codehaus.jackson.JsonFactory;
034import org.codehaus.jackson.JsonParser;
035import org.codehaus.jackson.JsonToken;
036import org.nuxeo.ecm.automation.jaxrs.io.documents.JSONDocumentModelReader;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.DocumentModelList;
039import org.nuxeo.ecm.core.api.impl.DocumentModelListImpl;
040import org.nuxeo.ecm.core.io.marshallers.json.document.DocumentModelListJsonReader;
041import org.nuxeo.ecm.webengine.WebException;
042import org.nuxeo.ecm.webengine.jaxrs.coreiodelegate.JsonCoreIODelegate;
043
044/**
045 * @since 5.7.3
046 * @deprecated since 7.10 The Nuxeo JSON marshalling was migrated to nuxeo-core-io. This class is replaced by
047 *             {@link DocumentModelListJsonReader} which is registered by default and available to marshal
048 *             {@link DocumentModel}'s list from the Nuxeo Rest API thanks to the JAX-RS marshaller
049 *             {@link JsonCoreIODelegate}
050 */
051@Deprecated
052public class JSONDocumentModelListReader implements MessageBodyReader<DocumentModelList> {
053
054    @Context
055    private HttpServletRequest request;
056
057    @Context
058    JsonFactory factory;
059
060    @Override
061    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
062        return DocumentModelList.class.isAssignableFrom(type);
063    }
064
065    @Override
066    public DocumentModelList readFrom(Class<DocumentModelList> type, Type genericType, Annotation[] annotations,
067            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
068            throws IOException, WebApplicationException {
069        String content = IOUtils.toString(entityStream);
070        if (content.isEmpty()) {
071            if (content.isEmpty()) {
072                throw new WebException("No content in request body", Response.Status.BAD_REQUEST.getStatusCode());
073            }
074
075        }
076        return readRequest(content, httpHeaders, request);
077    }
078
079    /**
080     * @param content
081     * @param httpHeaders
082     * @return
083     * @since 5.7.3
084     */
085    public DocumentModelList readRequest(String content, MultivaluedMap<String, String> httpHeaders,
086            HttpServletRequest request) throws IOException {
087
088        JsonParser jp = factory.createJsonParser(content);
089        return readRequest(jp, httpHeaders, request);
090
091    }
092
093    /**
094     * @param jp
095     * @param httpHeaders
096     * @param request2
097     * @return
098     * @since TODO
099     */
100    public static DocumentModelList readRequest(JsonParser jp, MultivaluedMap<String, String> httpHeaders,
101            HttpServletRequest request) throws IOException {
102        DocumentModelList result = null;
103        jp.nextToken(); // skip {
104        JsonToken tok = jp.nextToken();
105        while (tok != JsonToken.END_OBJECT) {
106            String key = jp.getCurrentName();
107            jp.nextToken();
108            if ("entries".equals(key)) {
109                result = readDocumentEntriesFromJson(jp, httpHeaders, request);
110            } else if ("entity-type".equals(key)) {
111                String entityType = jp.readValueAs(String.class);
112                if (!"documents".equals(entityType)) {
113                    throw new WebApplicationException(Response.Status.BAD_REQUEST);
114                }
115            }
116            tok = jp.nextToken();
117        }
118
119        if (result == null) {
120            throw new WebApplicationException(Response.Status.BAD_REQUEST);
121        } else {
122            return result;
123        }
124    }
125
126    /**
127     * @param jp
128     * @param httpHeaders
129     * @param request
130     * @return
131     * @since 5.7.3
132     */
133    private static DocumentModelList readDocumentEntriesFromJson(JsonParser jp,
134            MultivaluedMap<String, String> httpHeaders, HttpServletRequest request) throws IOException {
135
136        DocumentModelList entries = new DocumentModelListImpl();
137
138        // Skip the start of the array
139
140        while (jp.nextToken() == JsonToken.START_OBJECT) {
141
142            DocumentModel doc = JSONDocumentModelReader.readJson(jp, httpHeaders, request);
143            entries.add(doc);
144        }
145
146        return entries;
147
148    }
149
150}