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 }