001/* 002 * (C) Copyright 2006-2012 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 */ 021package org.nuxeo.ecm.platform.scanimporter.processor; 022 023import java.io.File; 024import java.io.IOException; 025import java.lang.reflect.Constructor; 026import java.nio.file.Files; 027import java.nio.file.Path; 028import java.util.ArrayList; 029import java.util.List; 030import java.util.concurrent.locks.ReentrantReadWriteLock; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.nuxeo.ecm.core.api.NuxeoException; 035import org.nuxeo.ecm.platform.importer.base.GenericMultiThreadedImporter; 036import org.nuxeo.ecm.platform.importer.factories.ImporterDocumentModelFactory; 037import org.nuxeo.ecm.platform.importer.log.BasicLogger; 038import org.nuxeo.ecm.platform.importer.service.DefaultImporterService; 039import org.nuxeo.ecm.platform.importer.source.FileSourceNode; 040import org.nuxeo.ecm.platform.importer.source.SourceNode; 041import org.nuxeo.ecm.platform.scanimporter.service.ImporterConfig; 042import org.nuxeo.ecm.platform.scanimporter.service.ScannedFileMapperService; 043import org.nuxeo.runtime.api.Framework; 044 045/** 046 * Setup the importer with the rights factories 047 * 048 * @author Thierry Delprat 049 */ 050public class ScannedFileImporter { 051 052 private static final Log log = LogFactory.getLog(ScannedFileImporter.class); 053 054 protected static List<String> processedDescriptors; 055 056 protected static ReentrantReadWriteLock processedLock = new ReentrantReadWriteLock(); 057 058 public ScannedFileImporter() { 059 processedDescriptors = new ArrayList<String>(); 060 } 061 062 public static void addProcessedDescriptor(String fileDesc) { 063 processedLock.writeLock().lock(); 064 try { 065 processedDescriptors.add(fileDesc); 066 if (processedDescriptors.size() % 100 == 0) { 067 doCleanUp(); 068 } 069 } finally { 070 processedLock.writeLock().unlock(); 071 } 072 } 073 074 protected static void doCleanUp() { 075 076 ScannedFileMapperService sfms = Framework.getService(ScannedFileMapperService.class); 077 ImporterConfig config = sfms.getImporterConfig(); 078 File outDir = null; 079 080 if (config != null) { 081 String outPath = config.getProcessedPath(); 082 if (outPath != null) { 083 outDir = new File(outPath); 084 if (!outDir.exists()) { 085 outDir = null; 086 } 087 } 088 } 089 for (String fileDesc : processedDescriptors) { 090 File file = new File(fileDesc); 091 if (file.exists()) { 092 if (outDir == null) { 093 file.delete(); 094 } else { 095 Path source = file.toPath(); 096 Path target = outDir.toPath().resolve(file.getName()); 097 try { 098 Files.move(source, target); 099 } catch (IOException e) { 100 log.error("An exception occured while moving " + source.getFileName(), e); 101 } 102 } 103 } 104 } 105 processedDescriptors = new ArrayList<String>(); 106 } 107 108 public void doImport() { 109 110 ScannedFileMapperService sfms = Framework.getService(ScannedFileMapperService.class); 111 112 ImporterConfig config = sfms.getImporterConfig(); 113 if (config == null) { 114 log.error("No configuration can be found, exit importer"); 115 return; 116 } 117 File folder = new File(config.getSourcePath()); 118 119 doImport(folder, config); 120 } 121 122 public void doImport(File folder, ImporterConfig config) { 123 124 if (folder == null || !folder.exists()) { 125 throw new NuxeoException("Unable to access source folder " + folder); 126 } 127 if (config.getTargetPath() == null) { 128 throw new NuxeoException("target path must be set"); 129 } 130 131 if (folder.listFiles().length == 0) { 132 log.info("Nothing to import exiting"); 133 return; 134 } 135 136 log.info("Starting import process on path " + config.getTargetPath() + " from source " 137 + folder.getAbsolutePath()); 138 SourceNode src = initSourceNode(folder); 139 140 ScanedFileSourceNode.useXMLMapping = config.useXMLMapping(); 141 GenericMultiThreadedImporter importer = new GenericMultiThreadedImporter(src, config.getTargetPath(), 142 !config.isCreateInitialFolder(), config.getBatchSize(), config.getNbThreads(), new BasicLogger(log)); 143 144 ImporterDocumentModelFactory factory = initDocumentModelFactory(config); 145 importer.setEnablePerfLogging(Framework.getService( 146 DefaultImporterService.class).getEnablePerfLogging()); 147 importer.setFactory(factory); 148 importer.setTransactionTimeout(config.getTransactionTimeout()); 149 importer.run(); 150 151 log.info("Fininish moving files"); 152 doCleanUp(); 153 154 log.info("Ending import process"); 155 } 156 157 /** 158 * @since 5.7.3 159 */ 160 private ImporterDocumentModelFactory initDocumentModelFactory(ImporterConfig config) { 161 Class<? extends ImporterDocumentModelFactory> factoryClass = Framework.getService( 162 DefaultImporterService.class).getDocModelFactoryClass(); 163 // Class<? extends DefaultDocumentModelFactory> factoryClass = ScanedFileFactory.class; 164 Constructor<? extends ImporterDocumentModelFactory> cst = null; 165 166 try { 167 try { 168 cst = factoryClass.getConstructor(ImporterConfig.class); 169 return cst.newInstance(config); 170 } catch (NoSuchMethodException e) { 171 return factoryClass.newInstance(); 172 } 173 } catch (ReflectiveOperationException e) { 174 throw new NuxeoException(e); 175 } 176 } 177 178 /** 179 * @throws Exception 180 * @since 5.7.3 181 */ 182 private SourceNode initSourceNode(File file) { 183 Class<? extends SourceNode> srcClass = Framework.getService(DefaultImporterService.class).getSourceNodeClass(); 184 // Class<? extends SourceNode> srcClass = ScanedFileSourceNode.class; 185 if (!FileSourceNode.class.isAssignableFrom(srcClass)) { 186 throw new NuxeoException("Waiting source node extending FileSourceNode for Scan Importer"); 187 } 188 try { 189 return srcClass.getConstructor(File.class).newInstance(file); 190 } catch (ReflectiveOperationException e) { 191 throw new NuxeoException(e); 192 } 193 } 194 195}