View Javadoc

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 }