View Javadoc

    1   /*************1**************************************************************************
    2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.annotation;
    9
    10
    11  import java.io.BufferedReader;
    12  import java.io.File;
    13  import java.io.FileReader;
    14  import java.io.IOException;
    15  import java.util.ArrayList;
    16  import java.util.List;
    17  import java.util.Iterator;
    18
    19  import org.apache.tools.ant.BuildException;
    20  import org.apache.tools.ant.DirectoryScanner;
    21  import org.apache.tools.ant.Project;
    22  import org.apache.tools.ant.Task;
    23  import org.apache.tools.ant.taskdefs.MatchingTask;
    24  import org.apache.tools.ant.taskdefs.Copy;
    25  import org.apache.tools.ant.types.FileSet;
    26  import org.apache.tools.ant.types.Path;
    27  import org.apache.tools.ant.types.Reference;
    28
    29  /***
    30   * AnnotationC Ant task.
    31   * <p/>
    32   * Use the following parameters to configure the task:
    33   * <ul>
    34   * <li>verbose: [optional] flag marking the task verbosity [true / false]</li>
    35   * <li>properties: [optional] path to a properties file when user-defined annoations are to be used</li>
    36   * <li>destdir: [optional unless input classes are in more than one path] directory where to put annnotated class files</li>
    37   * <li>copytodest: [optional] filename pattern to copy extra resources like dtd, xml, or properties files that were found
    38   * in the input classes path(s). By defaults, only ".class" files will be handled. It is ignored if "destdir" is not set.</li>
    39   * </ul>
    40   * <p/>
    41   * Use the following parameters to configure the classpath to point to the classes to be weaved. Those can be specified
    42   * with nested elements as well / instead:
    43   * <ul>
    44   * <li>properties path=..: extra path to a properties file when user-defined annoations are to be used</li>
    45   * <li>classpath: classpath of classes to annotated, as well as classpath to discover user-defined annotations if any</li>
    46   * <li>classpathref: classpath reference of classes to annotated, as well as classpath to discover user-defined annotations if any</li>
    47   * <li>srcdir: directory where to find annotated java source files</li>
    48   * <li>sourcepath: path where to find annotated java source files</li>
    49   * <li>sourcepathref: path reference where to find annotated java source files</li>
    50   * </ul>
    51   * <p/>
    52   * Nested elements are similar to the "javac" task when you configure a classpath and a sourcepath:
    53   * <ul>
    54   * <li>classpath: Path-like structure of classes to annotated, as well as classpath to discover user-defined annotations if any</li>
    55   * <li>src: single path entry of annotated java source files</li>
    56   * <li>sourcepath: Path-like structure of annotated java source files</li>
    57   * <li>fileset: fileset to contain annotated java source files</li>
    58   * </ul>
    59   * <p/>
    60   *
    61   * @author <a href='mailto:the_mindstorm@evolva.ro'>the_mindstorm(at)evolva(dot)ro</a>
    62   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    63   */
    64  public class AnnotationCTask extends Task {
    65
    66      private final static String CLASS_PATTERN = "**/*.class";
    67
    68
    69      private boolean m_verbose;
    70      private String m_includePattern;
    71      private Path m_classpath;
    72      private Path m_src;
    73      private File m_properties;
    74      private Path m_propertiesNested;
    75      private File m_destdir;
    76      private List m_filesets = new ArrayList();
    77
    78      /***
    79       * <task properties=..>
    80       *
    81       * @param annotationFile
    82       */
    83      public void setProperties(File annotationFile) {
    84          m_properties = annotationFile;
    85      }
    86
    87      /***
    88       * <task verbose=..>
    89       *
    90       * @param isVerbose
    91       */
    92      public void setVerbose(boolean isVerbose) {
    93          m_verbose = isVerbose;
    94      }
    95
    96      /***
    97       * <task copytodest="** slash *">
    98       *
    99       * @param pattern
    100      */
    101     public void setCopytodest(String pattern) {
    102         m_includePattern = pattern;
    103     }
    104
    105     /***
    106      * <task destdir=..>
    107      *
    108      * @param destdir
    109      */
    110     public void setDestdir(File destdir) {
    111         m_destdir = destdir;
    112     }
    113
    114     //-- <properties .., <src .., <sourcepath.. and srcdir=.. sourcepathref=..
    115
    116     public Path createProperties() {
    117         if (m_propertiesNested == null) {
    118             m_propertiesNested = new Path(getProject());
    119         }
    120         return m_propertiesNested.createPath();
    121     }
    122
    123     public Path createSrc() {
    124         if (m_src == null) {
    125             m_src = new Path(getProject());
    126         }
    127         return m_src.createPath();
    128     }
    129
    130     public void setSrcdir(Path srcDir) {
    131         if (m_src == null) {
    132             m_src = srcDir;
    133         } else {
    134             m_src.append(srcDir);
    135         }
    136     }
    137
    138     public void setSourcepath(Path sourcepath) {
    139         if (m_src == null) {
    140             m_src = sourcepath;
    141         } else {
    142             m_src.append(sourcepath);
    143         }
    144     }
    145
    146     public Path createSourcepath() {
    147         if (m_src == null) {
    148             m_src = new Path(getProject());
    149         }
    150         return m_src.createPath();
    151     }
    152
    153     public void setSourcepathRef(Reference r) {
    154         createSourcepath().setRefid(r);
    155     }
    156
    157
    158     //--- classpath
    159
    160     public void setClasspath(Path classpath) {
    161         if (m_classpath == null) {
    162             m_classpath = classpath;
    163         } else {
    164             m_classpath.append(classpath);
    165         }
    166     }
    167
    168     public Path createClasspath() {
    169         if (m_classpath == null) {
    170             m_classpath = new Path(getProject());
    171         }
    172         return m_classpath.createPath();
    173     }
    174
    175     public void setClasspathRef(Reference r) {
    176         createClasspath().setRefid(r);
    177     }
    178
    179     //---- fileset for source files
    180
    181     public void addFileset(FileSet fileset) {
    182         m_filesets.add(fileset);
    183     }
    184
    185     //-- Ant task
    186
    187     public void execute() throws BuildException {
    188         try {
    189             if (m_classpath == null) {
    190                 throw new BuildException("No classes specified [<classpath, classpath=.. classpathref=..]");
    191             }
    192             if (m_destdir == null && m_classpath.list().length > 1) {
    193                 throw new BuildException(
    194                         "When using more than one classpath directory, it is mandatory to specify [destdir=..]"
    195                 );
    196             }
    197             if (m_filesets.size() == 0 && (m_src == null || m_src.size() == 0)) {
    198                 throw new BuildException("No source specified [<include, <sourcepath, srcdir=..]");
    199             }
    200             if (m_properties != null && !m_properties.exists() && !m_properties.isFile()) {
    201                 throw new BuildException("properties file specified but not a valid file [" + m_properties + "]");
    202             }
    203             List allProperties = new ArrayList();
    204             if (m_properties != null) {
    205                 allProperties.add(m_properties.getAbsolutePath());
    206             }
    207             if (m_propertiesNested != null) {
    208                 allProperties.addAll(getDirectories(m_propertiesNested));
    209             }
    210
    211             // compute source directory list
    212             List srcDirs = getDirectories(m_src);
    213             List srcFiles = getFilesetFiles(m_filesets);
    214             List classpathDirs = getDirectories(m_classpath);
    215
    216             if (m_verbose) {
    217                 System.out.println("Source dir   : " + dump(srcDirs));
    218                 System.out.println("Source files : " + dump(srcFiles));
    219                 System.out.println("Classpath    : " + dump(classpathDirs));
    220                 System.out.println("Destdir      : " + m_destdir);
    221                 System.out.println("Properties   : " + dump(allProperties));
    222                 System.out.println("Copytodest   : " + m_includePattern);
    223             }
    224
    225             AnnotationC.compile(
    226                     m_verbose,
    227                     (String[]) srcDirs.toArray(new String[]{}),
    228                     (String[]) srcFiles.toArray(new String[]{}),
    229                     (String[]) classpathDirs.toArray(new String[]{}),
    230                     m_destdir == null ? null : m_destdir.getAbsolutePath(),
    231                     (String[]) allProperties.toArray(new String[]{})
    232                     //,getClass().getClassLoader()
    233             );
    234
    235             if (m_destdir != null) {
    236                 if (m_verbose) {
    237                     System.out.println("Copying residual files to dest dir...");
    238                 }
    239                 copySourcesToDest();
    240             }
    241
    242         } catch (Exception e) {
    243             e.printStackTrace();
    244             throw new BuildException(e);
    245         }
    246     }
    247
    248     private List getFilesetFiles(List filesets) throws BuildException {
    249         List files = new ArrayList();
    250         for (Iterator iterator = filesets.iterator(); iterator.hasNext();) {
    251             FileSet fileset = (FileSet) iterator.next();
    252             DirectoryScanner ds = fileset.getDirectoryScanner(getProject());
    253             for (int i = 0; i < ds.getIncludedFiles().length; i++) {
    254                 String file = ds.getIncludedFiles()[i];
    255                 files.add(ds.getBasedir() + File.separator + file);
    256             }
    257         }
    258         return files;
    259     }
    260
    261     private List getDirectories(Path path) throws BuildException {
    262         List dirs = new ArrayList();
    263         if (path == null) {
    264             return dirs;
    265         }
    266         for (int i = 0; i < path.list().length; i++) {
    267             File dir = getProject().resolveFile(path.list()[i]);
    268             if (!dir.exists()) {
    269                 throw new BuildException(" \"" + dir.getPath() + "\" does not exist!", getLocation());
    270             }
    271             dirs.add(dir.getAbsolutePath());
    272         }
    273         return dirs;
    274     }
    275
    276     private String dump(List strings) {
    277         StringBuffer sb = new StringBuffer();
    278         for (Iterator iterator = strings.iterator(); iterator.hasNext();) {
    279             Object o = (Object) iterator.next();
    280             sb.append(o.toString()).append(File.pathSeparator);
    281         }
    282         return sb.toString();
    283     }
    284
    285     private void copySourcesToDest() throws BuildException {
    286         Copy copy = new Copy();
    287
    288         copy.setProject(getProject());
    289         copy.setTodir(m_destdir);
    290         copy.setOverwrite(false);
    291         copy.setTaskName("copy");
    292         copy.setVerbose(m_verbose);
    293
    294         List sourceDir = getDirectories(m_src);
    295         for (Iterator iterator = sourceDir.iterator(); iterator.hasNext();) {
    296             String dir = (String) iterator.next();
    297             FileSet anonFs = new FileSet();
    298             anonFs.setIncludes(CLASS_PATTERN);
    299             if (m_includePattern != null) {
    300                 anonFs.setIncludes(m_includePattern);
    301             }
    302             anonFs.setDir(new File(dir));
    303             copy.addFileset(anonFs);
    304         }
    305         copy.execute();
    306     }
    307
    308 }