001/* 002 * (C) Copyright 2006-2007 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 - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.content.template.factories; 023 024import java.io.File; 025import java.io.IOException; 026import java.util.List; 027import java.util.Map; 028 029import org.apache.logging.log4j.LogManager; 030import org.apache.logging.log4j.Logger; 031import org.nuxeo.common.Environment; 032import org.nuxeo.common.utils.FileUtils; 033import org.nuxeo.ecm.core.api.Blob; 034import org.nuxeo.ecm.core.api.Blobs; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.platform.content.template.service.ACEDescriptor; 037import org.nuxeo.ecm.platform.content.template.service.TemplateItemDescriptor; 038import org.nuxeo.ecm.platform.filemanager.api.FileImporterContext; 039import org.nuxeo.ecm.platform.filemanager.api.FileManager; 040import org.nuxeo.runtime.api.Framework; 041 042/** 043 * This factory will import a file using a path defined in the option of the factoryBinding extension point. This path 044 * can be defined using three different prefix. absolute:myAbsolute path will reference a file on the server's 045 * filesystem, nxData:myPath will reference a file inside nuxeo data folder and resource:myPath will reference a file in 046 * the bundle's resources. If the file exist, it's imported by the {@link FileManager} service. 047 * 048 * @author ldoguin 049 */ 050public class ImportBasedFactory extends BaseContentFactory { 051 052 private static final Logger log = LogManager.getLogger(ImportBasedFactory.class); 053 054 public static final String IMPORT_FILE_PATH_OPTION = "path"; 055 056 public static final String IMPORT_OVERWRITE_OPTION = "overwrite"; 057 058 protected FileManager fileManager; 059 060 protected Map<String, String> options; 061 062 protected File importedFile; 063 064 protected Boolean overwrite = false; 065 066 public enum PathOptions { 067 resource { 068 @Override 069 public File getFile(String path) { 070 return FileUtils.getResourceFileFromContext(path); 071 } 072 }, 073 nxData { 074 @Override 075 public File getFile(String path) { 076 File nxDdataFolder = Environment.getDefault().getData(); 077 return new File(nxDdataFolder, path); 078 } 079 }, 080 absolute { 081 @Override 082 public File getFile(String path) { 083 return new File(path); 084 } 085 }; 086 087 protected abstract File getFile(String path); 088 089 public static File getResource(String path) { 090 String[] s = path.split(":", 2); 091 String resourceType = s[0]; 092 String resourcePath = s[1]; 093 PathOptions option = valueOf(resourceType); 094 if (option == null) { 095 log.error("Unsupported resource type: {}", resourceType); 096 return null; 097 } else { 098 return option.getFile(resourcePath); 099 } 100 } 101 } 102 103 @Override 104 public boolean initFactory(Map<String, String> options, List<ACEDescriptor> rootAcl, 105 List<TemplateItemDescriptor> template) { 106 this.options = options; 107 overwrite = Boolean.valueOf(options.get(IMPORT_OVERWRITE_OPTION)); 108 String path = options.get(IMPORT_FILE_PATH_OPTION); 109 File file = PathOptions.getResource(path); 110 if (file != null) { 111 if (file.exists()) { 112 importedFile = file; 113 return true; 114 } else { 115 log.warn("Following file does not exist: {}", file::getAbsolutePath); 116 } 117 } 118 return false; 119 } 120 121 @Override 122 public void createContentStructure(DocumentModel eventDoc) { 123 initSession(eventDoc); 124 125 if (eventDoc.isVersion()) { 126 return; 127 } 128 try { 129 String parentPath = eventDoc.getPathAsString(); 130 importBlob(importedFile, parentPath); 131 } catch (IOException e) { 132 throw new RuntimeException("Cannot import file: " + importedFile, e); 133 } 134 135 } 136 137 /** 138 * Use fileManager to import the given file. 139 * 140 * @param file to import 141 * @param parentPath of the targetDocument 142 */ 143 protected void importBlob(File file, String parentPath) throws IOException { 144 if (file.isDirectory()) { 145 DocumentModel createdFolder = getFileManagerService().createFolder(session, file.getAbsolutePath(), 146 parentPath, true); 147 File[] files = file.listFiles(); 148 for (File childFile : files) { 149 importBlob(childFile, createdFolder.getPathAsString()); 150 } 151 } else { 152 Blob fb = Blobs.createBlob(file); 153 fb.setFilename(file.getName()); 154 FileImporterContext context = FileImporterContext.builder(session, fb, parentPath) 155 .overwrite(overwrite) 156 .build(); 157 getFileManagerService().createOrUpdateDocument(context); 158 } 159 } 160 161 protected FileManager getFileManagerService() { 162 if (fileManager == null) { 163 fileManager = Framework.getService(FileManager.class); 164 } 165 return fileManager; 166 } 167}