/*
* (C) Copyright 2014-2016 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Benoit Delbosc
* Florent Guillaume
*/
package org.nuxeo.elasticsearch.io;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.search.lookup.SourceLookup;
import org.nuxeo.common.utils.Path;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelFactory;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.api.PropertyException;
import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;
import org.nuxeo.ecm.core.schema.DocumentType;
import org.nuxeo.ecm.core.schema.FacetNames;
import org.nuxeo.ecm.core.schema.SchemaManager;
import org.nuxeo.ecm.core.schema.types.Schema;
import org.nuxeo.runtime.api.Framework;
/**
* Read a DocumentModel from an ES Json export.
*
* @since 5.9.5
*/
public class JsonDocumentModelReader {
private static final Log log = LogFactory.getLog(JsonDocumentModelReader.class);
private final Map<String, Object> source;
private String sid;
public JsonDocumentModelReader(String json) {
byte[] bytes = json.getBytes();
source = SourceLookup.sourceAsMap(new BytesArray(bytes, 0, bytes.length));
}
public JsonDocumentModelReader(Map<String, Object> source) {
this.source = source;
}
public JsonDocumentModelReader session(CoreSession session) {
sid = session.getSessionId();
return this;
}
public JsonDocumentModelReader sid(String sid) {
this.sid = sid;
return this;
}
public DocumentModel getDocumentModel() {
assert (source != null);
String type = (String) getProperty("ecm:primaryType");
@SuppressWarnings("unchecked")
List<String> mixinTypes = (List<String>) getProperty("ecm:mixinType");
String id = (String) getProperty("ecm:uuid");
String path = (String) getProperty("ecm:path");
String parentId = (String) getProperty("ecm:parentId");
String repositoryName = (String) getProperty("ecm:repository");
boolean isProxy = Boolean.TRUE.equals(getProperty("ecm:isProxy"));
String sourceId = null; // TODO write this in JsonESDocumentWriter
SchemaManager schemaManager = Framework.getService(SchemaManager.class);
DocumentType docType = schemaManager.getDocumentType(type);
// fixup facets, keep only instance facets
Set<String> facets = new HashSet<>(mixinTypes == null ? Collections.emptyList() : mixinTypes);
facets.remove(FacetNames.IMMUTABLE); // system facet
facets.removeAll(docType.getFacets());
Path pathObj = path == null ? null : new Path(path);
DocumentRef docRef = new IdRef(id);
DocumentRef parentRef = parentId == null ? null : new IdRef(parentId);
DocumentModelImpl doc = new DocumentModelImpl(sid, type, id, pathObj, docRef, parentRef, null, facets, sourceId,
repositoryName, isProxy);
// preload DataModel to prevent DB access
for (String schemaName : doc.getSchemas()) { // all schemas including from facets
Schema schema = schemaManager.getSchema(schemaName);
doc.addDataModel(DocumentModelFactory.createDataModel(null, schema));
}
for (String prop : source.keySet()) {
String schema = prop.split(":")[0];
Serializable value = getProperty(prop);
if (value == null) {
continue;
}
if ("ecm".equals(schema)) {
switch (prop) {
case "ecm:currentLifeCycleState":
doc.prefetchCurrentLifecycleState((String) value);
break;
default:
// others not taken in account
}
continue;
}
// regular property
try {
doc.setPropertyValue(prop, value);
} catch (PropertyException e) {
if (log.isDebugEnabled()) {
log.debug(String.format("fetchDocFromEs can not set property %s to %s", prop, value));
}
}
}
doc.setIsImmutable(true);
return doc;
}
protected Serializable getProperty(String name) {
return (Serializable) source.get(name);
}
}