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.usermanager;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.lang.annotation.Annotation;
022import java.lang.reflect.Type;
023import java.util.ArrayList;
024import java.util.List;
025
026import javax.ws.rs.WebApplicationException;
027import javax.ws.rs.core.Context;
028import javax.ws.rs.core.MediaType;
029import javax.ws.rs.core.MultivaluedMap;
030import javax.ws.rs.core.Response;
031import javax.ws.rs.ext.MessageBodyReader;
032
033import org.apache.commons.io.IOUtils;
034import org.codehaus.jackson.JsonFactory;
035import org.codehaus.jackson.JsonParseException;
036import org.codehaus.jackson.JsonParser;
037import org.codehaus.jackson.JsonToken;
038import org.nuxeo.ecm.core.api.NuxeoException;
039import org.nuxeo.ecm.core.api.NuxeoGroup;
040import org.nuxeo.ecm.core.api.impl.NuxeoGroupImpl;
041import org.nuxeo.ecm.platform.usermanager.UserManager;
042import org.nuxeo.ecm.platform.usermanager.io.NuxeoGroupJsonReader;
043import org.nuxeo.ecm.webengine.WebException;
044import org.nuxeo.ecm.webengine.jaxrs.coreiodelegate.JsonCoreIODelegate;
045import org.nuxeo.runtime.api.Framework;
046
047/**
048 * @since 5.7.3
049 * @deprecated since 7.10 The Nuxeo JSON marshalling was migrated to nuxeo-core-io. This class is replaced by
050 *             {@link NuxeoGroupJsonReader} which is registered by default and available to marshal {@link NuxeoGroup}
051 *             from the Nuxeo Rest API thanks to the JAX-RS marshaller {@link JsonCoreIODelegate}
052 */
053@Deprecated
054public class NuxeoGroupReader implements MessageBodyReader<NuxeoGroup> {
055
056    @Context
057    JsonFactory factory;
058
059    @Override
060    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
061        return NuxeoGroup.class.isAssignableFrom(type);
062    }
063
064    @Override
065    public NuxeoGroup readFrom(Class<NuxeoGroup> type, Type genericType, Annotation[] annotations, MediaType mediaType,
066            MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException,
067            WebApplicationException {
068        String content = IOUtils.toString(entityStream);
069        if (content.isEmpty()) {
070            throw new WebException("No content in request body", Response.Status.BAD_REQUEST.getStatusCode());
071        }
072
073        return readRequest(content, httpHeaders);
074
075    }
076
077    /**
078     * @param content
079     * @param httpHeaders
080     * @return
081     */
082    private NuxeoGroup readRequest(String json, MultivaluedMap<String, String> httpHeaders) {
083        try {
084            JsonParser jp = factory.createJsonParser(json);
085            return readJson(jp, httpHeaders);
086        } catch (NuxeoException | IOException e) {
087            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
088        }
089    }
090
091    /**
092     * @param jp
093     * @param httpHeaders
094     * @return
095     * @throws IOException
096     * @throws JsonParseException
097     */
098    private NuxeoGroup readJson(JsonParser jp, MultivaluedMap<String, String> httpHeaders) throws JsonParseException,
099            IOException {
100        JsonToken tok = jp.nextToken();
101
102        // skip {
103        if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
104            tok = jp.nextToken();
105        }
106        String id = null;
107
108        UserManager um = Framework.getLocalService(UserManager.class);
109        NuxeoGroup group = null;
110
111        while (tok != JsonToken.END_OBJECT) {
112            String key = jp.getCurrentName();
113            jp.nextToken();
114            if ("groupname".equals(key)) {
115                id = jp.readValueAs(String.class);
116
117                group = um.getGroup(id);
118                if (group == null) {
119                    group = new NuxeoGroupImpl(id);
120                }
121            } else if ("grouplabel".equals(key)) {
122                group.setLabel(jp.readValueAs(String.class));
123            } else if ("memberUsers".equals(key)) {
124                tok = jp.nextToken();
125                List<String> users = new ArrayList<>();
126                while (tok != JsonToken.END_ARRAY) {
127                    users.add(jp.readValueAs(String.class));
128                    tok = jp.nextToken();
129                }
130                group.setMemberUsers(users);
131            } else if ("memberGroups".equals(key)) {
132                tok = jp.nextToken();
133                List<String> groups = new ArrayList<>();
134                while (tok != JsonToken.END_ARRAY) {
135                    groups.add(jp.readValueAs(String.class));
136                    tok = jp.nextToken();
137                }
138                group.setMemberGroups(groups);
139            } else if ("entity-type".equals(key)) {
140                String entityType = jp.readValueAs(String.class);
141                if (!NuxeoGroupWriter.ENTITY_TYPE.equals(entityType)) {
142                    throw new WebApplicationException(Response.Status.BAD_REQUEST);
143                }
144            }
145            tok = jp.nextToken();
146        }
147        return group;
148
149    }
150
151}