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 /** 059 * @deprecated since 11.1. Use {@link Framework#getService(Class)} with {@link FileManager} instead. 060 */ 061 @Deprecated 062 protected FileManager fileManager; 063 064 protected Map<String, String> options; 065 066 protected File importedFile; 067 068 protected Boolean overwrite = false; 069 070 public enum PathOptions { 071 resource { 072 @Override 073 public File getFile(String path) { 074 return FileUtils.getResourceFileFromContext(path); 075 } 076 }, 077 nxData { 078 @Override 079 public File getFile(String path) { 080 File nxDdataFolder = Environment.getDefault().getData(); 081 return new File(nxDdataFolder, path); 082 } 083 }, 084 absolute { 085 @Override 086 public File getFile(String path) { 087 return new File(path); 088 } 089 }; 090 091 protected abstract File getFile(String path); 092 093 public static File getResource(String path) { 094 String[] s = path.split(":", 2); 095 String resourceType = s[0]; 096 String resourcePath = s[1]; 097 PathOptions option = valueOf(resourceType); 098 if (option == null) { 099 log.error("Unsupported resource type: {}", resourceType); 100 return null; 101 } else { 102 return option.getFile(resourcePath); 103 } 104 } 105 } 106 107 @Override 108 public boolean initFactory(Map<String, String> options, List<ACEDescriptor> rootAcl, 109 List<TemplateItemDescriptor> template) { 110 this.options = options; 111 overwrite = Boolean.valueOf(options.get(IMPORT_OVERWRITE_OPTION)); 112 String path = options.get(IMPORT_FILE_PATH_OPTION); 113 File file = PathOptions.getResource(path); 114 if (file != null) { 115 if (file.exists()) { 116 importedFile = file; 117 return true; 118 } else { 119 log.warn("Following file does not exist: {}", file::getAbsolutePath); 120 } 121 } 122 return false; 123 } 124 125 @Override 126 public void createContentStructure(DocumentModel eventDoc) { 127 initSession(eventDoc); 128 129 if (eventDoc.isVersion()) { 130 return; 131 } 132 try { 133 String parentPath = eventDoc.getPathAsString(); 134 importBlob(importedFile, parentPath); 135 } catch (IOException e) { 136 throw new RuntimeException("Cannot import file: " + importedFile, e); 137 } 138 139 } 140 141 /** 142 * Use fileManager to import the given file. 143 * 144 * @param file to import 145 * @param parentPath of the targetDocument 146 */ 147 protected void importBlob(File file, String parentPath) throws IOException { 148 FileManager fileManagerService = Framework.getService(FileManager.class); 149 if (file.isDirectory()) { 150 DocumentModel createdFolder = fileManagerService.createFolder(session, file.getAbsolutePath(), parentPath, 151 true); 152 File[] files = file.listFiles(); 153 for (File childFile : files) { 154 importBlob(childFile, createdFolder.getPathAsString()); 155 } 156 } else { 157 Blob fb = Blobs.createBlob(file); 158 fb.setFilename(file.getName()); 159 FileImporterContext context = FileImporterContext.builder(session, fb, parentPath) 160 .overwrite(overwrite) 161 .build(); 162 fileManagerService.createOrUpdateDocument(context); 163 } 164 } 165 166 /** 167 * @deprecated since 11.1. Use {@link Framework#getService(Class)} with {@link FileManager} instead. 168 */ 169 @Deprecated 170 protected FileManager getFileManagerService() { 171 if (fileManager == null) { 172 fileManager = Framework.getService(FileManager.class); 173 } 174 return fileManager; 175 } 176 177}