001/*
002 * (C) Copyright 2015 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 *     Nicolas Chapurlat <nchapurlat@nuxeo.com>
016 */
017
018package org.nuxeo.ecm.directory.io;
019
020import static org.nuxeo.ecm.core.io.marshallers.json.document.DocumentPropertiesJsonReader.DEFAULT_SCHEMA_NAME;
021import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
022import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
023import static org.nuxeo.ecm.directory.io.DirectoryEntryJsonWriter.ENTITY_TYPE;
024
025import java.io.Closeable;
026import java.io.IOException;
027import java.lang.reflect.ParameterizedType;
028import java.util.HashMap;
029import java.util.List;
030
031import javax.inject.Inject;
032
033import org.apache.commons.lang3.reflect.TypeUtils;
034import org.codehaus.jackson.JsonNode;
035import org.nuxeo.ecm.core.api.DocumentModel;
036import org.nuxeo.ecm.core.api.model.Property;
037import org.nuxeo.ecm.core.io.marshallers.json.EntityJsonReader;
038import org.nuxeo.ecm.core.io.marshallers.json.document.DocumentPropertiesJsonReader;
039import org.nuxeo.ecm.core.io.registry.reflect.Setup;
040import org.nuxeo.ecm.directory.BaseSession;
041import org.nuxeo.ecm.directory.Directory;
042import org.nuxeo.ecm.directory.Session;
043import org.nuxeo.ecm.directory.api.DirectoryEntry;
044import org.nuxeo.ecm.directory.api.DirectoryService;
045
046/**
047 * Convert Json as {@link DirectoryEntry}.
048 * <p>
049 * Format is (any additional json property is ignored):
050 *
051 * <pre>
052 * {
053 *   "entity-type": "directoryEntry",
054 *   "directoryName": "DIRECTORY_NAME", <- use it to update an existing document
055 *   "properties": {
056 *     <- entry properties depending on the directory schema (password fields are hidden)
057 *     <- format is managed by {@link DocumentPropertiesJsonReader}
058 *   }
059 * }
060 * </pre>
061 *
062 * </p>
063 *
064 * @since 7.2
065 */
066@Setup(mode = SINGLETON, priority = REFERENCE)
067public class DirectoryEntryJsonReader extends EntityJsonReader<DirectoryEntry> {
068
069    @Inject
070    private DirectoryService directoryService;
071
072    public DirectoryEntryJsonReader() {
073        super(ENTITY_TYPE);
074    }
075
076    @Override
077    protected DirectoryEntry readEntity(JsonNode jn) throws IOException {
078        String directoryName = getStringField(jn, "directoryName");
079        Directory directory = directoryService.getDirectory(directoryName);
080        String schema = directory.getSchema();
081
082        JsonNode propsNode = jn.get("properties");
083        if (propsNode != null && !propsNode.isNull() && propsNode.isObject()) {
084            String id = getStringField(propsNode, directory.getIdField());
085            try (Session session = directory.getSession()) {
086                DocumentModel entry = session.getEntry(id);
087                if (entry == null) {
088                    entry = BaseSession.createEntryModel(null, schema, id, new HashMap<String, Object>());
089                }
090                ParameterizedType genericType = TypeUtils.parameterize(List.class, Property.class);
091                try (Closeable resource = ctx.wrap().with(DEFAULT_SCHEMA_NAME, schema).open()) {
092                    List<Property> properties = readEntity(List.class, genericType, propsNode);
093                    for (Property property : properties) {
094                        entry.setPropertyValue(property.getName(), property.getValue());
095                    }
096                }
097                return new DirectoryEntry(directory.getName(), entry);
098            }
099        }
100        return null;
101    }
102}