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