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.core.io.marshallers.json;
019
020import static org.nuxeo.ecm.core.io.registry.MarshallingConstants.ENTITY_FIELD_NAME;
021
022import java.io.IOException;
023
024import org.codehaus.jackson.JsonNode;
025import org.nuxeo.ecm.core.io.registry.MarshallingException;
026
027/**
028 * Base class to read Nuxeo entity Json and convert it in Objects. This class checks the json is an object, the json
029 * property "entity-type" is present and as expected and delegate the body reading to an abstract method.
030 *
031 * @param <EntityType> The managed Java type.
032 * @since 7.2
033 */
034public abstract class EntityJsonReader<EntityType> extends AbstractJsonReader<EntityType> {
035
036    /**
037     * The expected "entity-type" property in the json.
038     */
039    private final String entityType;
040
041    /**
042     * @param entityType The expected "entity-type" property in the json.
043     */
044    public EntityJsonReader(String entityType) {
045        super();
046        this.entityType = entityType;
047    }
048
049    @Override
050    public final EntityType read(JsonNode jn) throws IOException {
051        if (!jn.isObject()) {
052            throw new MarshallingException("Json does not contain an object as expected");
053        }
054        JsonNode entityNode = jn.get(ENTITY_FIELD_NAME);
055        if (entityNode == null || entityNode.isNull() || !entityNode.isTextual()) {
056            throw new MarshallingException("Json object does not contain an entity-type field as expected");
057        }
058        String entityValue = entityNode.getTextValue();
059        if (!entityType.equals(entityValue)) {
060            throw new MarshallingException("Json object entity-type is wrong. Expected is " + entityType + " but was "
061                    + entityValue);
062        }
063        return readEntity(jn);
064    }
065
066    /**
067     * Implement this method to read the entity.
068     *
069     * @param jn A {@link JsonNode} pointing at the root of the json input.
070     * @return The parsed entity.
071     * @since 7.2
072     */
073    protected abstract EntityType readEntity(JsonNode jn) throws IOException;
074
075}