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.webengine.WebException;
043import org.nuxeo.runtime.api.Framework;
044
045/**
046 * @since 5.7.3
047 */
048public class NuxeoGroupReader implements MessageBodyReader<NuxeoGroup> {
049
050    @Context
051    JsonFactory factory;
052
053    @Override
054    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
055        return NuxeoGroup.class.isAssignableFrom(type);
056    }
057
058    @Override
059    public NuxeoGroup readFrom(Class<NuxeoGroup> type, Type genericType, Annotation[] annotations, MediaType mediaType,
060            MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException,
061            WebApplicationException {
062        String content = IOUtils.toString(entityStream);
063        if (content.isEmpty()) {
064            throw new WebException("No content in request body", Response.Status.BAD_REQUEST.getStatusCode());
065        }
066
067        return readRequest(content, httpHeaders);
068
069    }
070
071    /**
072     * @param content
073     * @param httpHeaders
074     * @return
075     */
076    private NuxeoGroup readRequest(String json, MultivaluedMap<String, String> httpHeaders) {
077        try {
078            JsonParser jp = factory.createJsonParser(json);
079            return readJson(jp, httpHeaders);
080        } catch (NuxeoException | IOException e) {
081            throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
082        }
083    }
084
085    /**
086     * @param jp
087     * @param httpHeaders
088     * @return
089     * @throws IOException
090     * @throws JsonParseException
091     */
092    private NuxeoGroup readJson(JsonParser jp, MultivaluedMap<String, String> httpHeaders) throws JsonParseException,
093            IOException {
094        JsonToken tok = jp.nextToken();
095
096        // skip {
097        if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
098            tok = jp.nextToken();
099        }
100        String id = null;
101
102        UserManager um = Framework.getLocalService(UserManager.class);
103        NuxeoGroup group = null;
104
105        while (tok != JsonToken.END_OBJECT) {
106            String key = jp.getCurrentName();
107            jp.nextToken();
108            if ("groupname".equals(key)) {
109                id = jp.readValueAs(String.class);
110
111                group = um.getGroup(id);
112                if (group == null) {
113                    group = new NuxeoGroupImpl(id);
114                }
115            } else if ("grouplabel".equals(key)) {
116                group.setLabel(jp.readValueAs(String.class));
117            } else if ("memberUsers".equals(key)) {
118                tok = jp.nextToken();
119                List<String> users = new ArrayList<>();
120                while (tok != JsonToken.END_ARRAY) {
121                    users.add(jp.readValueAs(String.class));
122                    tok = jp.nextToken();
123                }
124                group.setMemberUsers(users);
125            } else if ("memberGroups".equals(key)) {
126                tok = jp.nextToken();
127                List<String> groups = new ArrayList<>();
128                while (tok != JsonToken.END_ARRAY) {
129                    groups.add(jp.readValueAs(String.class));
130                    tok = jp.nextToken();
131                }
132                group.setMemberGroups(groups);
133            } else if ("entity-type".equals(key)) {
134                String entityType = jp.readValueAs(String.class);
135                if (!NuxeoGroupWriter.ENTITY_TYPE.equals(entityType)) {
136                    throw new WebApplicationException(Response.Status.BAD_REQUEST);
137                }
138            }
139            tok = jp.nextToken();
140        }
141        return group;
142
143    }
144
145}