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.collections.ScopeType;
030import org.nuxeo.common.utils.Path;
031import org.nuxeo.ecm.core.api.CoreSession;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.NuxeoException;
034import org.nuxeo.ecm.core.api.impl.DocumentModelImpl;
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;
040import org.nuxeo.ecm.core.versioning.VersioningService;
041
042/**
043 * Compared to the default {@link DocumentModelWriter} implementation this one does handle versions and allows to plug
044 * {@link ExportExtension}
045 *
046 * @since 7.4
047 */
048public class ExtensibleDocumentWriter extends DocumentModelWriter {
049
050    protected static Log log = LogFactory.getLog(ExtensibleDocumentWriter.class);
051
052    public ExtensibleDocumentWriter(CoreSession session, String parentPath) {
053        super(session, parentPath);
054    }
055
056    protected List<ImportExtension> extensions = new ArrayList<ImportExtension>();
057
058    public void registerExtension(ImportExtension ext) {
059        extensions.add(ext);
060    }
061
062    @Override
063    protected DocumentModel createDocument(ExportedDocument xdoc, Path toPath) {
064        Path parentPath = toPath.removeLastSegments(1);
065        String name = toPath.lastSegment();
066
067        DocumentModel doc = new DocumentModelImpl(parentPath.toString(), name, xdoc.getType());
068
069        // set lifecycle state at creation
070        Element system = xdoc.getDocument().getRootElement().element(ExportConstants.SYSTEM_TAG);
071        String lifeCycleState = system.element(ExportConstants.LIFECYCLE_STATE_TAG).getText();
072        String lifeCyclePolicy = system.element(ExportConstants.LIFECYCLE_POLICY_TAG).getText();
073
074        doc.putContextData(CoreSession.IMPORT_LIFECYCLE_POLICY, lifeCyclePolicy);
075        doc.putContextData(CoreSession.IMPORT_LIFECYCLE_STATE, lifeCycleState);
076
077        // loadFacets before schemas so that additional schemas are not skipped
078        loadFacetsInfo(doc, xdoc.getDocument());
079
080        // then load schemas data
081        loadSchemas(xdoc, doc, xdoc.getDocument());
082
083        if (doc.hasSchema("uid")) {
084            doc.putContextData(ScopeType.REQUEST, VersioningService.SKIP_VERSIONING, true);
085        }
086
087        String uuid = xdoc.getId();
088        if (uuid != null) {
089            ((DocumentModelImpl) doc).setId(uuid);
090        }
091
092        Element version = xdoc.getDocument().getRootElement().element("version");
093        if (version != null) {
094
095            Element e = version.element("isVersion");
096            String isVersion = version.elementText("isVersion");
097
098            if ("true".equals(isVersion)) {
099                String label = version.elementText(IMPORT_VERSION_LABEL.substring(4));
100                String sourceId = version.elementText(IMPORT_VERSION_VERSIONABLE_ID.substring(4));
101                String desc = version.elementText(IMPORT_VERSION_DESCRIPTION.substring(4));
102                String created = version.elementText(IMPORT_VERSION_CREATED.substring(4));
103
104                if (label != null) {
105                    doc.putContextData(ScopeType.REQUEST, IMPORT_VERSION_LABEL, label);
106                }
107                if (sourceId != null) {
108                    doc.putContextData(ScopeType.REQUEST, IMPORT_VERSION_VERSIONABLE_ID, sourceId);
109                }
110                if (desc != null) {
111                    doc.putContextData(ScopeType.REQUEST, IMPORT_VERSION_DESCRIPTION, desc);
112                }
113                if (created != null) {
114                    doc.putContextData(ScopeType.REQUEST, IMPORT_VERSION_CREATED,
115                            (Serializable) new DateType().decode(created));
116                }
117                doc.setPathInfo(null, name);
118                ((DocumentModelImpl) doc).setIsVersion(true);
119
120                doc.putContextData(ScopeType.REQUEST, CoreSession.IMPORT_VERSION_MAJOR,
121                        doc.getPropertyValue("uid:major_version"));
122                doc.putContextData(ScopeType.REQUEST, CoreSession.IMPORT_VERSION_MINOR,
123                        doc.getPropertyValue("uid:minor_version"));
124                doc.putContextData(ScopeType.REQUEST, CoreSession.IMPORT_IS_VERSION, true);
125            }
126        }
127
128        if (doc.getId() != null) {
129            session.importDocuments(Collections.singletonList(doc));
130        } else {
131            doc = session.createDocument(doc);
132        }
133
134        // load into the document the system properties, document needs to exist
135        loadSystemInfo(doc, xdoc.getDocument());
136
137        for (ImportExtension ext : extensions) {
138            try {
139                ext.updateImport(session, doc, xdoc);
140            } catch (Exception e) {
141                log.error("Error while processing extensions", e);
142                throw new NuxeoException(e);
143            }
144        }
145
146        unsavedDocuments += 1;
147        saveIfNeeded();
148
149        return doc;
150    }
151
152}