001/*
002 * (C) Copyright 2015 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 *     Nuxeo
018 */
019
020package org.nuxeo.ecm.showcase.content;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024import org.nuxeo.common.utils.Path;
025import org.nuxeo.ecm.core.api.*;
026import org.nuxeo.ecm.core.io.DocumentPipe;
027import org.nuxeo.ecm.core.io.DocumentReader;
028import org.nuxeo.ecm.core.io.DocumentWriter;
029import org.nuxeo.ecm.core.io.ExportedDocument;
030import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
031import org.nuxeo.ecm.core.io.impl.plugins.NuxeoArchiveReader;
032import org.nuxeo.ecm.platform.audit.api.AuditLogger;
033import org.nuxeo.ecm.platform.audit.api.LogEntry;
034import org.nuxeo.ecm.platform.audit.api.Logs;
035import org.nuxeo.ecm.platform.filemanager.service.extension.ExportedZipImporter;
036import org.nuxeo.runtime.api.Framework;
037
038import java.io.IOException;
039import java.util.Calendar;
040import java.util.Collections;
041import java.util.zip.ZipFile;
042
043/**
044 * @author <a href="mailto:ak@nuxeo.com">Arnaud Kervern</a>
045 * @since 7.10
046 */
047public class ShowcaseContentImporter {
048
049    /**
050     * @deprecated
051     */
052    public static final String INITIALIZED_EVENT = "ShowcaseContentImported";
053
054    /**
055     * When computing event name for the "defaut" contribution; it uses the old global event name in case the showcase
056     * content was already imported.
057     */
058    public static final String DEFAULT_NAME = "default";
059
060    /**
061     * @since 8.4
062     */
063    public static final String INITIALIZED_EVENT_FORMAT = "ShowcaseContentImported_%s";
064
065    private static final Log log = LogFactory.getLog(ShowcaseContentImporter.class);
066
067    protected String name;
068
069    protected CoreSession session;
070
071    protected ShowcaseContentImporter(CoreSession session, String name) {
072        this.session = session;
073        this.name = name;
074    }
075
076    public static void run(CoreSession session, String name, Blob blob) throws IOException {
077        new ShowcaseContentImporter(session, name).create(blob);
078    }
079
080    public DocumentModel create(Blob blob) throws IOException {
081        if (isImported()) {
082            log.debug(String.format("Showcase Content '%s' already imported.", name));
083            return null;
084        }
085
086        DocumentModel doc = create(session, blob, getImportPathRoot(), true);
087
088        markImportDone();
089        return doc;
090    }
091
092    protected DocumentModel create(CoreSession documentManager, Blob content, String path, boolean overwrite)
093            throws IOException {
094        try (CloseableFile source = content.getCloseableFile(".zip")) {
095            try (ZipFile zip = ExportedZipImporter.getArchiveFileIfValid(source.getFile())) {
096                if (zip == null) {
097                    return null;
098                }
099            }
100
101            boolean importWithIds = false;
102            DocumentReader reader = new NuxeoArchiveReader(source.getFile());
103            ExportedDocument root = reader.read();
104            IdRef rootRef = new IdRef(root.getId());
105
106            if (documentManager.exists(rootRef)) {
107                DocumentModel target = documentManager.getDocument(rootRef);
108                if (target.getPath().removeLastSegments(1).equals(new Path(path))) {
109                    importWithIds = true;
110                }
111            }
112            reader.close();
113
114            DocumentRef resultingRef;
115            if (overwrite && importWithIds) {
116                resultingRef = rootRef;
117            } else {
118                String rootName = root.getPath().lastSegment();
119                resultingRef = new PathRef(path, rootName);
120            }
121
122            DocumentWriter writer = new ShowcaseWriter(documentManager, path, 10);
123            reader = new NuxeoArchiveReader(source.getFile());
124            try {
125                DocumentPipe pipe = new DocumentPipeImpl(10);
126                pipe.setReader(reader);
127                pipe.setWriter(writer);
128                pipe.run();
129            } catch (IOException e) {
130                log.warn(e, e);
131                return null;
132            } finally {
133                reader.close();
134                writer.close();
135            }
136            return documentManager.getDocument(resultingRef);
137        }
138    }
139
140    protected boolean isImported() {
141        return Framework.getService(Logs.class).getEventsCount(getEventName()) > 0;
142    }
143
144    protected void markImportDone() {
145        AuditLogger logger = Framework.getService(AuditLogger.class);
146        LogEntry entry = logger.newLogEntry();
147        entry.setEventId(getEventName());
148        entry.setEventDate(Calendar.getInstance().getTime());
149
150        logger.addLogEntries(Collections.singletonList(entry));
151    }
152
153    protected String getEventName() {
154        if (DEFAULT_NAME.equals(name)) {
155            return INITIALIZED_EVENT;
156        }
157        return String.format(INITIALIZED_EVENT_FORMAT, name);
158    }
159
160    protected String getImportPathRoot() {
161        return session.query("Select * from Domain").get(0).getPathAsString();
162    }
163}