View Javadoc

1   /*
2    * Jour - bytecode instrumentation library
3    *
4    * Copyright (C) 2007-2008 Vlad Skarzhevskyy
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Library General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Library General Public License for more details.
15   *
16   * You should have received a copy of the GNU Library General Public
17   * License along with this library; if not, write to the
18   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19   * Boston, MA  02111-1307, USA.
20   */
21  package net.sf.jour.maven;
22  
23  import java.io.File;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Vector;
27  
28  import net.sf.jour.PreProcessor;
29  
30  import org.apache.maven.artifact.Artifact;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  import org.apache.maven.plugin.logging.Log;
35  import org.apache.maven.project.MavenProject;
36  
37  import com.pyx4j.log4j.MavenLogAppender;
38  
39  /**
40   * The jour:instrument will apply instrumentation during build.
41   * 
42   * @author vlads
43   * 
44   * @goal instrument
45   * 
46   * @phase process-classes
47   * 
48   * @requiresDependencyResolution test
49   * 
50   * @description Instrument
51   */
52  public class InstrumentationMojo extends AbstractMojo {
53  
54  	private Log log;
55  
56  	/**
57  	 * Reads configuration options from the given file. File or resource name.
58  	 * 
59  	 * @parameter default-value="${basedir}/jour.xml"
60  	 */
61  	private String jourConfig;
62  
63  	/**
64  	 * The directory or jar containing original classes.
65  	 * 
66  	 * @parameter expression="${project.build.outputDirectory}"
67  	 * @required
68  	 */
69  	private File classesDirectory;
70  
71  	/**
72  	 * Directory containing the generated JAR.
73  	 * 
74  	 * @parameter expression="${project.build.directory}"
75  	 * @required
76  	 */
77  	protected File outputDirectory;
78  
79  	/**
80  	 * Output directory name relative to outputDirectory parameter.
81  	 * 
82  	 * @parameter expression="iclasses"
83  	 * @required
84  	 */
85  	protected String output;
86  
87  	/**
88  	 * Copy not instrumented classes to "output"
89  	 * 
90  	 * @parameter expression="false"
91  	 */
92  	private boolean copyClasses;
93  
94  	/**
95  	 * Copy resources to "output"
96  	 * 
97  	 * @parameter expression="false"
98  	 */
99  	private boolean copyResources;
100 
101 	/**
102 	 * Appends the system search path to the end of the search path. The system
103 	 * search path usually includes the platform library, extension libraries,
104 	 * and the search path specified by the <code>-classpath</code> option or
105 	 * the <code>CLASSPATH</code> environment variable.
106 	 * 
107 	 * @parameter expression="true"
108 	 */
109 	private boolean useSystemClassPath;
110 
111 	/**
112 	 * The Maven project reference where the plugin is currently being executed.
113 	 * Used for dependency resolution during compilation. The default value is
114 	 * populated from maven.
115 	 * 
116 	 * @parameter expression="${project}"
117 	 * @readonly
118 	 * @required
119 	 */
120 	protected MavenProject mavenProject;
121 
122 	public void execute() throws MojoExecutionException, MojoFailureException {
123 		log = getLog();
124 		MavenLogAppender.startPluginLog(this);
125 		try {
126 
127 			log.info("jourConfig: " + jourConfig);
128 
129 			File out = new File(outputDirectory, output);
130 
131 			List classpath = new Vector();
132 
133 			List dependancy = this.mavenProject.getTestArtifacts();
134 			for (Iterator i = dependancy.iterator(); i.hasNext();) {
135 				Artifact artifact = (Artifact) i.next();
136 				File file = getClasspathElement(artifact, mavenProject);
137 				log.debug("dependancy:" + file.toString());
138 				classpath.add(file.toString());
139 			}
140 
141 			PreProcessor pp = new PreProcessor(jourConfig, classesDirectory, out, classpath);
142 
143 			pp.setUseSystemClassPath(useSystemClassPath);
144 			pp.setCopyClasses(copyClasses);
145 			pp.setCopyResources(copyResources);
146 
147 			try {
148 				pp.process();
149 			} catch (Exception e) {
150 				log.error("PreProcessing error", e);
151 				throw new MojoExecutionException("PreProcessing error", e);
152 			}
153 
154 		} finally {
155 			MavenLogAppender.endPluginLog(this);
156 		}
157 	}
158 
159 	public static File getClasspathElement(Artifact artifact, MavenProject mavenProject) throws MojoExecutionException {
160 		String refId = artifact.getGroupId() + ":" + artifact.getArtifactId();
161 		MavenProject project = (MavenProject) mavenProject.getProjectReferences().get(refId);
162 		if (project != null) {
163 			return new File(project.getBuild().getOutputDirectory());
164 		} else {
165 			File file = artifact.getFile();
166 			if ((file == null) || (!file.exists())) {
167 				throw new MojoExecutionException("Dependency Resolution Required " + artifact);
168 			}
169 			return file;
170 		}
171 	}
172 }