001 /* 002 * BatchProcessorOperation 003 * 004 * Copyright (c) 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.ops; 009 010 import java.io.File; 011 import java.util.Vector; 012 013 /** 014 * Small data class for names of directories that are to be 015 * processed. 016 * @author Marco Schmidt 017 */ 018 class DirectoryTree 019 { 020 /** 021 * Input directory name, as found in the file system. 022 */ 023 String input; 024 025 /** 026 * Corresponding output directory name, may not yet be in the file system. 027 */ 028 String output; 029 } 030 031 /** 032 * Abstract base class to do batch processing on files and complete directory trees. 033 * For a non-abstract extension of this operation, you must implement {@link #processFile}. 034 * @author Marco Schmidt 035 * @since 0.11.0 036 */ 037 public abstract class BatchProcessorOperation extends Operation 038 { 039 private boolean collectErrors; 040 private Vector directoryTrees = new Vector(); 041 private Vector errorMessages = new Vector(); 042 private Vector inputFileNames = new Vector(); 043 private String outputDirectory; 044 private boolean overwrite; 045 046 /** 047 * Adds the argument to the list of directories to be completely 048 * processed. 049 * @param rootDirectoryName name of the root of the directory tree, can be any valid directory name 050 */ 051 public void addDirectoryTree(String rootDirectoryName) 052 { 053 addDirectoryTree(rootDirectoryName, null); 054 } 055 056 /** 057 * Adds the first argument to the list of directories to be completely 058 * processed, writes all output files to the directory tree specified by 059 * the second argument. 060 * @param rootDirectoryName name of the root of the directory tree, can be any valid directory name 061 * @param outputRootDirectoryName name of the root of the directory tree, can be any valid directory name 062 */ 063 public void addDirectoryTree(String rootDirectoryName, String outputRootDirectoryName) 064 { 065 DirectoryTree tree = new DirectoryTree(); 066 tree.input = rootDirectoryName; 067 tree.output = outputRootDirectoryName; 068 directoryTrees.addElement(tree); 069 } 070 071 /** 072 * Adds a single name to the list of file names to be processed. 073 * @param fileName name to be added to list 074 */ 075 public void addInputFileName(String fileName) 076 { 077 inputFileNames.addElement(fileName); 078 } 079 080 /** 081 * Adds a number of file names to the internal list of file names to be processed. 082 * @param fileNameList list of file names, each object in the list must be a String 083 */ 084 public void addInputFileNames(Vector fileNameList) 085 { 086 int index = 0; 087 while (index < fileNameList.size()) 088 { 089 String fileName = (String)fileNameList.elementAt(index++); 090 inputFileNames.addElement(fileName); 091 } 092 } 093 094 /** 095 * Returns a list of error messages collected during the execution of {@link #process}. 096 * @return list of error messages, each object is a String 097 */ 098 public Vector getErrorMessages() 099 { 100 return errorMessages; 101 } 102 103 /** 104 * Returns the current overwrite setting. 105 * @return whether existing files are to be overwritten 106 */ 107 public boolean getOverwrite() 108 { 109 return overwrite; 110 } 111 112 /** 113 * Processes all directory trees and files given to this operation, 114 * calling {@link #processFile} on each file name. 115 */ 116 public void process() 117 { 118 // process directory trees 119 int index = 0; 120 while (index < directoryTrees.size()) 121 { 122 DirectoryTree tree = (DirectoryTree)directoryTrees.elementAt(index++); 123 String output = tree.output; 124 if (output == null) 125 { 126 output = outputDirectory; 127 } 128 processDirectoryTree(tree.input, output); 129 } 130 // process single files 131 index = 0; 132 while (index < inputFileNames.size()) 133 { 134 String fileName = (String)inputFileNames.elementAt(index++); 135 File file = new File(fileName); 136 if (!file.isFile()) 137 { 138 if (collectErrors) 139 { 140 errorMessages.addElement("Cannot process \"" + fileName + "\" (not a file)."); 141 } 142 } 143 String inDir = file.getParent(); 144 String outDir = outputDirectory; 145 if (outDir == null) 146 { 147 outDir = inDir; 148 } 149 processFile(inDir, file.getName(), outDir); 150 } 151 } 152 153 private void processDirectoryTree(String fromDir, String toDir) 154 { 155 File fromDirFile = new File(fromDir); 156 String[] entries = fromDirFile.list(); 157 for (int i = 0; i < entries.length; i++) 158 { 159 String name = entries[i]; 160 File entry = new File(fromDir, name); 161 if (entry.isFile()) 162 { 163 processFile(fromDir, name, toDir); 164 } 165 else 166 if (entry.isDirectory()) 167 { 168 File inSubDir = new File(fromDir, name); 169 File outSubDir = new File(toDir, name); 170 if (outSubDir.exists()) 171 { 172 if (outSubDir.isFile()) 173 { 174 if (collectErrors) 175 { 176 errorMessages.addElement("Cannot create output directory \"" + 177 outSubDir.getAbsolutePath() + "\" because a file of that name already exists."); 178 } 179 continue; 180 } 181 } 182 else 183 { 184 if (!outSubDir.mkdir()) 185 { 186 if (collectErrors) 187 { 188 errorMessages.addElement("Could not create output directory \"" + 189 outSubDir.getAbsolutePath() + "\"."); 190 } 191 continue; 192 } 193 } 194 processDirectoryTree(inSubDir.getAbsolutePath(), outSubDir.getAbsolutePath()); 195 } 196 } 197 } 198 199 /** 200 * Method to be called on each file given to this operation. 201 * Non-abstract heirs of this class must implement this method to add functionality. 202 * @param inputDirectory name of directory where the file to be processed resides 203 * @param inputFileName name of file to be processed 204 * @param outputDirectory output directory for that file, need not necessarily be used 205 */ 206 public abstract void processFile(String inputDirectory, String inputFileName, String outputDirectory); 207 208 /** 209 * Specifies whether error messages are supposed to be collected 210 * during the execution of {@link #process}. 211 * @param collectErrorMessages if true, error messages will be collected, otherwise not 212 * @see #getErrorMessages 213 */ 214 public void setCollectErrorMessages(boolean collectErrorMessages) 215 { 216 collectErrors = collectErrorMessages; 217 } 218 219 /** 220 * Specifies the output directory for all single files. 221 * Note that you can specify different output directories when dealing 222 * with directory trees. 223 * @param outputDirectoryName name of output directory 224 */ 225 public void setOutputDirectory(String outputDirectoryName) 226 { 227 outputDirectory = outputDirectoryName; 228 } 229 230 /** 231 * Specify whether existing files are to be overwritten. 232 * @param newValue if true, files are overwritten, otherwise not 233 * @see #getOverwrite 234 */ 235 public void setOverwrite(boolean newValue) 236 { 237 overwrite = newValue; 238 } 239 }