1 /* 2 Copyright (C) 2000 - 2007 Grid Systems, S.A. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2, as 6 published by the Free Software Foundation. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 package com.gridsystems; 18 19 //import gnu.regexp.RE; 20 //import gnu.regexp.REException; 21 22 import java.io.File; 23 import java.io.FileFilter; 24 import java.io.IOException; 25 import java.io.Writer; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 30 /** 31 * GridXMLDirectorySerializer. 32 */ 33 public class GridXMLDirectorySerializer { 34 35 /** 36 * Class logger. 37 */ 38 private static Log log = LogFactory.getLog(GridXMLDirectorySerializer.class); 39 40 /** 41 * Writer en el cual escribir el XML generado. 42 */ 43 private Writer out = null; 44 45 /** 46 * Pre-built array of indentation strings. 47 */ 48 private static final String[] INDENTS = { 49 " ", " ", " ", " ", " ", " ", 50 " ", " ", " ", 51 " ", " ", " " 52 }; 53 54 /** 55 * Current indentation level. 56 */ 57 private int level; 58 59 /** 60 * Optional filter for file listings. 61 */ 62 private FileFilter filter; 63 64 /** 65 * Crea un nuevo GridXMLSerializer para escribir sobre un Writer. 66 * 67 * @param out writer de salida del XML generado 68 */ 69 public GridXMLDirectorySerializer(Writer out) { 70 this(out, new NoFilter()); 71 } 72 73 /** 74 * Crea un nuevo GridXMLSerializer para escribir sobre un Writer. 75 * 76 * @param out Output writer 77 * @param filter Used to filter included files 78 */ 79 public GridXMLDirectorySerializer(Writer out, FileFilter filter) { 80 this.out = out; 81 this.level = 0; 82 this.filter = filter; 83 log.debug("New GridXMLDirectorySerializer created"); 84 } 85 86 /** 87 * Comienza la serializacion, generando las cabeceras XML correspondientes. 88 * 89 * @throws IOException si hay error de escritura en el writer del serializador 90 */ 91 private void begin() throws IOException { 92 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 93 out.write("<main>\n"); 94 95 log.debug("Serialization started"); 96 } 97 98 /** 99 * Termina la serializacion, generando el cierre de las cabeceras XML correspondientes. 100 * Despues de esta operacion se recomienda hacer flush() y close() del writer 101 * 102 * @throws java.io.IOException si hay error de escritura en el writer del serializador 103 */ 104 private void end() throws IOException { 105 out.write("</main>\n"); 106 out.flush(); 107 108 log.debug("Serialization ended"); 109 } 110 111 /** 112 * Serializes in XML style the information of a directory. 113 * All paths must be in java style, using '/' as separator 114 * 115 * @param dir Contains the root path to serialize. It must finish with /. 116 * @param relativePath Contains the path relative to the dir path. (Basically used 117 in recurcsive method). 118 * @param excludedDirs Serialization excludes the selected dirs. 119 * @param excludedFiles Serialization excludes the selected files. 120 * @param regexpExclude Serialization excludes the selected files according to the 121 regular expresion. 122 * @param properties If true, file properties will be serialized 123 * @throws IOException If dir is not a directory 124 * @throws REException If a syntax error is found in one of the regular expressions 125 * 126 private void serializeSubDirs(String dir, String relativePath, 127 String[] excludedDirs, String[] excludedFiles, String[] regexpExclude, 128 boolean properties) throws IOException, REException { 129 130 File d = new File(dir, relativePath); 131 if (!d.isDirectory()) { 132 throw new IOException(dir + " is not a directory"); 133 } 134 135 final int n = (regexpExclude == null) ? 0 : regexpExclude.length; 136 RE[] re = new RE[n]; 137 for (int i = 0; i < n; i++) { 138 re[i] = new RE(regexpExclude[i]); 139 } 140 141 serializeSubDirs(d, relativePath, excludedDirs, excludedFiles, re, properties); 142 }*/ 143 144 /** 145 * Serializes in XML style the information of a directory. 146 * All paths must be in java style, using '/' as separator 147 * 148 * @param d Contains the root path to serialize. It must finish with /. 149 * @param relativePath Contains the path relative to the dir path. (Basically used 150 in recurcsive method). 151 * @param excludedDirs Serialization excludes the selected dirs. 152 * @param excludedFiles Serialization excludes the selected files. 153 * @param re Serialization excludes the selected files according to the 154 regular expresion. 155 * @param props If true, file properties will be serialized 156 * 157 * @throws IOException if error 158 * 159 private void serializeSubDirs(File d, String relativePath, 160 String[] excludedDirs, String[] excludedFiles, RE[] re, 161 boolean props) throws IOException { 162 163 final File[] files = d.listFiles(filter); 164 final int count = (files == null) ? 0 : files.length; 165 166 final String indent = INDENTS[level]; 167 level++; 168 169 // Preprocess array sizes to avoid null comparisons 170 final int dCount = (excludedDirs == null) ? 0 : excludedDirs.length; 171 final int fCount = (excludedFiles == null) ? 0 : excludedFiles.length; 172 173 loop: 174 for (int i = 0; i < count; i++) { 175 File f = files[i]; 176 String name = f.getName(); 177 final String path = relativePath + name; 178 179 // Regular expression filtering 180 for (int j = 0; j < re.length; j++) { 181 if (re[i].isMatch(name)) { 182 continue loop; 183 } 184 } 185 186 if (f.isDirectory()) { 187 // Directory filtering 188 for (int j = 0; j < dCount; j++) { 189 if (path.equals(excludedDirs[j])) { 190 continue loop; 191 } 192 } 193 194 // Directory serialization 195 out.append(indent).append("<dir name=\"" + name + "\">\n"); 196 serializeSubDirs(d, path, excludedDirs, excludedFiles, re, props); 197 out.append(indent).append("</dir>\n"); 198 } else { 199 // File filtering 200 for (int j = 0; j < fCount; j++) { 201 if (path.equals(excludedFiles[j])) { 202 continue loop; 203 } 204 } 205 206 out.append(indent).append("<file name=\"").append(name).append('"'); 207 // File serialization 208 if (props) { 209 out.append(" size=\"").append(Long.toString(f.length())).append('"'); 210 } 211 out.append("></file>\n"); 212 } 213 } 214 215 level--; 216 }*/ 217 218 /** 219 * Serializes in XML style the information of a directory. 220 * All paths must be in java style, using '/' as separator 221 * 222 * @param d Contains the root path to serialize. It must finish with /. 223 * @param relativePath Contains the path relative to the dir path. (Basically used 224 in recurcsive method). 225 * @param props If true, file properties will be serialized 226 * @throws IOException If an error occurs writting to 'out' 227 */ 228 private void serializeSubDirs(File d, String relativePath, 229 boolean props) throws IOException { 230 231 File[] files = d.listFiles(filter); 232 int count = (files == null) ? 0 : files.length; 233 234 String indent = INDENTS[level++]; 235 236 for (int i = 0; i < count; i++) { 237 final File f = files[i]; 238 final String name = f.getName(); 239 final String path = relativePath + name; 240 241 if (f.isDirectory()) { 242 243 // Directory serialization 244 out.append(indent).append("<dir name=\"" + name + "\">\n"); 245 serializeSubDirs(f, path, props); 246 out.append(indent).append("</dir>\n"); 247 } else { 248 out.append(indent).append("<file name=\"").append(name).append('"'); 249 // File serialization 250 if (props) { 251 out.append(" size=\"").append(Long.toString(f.length())).append('"'); 252 } 253 out.append("/>\n"); 254 } 255 } 256 257 level--; 258 } 259 260 /** 261 * It serialize in XML style the information of a directory. 262 * All paths must be in java style, using '/' as separator 263 * 264 * @param dir Conteins the root path to serialize. It must finish with /. 265 * @param excludedDirs Serialization excludes the selected dirs. 266 * @param excludedFiles Serialization excludes the selected files. 267 * @param regexpExclude Serialization excludes the selected files according to 268 * the regular expresion. 269 * @throws Exception if error 270 * @deprecated serialize() methods are now preferred 271 * 272 public void serializeDirStructure(String dir, String[] excludedDirs, 273 String[] excludedFiles, String[] regexpExclude) throws Exception { 274 this.begin(); 275 serializeSubDirs(dir, "", excludedDirs, excludedFiles, regexpExclude, true); 276 this.end(); 277 }*/ 278 279 /** 280 * It serialize in XML style the information of a directory. 281 * All paths must be in java style, using '/' as separator 282 * 283 * @param dirs Contains the root path to serialize. It must finish with /. 284 * @throws Exception if error 285 * @deprecated serialize() methods are now preferred 286 */ 287 public void serializeDirStructure(String[] dirs) throws Exception { 288 serialize(true, dirs); 289 } 290 291 /** 292 * It serialize in XML style the information of a directory. 293 * All paths must be in java style, using '/' as separator 294 * 295 * @param dirs Contains the root path to serialize. It must finish with /. 296 * @param properties If true, file properties will be serialized 297 * @throws Exception if error 298 * @deprecated serialize() methods are now preferred 299 */ 300 public void serializeDirStructure(String[] dirs, boolean properties) 301 throws Exception { 302 serialize(properties, dirs); 303 } 304 305 /** 306 * Serializes in XML style the information of a directory. 307 * All paths must be in java style, using '/' as separator 308 * 309 * @param dirs Contains the root path to serialize. It must finish with /. 310 * @throws IOException if error 311 */ 312 public void serialize(String... dirs) throws IOException { 313 serialize(true, dirs); 314 } 315 316 /** 317 * Serializes in XML style the information of a directory. 318 * All paths must be in java style, using '/' as separator 319 * 320 * @param paths Contains the root paths to serialize. 321 * @param properties If true, file properties will be serialized 322 * @throws IOException if error 323 */ 324 public void serialize(boolean properties, String... paths) throws IOException { 325 final int count = (paths == null) ? 0 : paths.length; 326 File[] dirs = new File[count]; 327 for (int i = 0; i < count; i++) { 328 File d = new File(paths[i]); 329 if (d.isDirectory()) { 330 dirs[i] = d; 331 } else { 332 throw new IOException("'" + paths[i] + "' not a directory"); 333 } 334 } 335 336 this.begin(); 337 for (int i = 0; i < count; i++) { 338 serializeSubDirs(dirs[i], "", properties); 339 } 340 this.end(); 341 } 342 343 /** 344 * Serializes in XML style the information of a directory. 345 * All paths must be in java style, using '/' as separator 346 * 347 * @param dirs Contains the root path to serialize. It must finish with /. 348 * @param properties If true, file properties will be serialized 349 * @throws IOException if error 350 */ 351 public void serialize(boolean properties, File... dirs) throws IOException { 352 final int count = (dirs == null) ? 0 : dirs.length; 353 for (int i = 0; i < count; i++) { 354 if (!dirs[i].isDirectory()) { 355 throw new IOException("'" + dirs[i] + "' not a directory"); 356 } 357 } 358 359 this.begin(); 360 for (int i = 0; i < count; i++) { 361 serializeSubDirs(dirs[i], "", properties); 362 } 363 this.end(); 364 } 365 366 /** 367 * Dummy filter that accepts all files. 368 */ 369 private static class NoFilter implements FileFilter { 370 /** 371 * {@inheritDoc} 372 */ 373 public boolean accept(File pathname) { 374 return true; 375 } 376 } 377 }