001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.content.template.factories;
021
022import java.io.File;
023import java.io.IOException;
024import java.util.List;
025import java.util.Map;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.nuxeo.common.Environment;
030import org.nuxeo.common.utils.FileUtils;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.api.Blobs;
033import org.nuxeo.ecm.core.api.DocumentModel;
034import org.nuxeo.ecm.platform.content.template.service.ACEDescriptor;
035import org.nuxeo.ecm.platform.content.template.service.TemplateItemDescriptor;
036import org.nuxeo.ecm.platform.filemanager.api.FileManager;
037import org.nuxeo.runtime.api.Framework;
038
039/**
040 * This factory will import a file using a path defined in the option of the factoryBinding extension point. This path
041 * can be defined using three different prefix. absolute:myAbsolute path will reference a file on the server's
042 * filesystem, nxData:myPath will reference a file inside nuxeo data folder and resource:myPath will reference a file in
043 * the bundle's resources. If the file exist, it's imported by the {@link FileManager} service.
044 *
045 * @author ldoguin
046 */
047public class ImportBasedFactory extends BaseContentFactory {
048
049    private static final Log log = LogFactory.getLog(ImportBasedFactory.class);
050
051    public static final String IMPORT_FILE_PATH_OPTION = "path";
052
053    public static final String IMPORT_OVERWRITE_OPTION = "overwrite";
054
055    protected FileManager fileManager;
056
057    protected Map<String, String> options;
058
059    protected File importedFile;
060
061    protected Boolean overwrite = false;
062
063    public enum PathOptions {
064        resource {
065            @Override
066            public File getFile(String path) {
067                return FileUtils.getResourceFileFromContext(path);
068            }
069        },
070        nxData {
071            @Override
072            public File getFile(String path) {
073                File nxDdataFolder = Environment.getDefault().getData();
074                return new File(nxDdataFolder, path);
075            }
076        },
077        absolute {
078            @Override
079            public File getFile(String path) {
080                return new File(path);
081            }
082        };
083
084        protected abstract File getFile(String path);
085
086        public static File getResource(String path) {
087            String[] s = path.split(":", 2);
088            String resourceType = s[0];
089            String resourcePath = s[1];
090            PathOptions option = valueOf(resourceType);
091            if (option == null) {
092                log.error("Unsupported resource type: " + resourceType);
093                return null;
094            } else {
095                return option.getFile(resourcePath);
096            }
097        }
098    }
099
100    @Override
101    public boolean initFactory(Map<String, String> options, List<ACEDescriptor> rootAcl,
102            List<TemplateItemDescriptor> template) {
103        this.options = options;
104        overwrite = Boolean.valueOf(options.get(IMPORT_OVERWRITE_OPTION));
105        String path = options.get(IMPORT_FILE_PATH_OPTION);
106        File file = PathOptions.getResource(path);
107        if (file != null) {
108            if (file.exists()) {
109                importedFile = file;
110                return true;
111            } else {
112                log.warn("Following file does not exist: " + file.getAbsolutePath());
113            }
114        }
115        return false;
116    }
117
118    @Override
119    public void createContentStructure(DocumentModel eventDoc) {
120        initSession(eventDoc);
121
122        if (eventDoc.isVersion()) {
123            return;
124        }
125        try {
126            String parentPath = eventDoc.getPathAsString();
127            importBlob(importedFile, parentPath);
128        } catch (IOException e) {
129            throw new RuntimeException("Cannot import file: " + importedFile, e);
130        }
131
132    }
133
134    /**
135     * Use fileManager to import the given file.
136     *
137     * @param file to import
138     * @param parentPath of the targetDocument
139     */
140    protected void importBlob(File file, String parentPath) throws IOException {
141        if (file.isDirectory()) {
142            DocumentModel createdFolder = getFileManagerService().createFolder(session, file.getAbsolutePath(),
143                    parentPath);
144            File[] files = file.listFiles();
145            for (File childFile : files) {
146                importBlob(childFile, createdFolder.getPathAsString());
147            }
148        } else {
149            Blob fb = Blobs.createBlob(file);
150            fb.setFilename(file.getName());
151            getFileManagerService().createDocumentFromBlob(session, fb, parentPath, overwrite, fb.getFilename());
152        }
153    }
154
155    protected FileManager getFileManagerService() {
156        if (fileManager == null) {
157            fileManager = Framework.getService(FileManager.class);
158        }
159        return fileManager;
160    }
161}