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