001/*
002 * Copyright (c) 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 */
013
014package org.nuxeo.ecm.core.io.impl.plugins;
015
016import static org.nuxeo.ecm.core.api.CoreSession.IMPORT_VERSION_CREATED;
017import static org.nuxeo.ecm.core.api.CoreSession.IMPORT_VERSION_DESCRIPTION;
018import static org.nuxeo.ecm.core.api.CoreSession.IMPORT_VERSION_LABEL;
019import static org.nuxeo.ecm.core.api.CoreSession.IMPORT_VERSION_VERSIONABLE_ID;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.List;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.dom4j.Element;
029import org.nuxeo.common.utils.Path;
030import org.nuxeo.ecm.core.api.CoreSession;
031import org.nuxeo.ecm.core.api.DocumentModel;
032import org.nuxeo.ecm.core.api.NuxeoException;
033import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;
034import org.nuxeo.ecm.core.api.versioning.VersioningService;
035import org.nuxeo.ecm.core.io.ExportConstants;
036import org.nuxeo.ecm.core.io.ExportExtension;
037import org.nuxeo.ecm.core.io.ExportedDocument;
038import org.nuxeo.ecm.core.io.ImportExtension;
039import org.nuxeo.ecm.core.schema.types.primitives.DateType;
040
041/**
042 * Compared to the default {@link DocumentModelWriter} implementation this one does handle versions and allows to plug
043 * {@link ExportExtension}
044 *
045 * @since 7.4
046 */
047public class ExtensibleDocumentWriter extends DocumentModelWriter {
048
049    protected static Log log = LogFactory.getLog(ExtensibleDocumentWriter.class);
050
051    public ExtensibleDocumentWriter(CoreSession session, String parentPath) {
052        super(session, parentPath);
053    }
054
055    protected List<ImportExtension> extensions = new ArrayList<>();
056
057    public void registerExtension(ImportExtension ext) {
058        extensions.add(ext);
059    }
060
061    @Override
062    protected DocumentModel createDocument(ExportedDocument xdoc, Path toPath) {
063        Path parentPath = toPath.removeLastSegments(1);
064        String name = toPath.lastSegment();
065
066        DocumentModel doc = session.createDocumentModel(parentPath.toString(), name, xdoc.getType());
067
068        // set lifecycle state at creation
069        Element system = xdoc.getDocument().getRootElement().element(ExportConstants.SYSTEM_TAG);
070        String lifeCycleState = system.element(ExportConstants.LIFECYCLE_STATE_TAG).getText();
071        String lifeCyclePolicy = system.element(ExportConstants.LIFECYCLE_POLICY_TAG).getText();
072
073        doc.putContextData(CoreSession.IMPORT_LIFECYCLE_POLICY, lifeCyclePolicy);
074        doc.putContextData(CoreSession.IMPORT_LIFECYCLE_STATE, lifeCycleState);
075
076        // loadFacets before schemas so that additional schemas are not skipped
077        loadFacetsInfo(doc, xdoc.getDocument());
078
079        // then load schemas data
080        loadSchemas(xdoc, doc, xdoc.getDocument());
081
082        if (doc.hasSchema("uid")) {
083            doc.putContextData(VersioningService.SKIP_VERSIONING, true);
084        }
085
086        String uuid = xdoc.getId();
087        if (uuid != null) {
088            ((DocumentModelImpl) doc).setId(uuid);
089        }
090
091        Element version = xdoc.getDocument().getRootElement().element("version");
092        if (version != null) {
093
094            version.element("isVersion");
095            String isVersion = version.elementText("isVersion");
096
097            if ("true".equals(isVersion)) {
098                String label = version.elementText(IMPORT_VERSION_LABEL.substring(4));
099                String sourceId = version.elementText(IMPORT_VERSION_VERSIONABLE_ID.substring(4));
100                String desc = version.elementText(IMPORT_VERSION_DESCRIPTION.substring(4));
101                String created = version.elementText(IMPORT_VERSION_CREATED.substring(4));
102
103                if (label != null) {
104                    doc.putContextData(IMPORT_VERSION_LABEL, label);
105                }
106                if (sourceId != null) {
107                    doc.putContextData(IMPORT_VERSION_VERSIONABLE_ID, sourceId);
108                }
109                if (desc != null) {
110                    doc.putContextData(IMPORT_VERSION_DESCRIPTION, desc);
111                }
112                if (created != null) {
113                    doc.putContextData(IMPORT_VERSION_CREATED,
114                            (Serializable) new DateType().decode(created));
115                }
116                doc.setPathInfo(null, name);
117                ((DocumentModelImpl) doc).setIsVersion(true);
118
119                doc.putContextData(CoreSession.IMPORT_VERSION_MAJOR,
120                        doc.getPropertyValue("uid:major_version"));
121                doc.putContextData(CoreSession.IMPORT_VERSION_MINOR,
122                        doc.getPropertyValue("uid:minor_version"));
123                doc.putContextData(CoreSession.IMPORT_IS_VERSION, true);
124            }
125        }
126
127        if (doc.getId() != null) {
128            session.importDocuments(Collections.singletonList(doc));
129        } else {
130            doc = session.createDocument(doc);
131        }
132
133        // load into the document the system properties, document needs to exist
134        loadSystemInfo(doc, xdoc.getDocument());
135
136        for (ImportExtension ext : extensions) {
137            try {
138                ext.updateImport(session, doc, xdoc);
139            } catch (Exception e) {
140                log.error("Error while processing extensions", e);
141                throw new NuxeoException(e);
142            }
143        }
144
145        unsavedDocuments += 1;
146        saveIfNeeded();
147
148        return doc;
149    }
150
151}