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