EMMA Coverage Report (generated Fri Jun 19 09:16:10 CEST 2009)
[all classes][org.ktc.rbutils.rb]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractRbTask.java]

nameclass, %method, %block, %line, %
AbstractRbTask.java100% (3/3)100% (26/26)92%  (515/559)97%  (121/125)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractRbTask$Log100% (1/1)100% (8/8)77%  (130/168)91%  (32/35)
setType (AbstractRbTask$LoggerType): void 100% (1/1)45%  (10/22)80%  (4/5)
createXmlLogger (Task): Logger 100% (1/1)71%  (32/45)88%  (7/8)
createDefaultLogger (Task): Logger 100% (1/1)81%  (55/68)92%  (11/12)
AbstractRbTask$Log (): void 100% (1/1)100% (3/3)100% (2/2)
createLogger (Task): Logger 100% (1/1)100% (20/20)100% (4/4)
getLoggerType (): AbstractRbTask$LoggerType 100% (1/1)100% (3/3)100% (1/1)
getOutputFile (): File 100% (1/1)100% (3/3)100% (1/1)
setOutputFile (File): void 100% (1/1)100% (4/4)100% (2/2)
     
class AbstractRbTask100% (1/1)100% (14/14)98%  (361/367)99%  (83/84)
handleErrors (int): void 100% (1/1)90%  (53/59)90%  (9/10)
AbstractRbTask (): void 100% (1/1)100% (16/16)100% (5/5)
addFileset (FileSet): void 100% (1/1)100% (6/6)100% (2/2)
addLogger (AbstractRbTask$Log): void 100% (1/1)100% (6/6)100% (2/2)
doJob (): void 100% (1/1)100% (71/71)100% (17/17)
getFiles (): List 100% (1/1)100% (80/80)100% (14/14)
getLoggers (): List 100% (1/1)100% (97/97)100% (20/20)
logTaskStarts (): void 100% (1/1)100% (7/7)100% (2/2)
setDisplayLocale (String): void 100% (1/1)100% (5/5)100% (2/2)
setExtension (String): void 100% (1/1)100% (4/4)100% (2/2)
setFailOnErrors (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setFailureProperty (String): void 100% (1/1)100% (4/4)100% (2/2)
setMaxErrors (int): void 100% (1/1)100% (4/4)100% (2/2)
setRoot (File): void 100% (1/1)100% (4/4)100% (2/2)
     
class AbstractRbTask$LoggerType100% (1/1)100% (4/4)100% (24/24)100% (6/6)
<static initializer> 100% (1/1)100% (15/15)100% (2/2)
AbstractRbTask$LoggerType (): void 100% (1/1)100% (3/3)100% (2/2)
getValues (): String [] 100% (1/1)100% (2/2)100% (1/1)
isLoggerTypeValue (String): boolean 100% (1/1)100% (4/4)100% (1/1)

1/*
2 * Copyright  2005-2006 The RbUtils Project
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 *  you may not use this file except in compliance with the License.
6 *  You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *  Unless required by applicable law or agreed to in writing, software
11 *  distributed under the License is distributed on an "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 *
16 */
17 
18// $Id: AbstractRbTask.java,v 1.5 2007/07/08 01:15:31 moishi Exp $
19 
20package org.ktc.rbutils.rb;
21 
22import java.io.BufferedOutputStream;
23import java.io.File;
24import java.io.FileNotFoundException;
25import java.io.FileOutputStream;
26import java.io.IOException;
27import java.io.OutputStream;
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.Iterator;
31import java.util.List;
32import java.util.Locale;
33 
34import org.apache.tools.ant.BuildException;
35import org.apache.tools.ant.DirectoryScanner;
36import org.apache.tools.ant.Project;
37import org.apache.tools.ant.Task;
38import org.apache.tools.ant.taskdefs.LogOutputStream;
39import org.apache.tools.ant.types.EnumeratedAttribute;
40import org.apache.tools.ant.types.FileSet;
41import org.ktc.rbutils.api.audit.Logger;
42import org.ktc.rbutils.api.audit.MainProcessor;
43import org.ktc.rbutils.api.i18n.LocaleUtils;
44import org.ktc.rbutils.rb.check.DefaultLogger;
45import org.ktc.rbutils.rb.check.RbCheckerTask;
46import org.ktc.rbutils.rb.check.XmlLogger;
47import org.ktc.rbutils.rb.generation.RbGeneratorTask;
48 
49/**
50 * Abstract class for RbUtils ant tasks. Provides common options for check and generation. This
51 * includes logging system.
52 * @since RbUtils 0.9.1
53 * @version $Revision: 1.5 $
54 * @author redfish
55 */
56public abstract class AbstractRbTask extends Task {
57    /** Enum value for an xml logger. */
58    private static final String LOGGERTYPE_XML = "xml";
59    /** Enum value for an plain logger. */
60    private static final String LOGGERTYPE_PLAIN = "plain";
61 
62    /** Locale for results display. */
63    protected Locale displayLocale;
64    /**
65     * The maximum number of errors that are tolerated before breaking the build or setting the
66     * failure property.
67     */
68    protected int maxErrors;
69    /** Specifies whether the build will break if errors occur. */
70    protected boolean failOnErrors = true;
71    /** The name of the property to set if errors occur. */
72    protected String failureProperty;
73 
74    /** Contains the loggers to log to. */
75    private final List loggersList = new ArrayList();
76 
77    /** Contains the filesets to process. */
78    protected final List fileSets = new ArrayList();
79    /** Root directory used to find properties file. */
80    protected File root;
81    /** Extension of properties file. */
82    protected String extension;
83 
84    /**
85     * Processor used by the task to do the job.
86     */
87    protected MainProcessor processor;
88 
89    /**
90     * The type of the Task. This must be initialized by subclasses.
91     */
92    protected TaskType taskType;
93 
94 
95    /**
96     * Instanciates a new AbstractRbTask.
97     */
98    public AbstractRbTask() {
99        super();
100    }
101 
102    /**
103     * Launches the check.
104     */
105    protected void doJob() {
106        // TODO Code - validate args in order to get explicit exception (?)
107//        MainChecker processor = null;
108        try {
109            specificTaskinitilization();
110            processor.addLoggers(getLoggers());
111            processor.setMessagesLocale(displayLocale);
112 
113            // Set the list of files to be inspected
114            // If the user specify files with filesets, the checker does not need to look for files
115            // in the root directory. So set the filesAlreadyAdded attribute.
116            // Otherwise, the checker will look for files by itself.
117            // TODO: we should tests if the filesets is empty in the getFilesMethod when the
118            // addFiles method will be refactored
119            if (!fileSets.isEmpty()) {
120                processor.addFiles(getFiles());
121                processor.setFilesAlreadyAdded(true);
122            }
123 
124            // Launch the check
125            logTaskStarts();
126            final int numErrors = processor.process();
127 
128            // RBUTILS-028: Display the number of processed files
129            log("Processed Files: " + processor.getProcessedFilesCount(), Project.MSG_INFO);
130 
131            handleErrors(numErrors);
132        }
133        // TODO Code - Exception catching
134        catch (final BuildException buildexception) {
135            throw buildexception;
136        }
137        catch (final Exception exception) {
138            throw new BuildException(exception, getLocation());
139        }
140        finally {
141            processor = null;
142        }
143    }
144 
145    /**
146     * Adds specific Initialization to the task. This let subclasses instanciate the processor and
147     * set processor properties .
148     * @throws FileNotFoundException if a file is not found on processor instanciation.
149     */
150    protected abstract void specificTaskinitilization() throws FileNotFoundException;
151 
152    /**
153     * Display, via the ant loggers, that the task starts.
154     */
155    protected void logTaskStarts() {
156        log(CommonProps.getRunningTask(taskType), Project.MSG_INFO);
157    }
158 
159    /**
160     * Adds an Ant Logger.
161     * @param logger the ant logger to be added for logging.
162     */
163    public void addLogger(final Log logger) {
164        loggersList.add(logger);
165    }
166 
167    /**
168     * Returns the list of listeners set in this task.
169     * <p>
170     * If no loggers are registered, creates a new DefaultLogger using the ant logging system and
171     * adds it to the returned list.
172     * @return the list of listeners.
173     * @throws IOException if an error occurs.
174     */
175    protected List getLoggers() throws IOException {
176        final List internalLoggerslist = new ArrayList();
177 
178        // If no logger is set, create a DefaultLogger which display messges using ant logging
179        // system and adds it to the returned list
180        if (loggersList.size() == 0) {
181            // TODO Code - to be removed because this is already done in the AbstractMainProcessor
182            log("no logger registered", Project.MSG_VERBOSE);
183 
184            final Log antlogger = new Log();
185            final LoggerType loggertype = new LoggerType();
186            loggertype.setValue(LOGGERTYPE_PLAIN);
187            antlogger.setType(loggertype);
188 
189            log("adding a default plain text listener", Project.MSG_VERBOSE);
190            internalLoggerslist.add(antlogger.createLogger(this));
191        }
192        // Otherwise, create listeners for all registered loggers
193        else {
194            log("found registered loggers", Project.MSG_VERBOSE);
195 
196            for (final Iterator iterLogger = loggersList.iterator(); iterLogger.hasNext();) {
197                final Log antlogger = (Log) iterLogger.next();
198                log("--found logger : type " + antlogger.getLoggerType() + " with file "
199                    + antlogger.getOutputFile(), Project.MSG_VERBOSE);
200                final Logger logger = antlogger.createLogger(this);
201                log("--adding listener " + logger.getClass().getName(), Project.MSG_VERBOSE);
202                internalLoggerslist.add(logger);
203            }
204            log("end of found registered loggers", Project.MSG_VERBOSE);
205        }
206        return internalLoggerslist;
207    }
208 
209    /**
210     * Scans all optional filesets to find files to check and returns the list of found files.
211     * <p>
212     * The list contains <code>File</code> objects.
213     * @return the list of files found with the filesets of the task.
214     */
215    protected List getFiles() {
216        final List filesList = new ArrayList();
217 
218        // Scan all filesets of the task
219        for (final Iterator itFSets = fileSets.iterator(); itFSets.hasNext();) {
220            // Get all filenames included in this fileset
221            final FileSet fs = (FileSet) itFSets.next();
222            final DirectoryScanner ds = fs.getDirectoryScanner(getProject());
223            ds.scan();
224            final File basedir = ds.getBasedir();
225            final String[] names = ds.getIncludedFiles();
226 
227            // Add all found files to the files list
228            log("Adding " + names.length + " files from directory " + basedir, Project.MSG_VERBOSE);
229            for (int i = 0; i < names.length; i++) {
230                final String filename = names[i];
231                filesList.add(new File(basedir, filename));
232                log("  " + filename + " added", Project.MSG_VERBOSE);
233            }
234        }
235 
236        return filesList;
237    }
238    // TODO Code - classloader (voir ClasspathUtils.getClassLoaderForPath()
239    // /**
240    // * Creates and configures an AntClassLoader instance from the
241    // * nested classpath element.
242    // *
243    // * @since Ant 1.6
244    // */
245    // private void createClassLoader() {
246    // Path userClasspath = getCommandline().getClasspath();
247    // if (userClasspath != null) {
248    // if (reloading || classLoader == null) {
249    // Path classpath = (Path) userClasspath.clone();
250    // if (includeAntRuntime) {
251    // log("Implicitly adding " + antRuntimeClasses
252    // + " to CLASSPATH", Project.MSG_VERBOSE);
253    // classpath.append(antRuntimeClasses);
254    // }
255    // classLoader = getProject().createClassLoader(classpath);
256    // if (getClass().getClassLoader() != null
257    // && getClass().getClassLoader() != Project.class.getClassLoader()) {
258    // classLoader.setParent(getClass().getClassLoader());
259    // }
260    // classLoader.setParentFirst(false);
261    // classLoader.addJavaLibraries();
262    // log("Using CLASSPATH " + classLoader.getClasspath(),
263    // Project.MSG_VERBOSE);
264    // // make sure the test will be accepted as a TestCase
265    // classLoader.addSystemPackageRoot("junit");
266    // // will cause trouble in JDK 1.1 if omitted
267    // classLoader.addSystemPackageRoot("org.apache.tools.ant");
268    //            }
269    //        }
270    // }
271 
272    /**
273     * Handles errors. This should be used after the underlying task execution.
274     * <p>
275     * If this number is greater than maxErrors, sets the failureProperty if asked and throws an
276     * BuildException if failOnErrors is sets to <code>true</code>.
277     * @param numErrors number of errors to be check against maxErrors.
278     */
279    protected void handleErrors(final int numErrors) {
280        final boolean ok = numErrors <= maxErrors;
281 
282        // Display the number of errors
283        final int verbosityLevel;
284        if (!ok) {
285            verbosityLevel = Project.MSG_ERR;
286        }
287        else {
288            verbosityLevel = Project.MSG_INFO;
289        }
290        log("Errors: " + numErrors, verbosityLevel);
291 
292        // Handle the return status
293        if (!ok && failureProperty != null) {
294            getProject().setProperty(failureProperty, "true");
295        }
296 
297        if (!ok && failOnErrors) {
298            throw new BuildException("Got " + numErrors + " errors", getLocation());
299        }
300    }
301 
302    // ////////////////////////////////////////////////////////////////////////////////////////////
303    // Setters for ANT specific attributes
304    // ////////////////////////////////////////////////////////////////////////////////////////////
305 
306    /**
307     * Sets the locale to be used to generate message used on logging.
308     * TODO Javadoc - default?
309     * <p>
310     * The separator in the <code>String</code> argument must be
311     * {@link org.ktc.rbutils.api.i18n.LocaleUtils#LOCALE_SEPARATOR}.
312     * @param displayLocale The locale to set.
313     */
314    public void setDisplayLocale(final String displayLocale) {
315        this.displayLocale = LocaleUtils.toLocale(displayLocale);
316    }
317 
318    /**
319     * Tells this task whether to fail if errors occur during the check. Default to
320     * <code>true</code>.
321     * @param failOnErrors <code>true</code> to fail on errors; <code>false</code> otherwise.
322     */
323    public void setFailOnErrors(final boolean failOnErrors) {
324        this.failOnErrors = failOnErrors;
325    }
326 
327    /**
328     * Tells this task to set the named property to "true" when there is a violation.
329     * @param failureProperty the name of the property to set in the event of an failure.
330     */
331    public void setFailureProperty(final String failureProperty) {
332        this.failureProperty = failureProperty;
333    }
334 
335    /**
336     * Sets the maximum number of errors allowed. Default to 0.
337     * @param maxErrors the maximum number of errors allowed.
338     */
339    public void setMaxErrors(final int maxErrors) {
340        this.maxErrors = maxErrors;
341    }
342 
343    // *****************************************
344    // FILESET
345    //*****************************************
346    /**
347     * Adds a set of files (nested fileset attribute).
348     * @param fileSet the file set to add.
349     */
350    public void addFileset(final FileSet fileSet) {
351        fileSets.add(fileSet);
352    }
353 
354    /**
355     * Sets the directory where the properties files will be searched for the check.
356     * @param root the root directory to set.
357     */
358    public void setRoot(final File root) {
359        this.root = root;
360    }
361 
362    /**
363     * Sets the extension of the properties file used for the check. Default is
364     * {@link AbstractMainProcessor#DEFAULT_PROPERTIES_EXTENSION}.
365     * @param extension the extension to set.
366     */
367    public void setExtension(final String extension) {
368        this.extension = extension;
369    }
370 
371    // ////////////////////////////////////////////////////////////////////////////////////////////
372    // Inner classes
373    // ////////////////////////////////////////////////////////////////////////////////////////////
374    /**
375     * Logger for the rbUtils ant tasks.
376     * <p>
377     * The logger is created by the {@link #createLogger(Task)} method. The {@link RbCheckerTask}
378     * and {@link RbGeneratorTask} are currently supported.
379     * @since RbUtils 0.9.1
380     * @version $Revision: 1.5 $
381     * @author redfish
382     */
383    public static class Log {
384        /** The logger type. */
385        private LoggerType loggerType;
386        /** The file to output to. */
387        private File outputFile;
388        /** Header message for unsupported task exception. */
389        private static final String UNSUPPORTEDTASK_MSG = "Unsupported Task ";
390 
391        /**
392         * Instanciates a new Logger.
393         */
394        public Log() {
395            super();
396        }
397 
398        /**
399         * Set the type of the logger.
400         * @param loggertype the type of the logger.
401         */
402        public void setType(final LoggerType loggertype) {
403            // TODO Code - is this necessary. Create a test case for this
404            final String val = loggertype.getValue();
405//            if (!LOGGERTYPE_XML.equals(val) && !LOGGERTYPE_PLAIN.equals(val)) {
406            if (!LoggerType.isLoggerTypeValue(val)) {
407                throw new BuildException("Invalid formatter type: " + val);
408            }
409            loggerType = loggertype;
410        }
411 
412        /**
413         * Set the file to output to.
414         * @param theOutputFile the file to output to.
415         */
416        public void setOutputFile(final File theOutputFile) {
417            outputFile = theOutputFile;
418        }
419 
420        /**
421         * Creates a logger according to a task.
422         * TODO Javadoc - to be improved.
423         * @param task the task to be associated to the logger.
424         * @return a logger according to the task.
425         * @throws IOException if an error occurs.
426         */
427        public Logger createLogger(final Task task) throws IOException {
428            final Logger logger;
429            if ((loggerType != null) && LOGGERTYPE_XML.equals(loggerType.getValue())) {
430                logger = createXmlLogger(task);
431            }
432            else {
433                logger = createDefaultLogger(task);
434            }
435            return logger;
436        }
437 
438        /**
439         * Creates a default logger according to a task.
440         * @return a DefaultLogger instance.
441         * @param task the task associated to the logger.
442         * @throws IOException if an error occurs on logger creation.
443         * @throws BuildException if the task is not supported.
444         */
445        private Logger createDefaultLogger(final Task task) throws IOException {
446            // Sets the used output stream by this logger
447            final OutputStream msgStream;
448            final OutputStream errorStream;
449            if (outputFile == null) {
450                msgStream = new LogOutputStream(task, Project.MSG_DEBUG);
451                errorStream = new LogOutputStream(task, Project.MSG_ERR);
452            }
453            else {
454                msgStream = new BufferedOutputStream(new FileOutputStream(outputFile));
455                errorStream = msgStream;
456            }
457 
458            // Instanciates the default logger
459            Logger logger = null;
460            if (task instanceof RbCheckerTask) {
461                logger = new DefaultLogger(msgStream, true, errorStream, true);
462            }
463            else if (task instanceof RbGeneratorTask) {
464                logger = new org.ktc.rbutils.rb.generation.DefaultLogger(msgStream, true,
465                                                                           errorStream, true);
466            }
467            else {
468                throw new BuildException(UNSUPPORTEDTASK_MSG + task.getTaskName());
469            }
470            return logger;
471 
472        }
473 
474        /**
475         * Creates a xml logger according to the task.
476         * @return an XmlLogger instance.
477         * @param task the task associated to the logger.
478         * @throws IOException if an error occurs on logger creation.
479         * @throws BuildException if the outputFile is not set or if the task is not supported.
480         */
481        private Logger createXmlLogger(final Task task) throws IOException {
482            final Logger logger;
483            if (outputFile == null) {
484                throw new BuildException("outputFile must not be null", task.getLocation());
485            }
486 
487            if (task instanceof RbCheckerTask) {
488                logger = new XmlLogger(outputFile);
489            }
490            else if (task instanceof RbGeneratorTask) {
491                logger = new org.ktc.rbutils.rb.generation.XmlLogger(outputFile);
492            }
493            else {
494                throw new BuildException(UNSUPPORTEDTASK_MSG + task.getTaskName());
495            }
496            return logger;
497        }
498 
499        /**
500         * Returns the type of this ant logger.
501         * @return the type of the ant logger.
502         */
503        public LoggerType getLoggerType() {
504            return this.loggerType;
505        }
506 
507        /**
508         * Returns the output file of this ant logger.
509         * @return the output file of this ant logger.
510         */
511        public File getOutputFile() {
512            return this.outputFile;
513        }
514    }
515 
516    /**
517     * Enumerated attribute for ant logger type.
518     * @since RbUtils 0.9.1
519     * @version $Revision: 1.5 $
520     * @author redfish
521     */
522    public static class LoggerType extends EnumeratedAttribute {
523        /** Enum types for the LoggerType as String[].*/
524        private static final String[] LOGGER_TYPES = {LOGGERTYPE_XML, LOGGERTYPE_PLAIN};
525        /** Enum types for the LoggerType as List.*/
526        private static final List LOGGER_TYPES_LIST = Arrays.asList(LOGGER_TYPES);
527 
528        /**
529         * Instanciates a new LoggerType.
530         */
531        public LoggerType() {
532            super();
533        }
534 
535        /**
536         * {@inheritDoc}
537         */
538        public String[] getValues() {
539            // return new String[] {LOGGERTYPE_XML, LOGGERTYPE_PLAIN};
540            return LOGGER_TYPES;
541        }
542 
543        /**
544         * Indicates if the argument is a logger type value.
545         * @param typeValue type value to be checked.
546         * @return <code>true</code> if the argument is an ant logger type value; otherwise returns
547         *         <code>false</code>.
548         */
549        public static boolean isLoggerTypeValue(final String typeValue) {
550            return LOGGER_TYPES_LIST.contains(typeValue);
551        }
552    }
553}

[all classes][org.ktc.rbutils.rb]
EMMA 2.0.5312 (C) Vladimir Roubtsov