001/*
002 * (C) Copyright 2014 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 *     bdelbosc
018 */
019package org.nuxeo.elasticsearch.io;
020
021import java.util.Map;
022
023import org.apache.commons.logging.Log;
024import org.apache.commons.logging.LogFactory;
025import org.elasticsearch.common.bytes.BytesArray;
026import org.elasticsearch.search.lookup.SourceLookup;
027import org.nuxeo.common.utils.Path;
028import org.nuxeo.ecm.core.api.CoreSession;
029import org.nuxeo.ecm.core.api.DocumentModel;
030import org.nuxeo.ecm.core.api.DocumentModelFactory;
031import org.nuxeo.ecm.core.api.IdRef;
032import org.nuxeo.ecm.core.api.PropertyException;
033import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;
034import org.nuxeo.ecm.core.schema.DocumentType;
035import org.nuxeo.ecm.core.schema.SchemaManager;
036import org.nuxeo.ecm.core.schema.types.Schema;
037import org.nuxeo.runtime.api.Framework;
038
039/**
040 * Read a DocumentModel from an ES Json export.
041 *
042 * @since 5.9.5
043 */
044public class JsonDocumentModelReader {
045    private static final Log log = LogFactory.getLog(JsonDocumentModelReader.class);
046
047    private final Map<String, Object> source;
048
049    private String sid;
050
051    public JsonDocumentModelReader(String json) {
052        byte[] bytes = json.getBytes();
053        source = SourceLookup.sourceAsMap(new BytesArray(bytes, 0, bytes.length));
054    }
055
056    public JsonDocumentModelReader(Map<String, Object> source) {
057        this.source = source;
058    }
059
060    public JsonDocumentModelReader session(CoreSession session) {
061        sid = session.getSessionId();
062        return this;
063    }
064
065    public JsonDocumentModelReader sid(String sid) {
066        this.sid = sid;
067        return this;
068    }
069
070    public DocumentModel getDocumentModel() {
071        assert (source != null);
072        String type = getType();
073        String name = getPropertyAsString("ecm:name");
074        String id = getPropertyAsString("ecm:uuid");
075        String path = getPropertyAsString("ecm:path");
076        String parentId = getPropertyAsString("ecm:parentId");
077        String repository = getPropertyAsString("ecm:repository");
078
079        DocumentModelImpl doc = new DocumentModelImpl(sid, getType(), id, new Path(path), new IdRef(id),
080                new IdRef(parentId), null, null, null, repository, false);
081
082        // pre load datamodel to prevent DB access
083        DocumentType docType = Framework.getService(SchemaManager.class).getDocumentType(type);
084        for (Schema schema : docType.getSchemas()) {
085            doc.addDataModel(DocumentModelFactory.createDataModel(null, schema));
086        }
087
088        for (String prop : source.keySet()) {
089            String schema = prop.split(":")[0];
090            // schema = schema.replace("dc", "dublincore");
091            String key = prop.split(":")[1];
092            if (source.get(prop) == null) {
093                continue;
094            }
095            String value = getPropertyAsString(prop);
096            if (value.isEmpty() || "[]".equals(value)) {
097                continue;
098            }
099            // System.out.println( String.format("schema: %s, key %s = %s", schema, key, value));
100            if ("ecm".equals(schema)) {
101                switch (key) {
102                case "isProxy":
103                    doc.setIsProxy(Boolean.valueOf(value));
104                    break;
105                case "currentLifeCycleState":
106                    doc.prefetchCurrentLifecycleState(value);
107                    break;
108                case "versionLabel":
109                case "mixinType":
110                    // Can not be done via API
111                    break;
112                default:
113                    // not taken in account
114                }
115            } else {
116                try {
117                    doc.setPropertyValue(prop, value);
118                    // doc.setProperty(schema, key, value);
119                } catch (PropertyException e) {
120                    if (log.isDebugEnabled()) {
121                        log.debug(String.format("fetchDocFromEs can not set property %s to %s", key, value));
122                    }
123                }
124            }
125        }
126        doc.setIsImmutable(true);
127        return doc;
128    }
129
130    private String getType() {
131        return getPropertyAsString("ecm:primaryType");
132    }
133
134    private String getPropertyAsString(String name) {
135        Object prop = source.get(name);
136        return (prop == null) ? "" : prop.toString();
137    }
138}