View Javadoc

1   package org.codehaus.mojo.apt;
2   
3   /*
4    * The MIT License
5    *
6    * Copyright 2006-2008 The Codehaus.
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  
27  import java.io.File;
28  import java.io.FileNotFoundException;
29  import java.io.IOException;
30  import java.io.PrintWriter;
31  import java.io.UnsupportedEncodingException;
32  import java.util.Date;
33  import java.util.Set;
34  import java.util.jar.JarFile;
35  
36  import org.apache.maven.artifact.Artifact;
37  import org.apache.maven.artifact.handler.ArtifactHandler;
38  import org.apache.maven.artifact.repository.ArtifactRepository;
39  import org.apache.maven.plugin.MojoExecutionException;
40  
41  /**
42   * Generates Eclipse files for apt integration.
43   * 
44   * @author <a href="mailto:jubu@codehaus.org">Juraj Burian</a>
45   * @version $Id: EclipseMojo.java 7038 2008-05-22 22:07:36Z hboutemy $
46   * @goal eclipse
47   * @requiresDependencyResolution compile
48   */
49  public class EclipseMojo extends ProcessMojo
50  {
51      // TODO: tidy up code and write tests
52      // TODO: move to maven-eclipse-plugin?
53  
54      // read-only parameters ---------------------------------------------------
55  
56      /**
57       * The directory to run apt in.
58       * 
59       * @parameter expression="${basedir}"
60       * @required
61       * @readonly
62       */
63      private File basedir;
64  
65      /**
66       * The local artifact repository.
67       * 
68       * @parameter expression="${localRepository}"
69       * @required
70       * @readonly
71       */
72      private ArtifactRepository localRepository;
73  
74      // AbstractAptMojo methods ------------------------------------------------
75  
76      /**
77       * {@inheritDoc}
78       */
79      @Override
80      protected void executeImpl() throws MojoExecutionException
81      {
82          // exclude this:
83          ArtifactHandler artifactHandler = getProject().getArtifact().getArtifactHandler();
84  
85          if ( !"java".equals( artifactHandler.getLanguage() ) )
86          {
87              getLog().info( "Not executing apt eclipse goal as the project is not a Java classpath-capable package" );
88              return;
89          }
90  
91          if ( !isAptDefined() )
92          {
93              getLog().info( "Not executing apt eclipse goal, plugin is not configuret for this project." );
94              return;
95          }
96  
97          getLog().info( "Executing apt eclipse goal!" );
98  
99          // write prefs file
100 
101         File prefs = new File( basedir, ".settings" + File.separator + "org.eclipse.jdt.apt.core.prefs" );
102 
103         try
104         {
105             prefs.getParentFile().mkdirs();
106             prefs.createNewFile();
107         }
108         catch ( IOException exception )
109         {
110             throw new MojoExecutionException( "Can't create file: " + prefs.getPath() );
111         }
112 
113         PrintWriter out = null;
114 
115         try
116         {
117             out = new PrintWriter( prefs, "ISO-8859-1" );
118         }
119         catch ( FileNotFoundException exception )
120         {
121             // can't happen
122             throw new MojoExecutionException( null, exception );
123         }
124         catch ( UnsupportedEncodingException exception )
125         {
126             // can't happen
127             throw new MojoExecutionException( null, exception );
128         }
129 
130         out.println( "#" + new Date() );
131         out.println( "eclipse.preferences.version=1" );
132         out.println( "org.eclipse.jdt.apt.aptEnabled=true" );
133         out.println( "org.eclipse.jdt.apt.genSrcDir=" + getOutputDirectory().getPath() );
134 
135         // write processor options
136 
137         if ( getOptions() != null )
138         {
139             for ( String option : getOptions() )
140             {
141                 out.println( "org.eclipse.jdt.apt.processorOptions/" + option );
142             }
143         }
144 
145         out.close();
146 
147         // write .factorypath
148 
149         File factorypathFile = new File( basedir, ".factorypath" );
150 
151         try
152         {
153             prefs.createNewFile();
154         }
155         catch ( IOException exception )
156         {
157             throw new MojoExecutionException( "Can't create file: " + factorypathFile.getPath() );
158         }
159 
160         try
161         {
162             out = new PrintWriter( factorypathFile, "UTF-8" );
163         }
164         catch ( FileNotFoundException exception )
165         {
166             // can't happen
167         }
168         catch ( UnsupportedEncodingException exception )
169         {
170             // can't happen
171         }
172 
173         String localRepo = null;
174 
175         try
176         {
177             localRepo = new File( localRepository.getBasedir() ).getCanonicalPath();
178         }
179         catch ( IOException exception )
180         {
181             throw new MojoExecutionException( "Local repository: " + localRepository.getBasedir()
182                                               + " doesn't exists!" );
183         }
184 
185         out.println( "<factorypath> " );
186 
187         for ( String factorypathentry : getClasspathElements() )
188         {
189             // EXTJAR VARJAR
190             String kind = "EXTJAR";
191 
192             // force skip tools jar
193             if ( factorypathentry.endsWith( "tools.jar" ) )
194             {
195                 continue;
196             }
197 
198             try
199             {
200                 String tmp = new File( factorypathentry ).getCanonicalPath();
201 
202                 if ( tmp.startsWith( localRepo ) )
203                 {
204                     kind = "VARJAR";
205                     factorypathentry = tmp.replace( localRepo, "" );
206                     factorypathentry = "M2_REPO" + factorypathentry.replace( "\\", "/" );
207                 }
208             }
209             catch ( IOException exception )
210             {
211                 // ignore this
212             }
213 
214             String batchModeString = hasAnnotationProcessorFactory( factorypathentry ) ? "true" : "false";
215 
216             out.println( "    <factorypathentry kind=\"" + kind + "\" id=\"" + factorypathentry
217                             + " \" enabled=\"true\" runInBatchMode=\"" + batchModeString + "\"/>" );
218         }
219 
220         out.println( "</factorypath> " );
221         out.close();
222     }
223 
224     /**
225      * {@inheritDoc}
226      */
227     @Override
228     protected File getOutputDirectory()
229     {
230         String path = super.getOutputDirectory().getPath();
231 
232         // return only relative part of generated dir and replace \ -> /
233         path = path.replace( getProject().getBasedir().getAbsolutePath(), "" ).replace( "\\", "/" );
234 
235         return new File( path );
236     }
237 
238     // private methods --------------------------------------------------------
239 
240     private boolean isAptDefined()
241     {
242         Set<Artifact> pluginArtifacts = CollectionUtils.genericSet( getProject().getPluginArtifacts(), Artifact.class );
243 
244         for ( Artifact artifact : pluginArtifacts )
245         {
246             if ( "apt-maven-plugin".equals( artifact.getArtifactId() ) )
247             {
248                 return true;
249             }
250         }
251 
252         return false;
253     }
254 
255     private static boolean hasAnnotationProcessorFactory( String factorypathentry )
256     {
257         try
258         {
259             if ( factorypathentry.endsWith( "jar" ) )
260             {
261                 JarFile file = new JarFile( factorypathentry );
262 
263                 if ( file.getEntry( "META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory" ) != null )
264                 {
265                     return true;
266                 }
267             }
268         }
269         catch ( IOException exception )
270         {
271             // ignore this
272         }
273 
274         return false;
275     }
276 }