View Javadoc
1   package org.codehaus.plexus.compiler;
2   
3   /**
4    * The MIT License
5    *
6    * Copyright (c) 2005, 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 org.codehaus.plexus.logging.AbstractLogEnabled;
28  import org.codehaus.plexus.util.DirectoryScanner;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.util.HashSet;
33  import java.util.List;
34  import java.util.Set;
35  
36  /**
37   * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
38   * @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka </a>
39   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
40   */
41  public abstract class AbstractCompiler
42      extends AbstractLogEnabled
43      implements Compiler
44  {
45      protected static final String EOL = System.lineSeparator();
46  
47      protected static final String PS = System.getProperty( "path.separator" );
48  
49      private CompilerOutputStyle compilerOutputStyle;
50  
51      private String inputFileEnding;
52  
53      private String outputFileEnding;
54  
55      private String outputFile;
56  
57      // ----------------------------------------------------------------------
58      //
59      // ----------------------------------------------------------------------
60  
61      protected AbstractCompiler( CompilerOutputStyle compilerOutputStyle, String inputFileEnding,
62                                  String outputFileEnding, String outputFile )
63      {
64          this.compilerOutputStyle = compilerOutputStyle;
65  
66          this.inputFileEnding = inputFileEnding;
67  
68          this.outputFileEnding = outputFileEnding;
69  
70          this.outputFile = outputFile;
71      }
72  
73      // ----------------------------------------------------------------------
74      //
75      // ----------------------------------------------------------------------
76  
77      public CompilerResult performCompile(CompilerConfiguration configuration)
78              throws CompilerException 
79      {
80          throw new CompilerNotImplementedException("The performCompile method has not been implemented.");
81      }
82  
83      @Deprecated
84      public List<CompilerError> compile(CompilerConfiguration configuration)
85              throws CompilerException
86      {
87          throw new CompilerNotImplementedException("The compile method has not been implemented.");
88      }
89  
90      public CompilerOutputStyle getCompilerOutputStyle()
91      {
92          return compilerOutputStyle;
93      }
94  
95      public String getInputFileEnding( CompilerConfiguration configuration )
96          throws CompilerException
97      {
98          return inputFileEnding;
99      }
100 
101     public String getOutputFileEnding( CompilerConfiguration configuration )
102         throws CompilerException
103     {
104         if ( compilerOutputStyle != CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE )
105         {
106             throw new RuntimeException( "This compiler implementation doesn't have one output file per input file." );
107         }
108 
109         return outputFileEnding;
110     }
111 
112     public String getOutputFile( CompilerConfiguration configuration )
113         throws CompilerException
114     {
115         if ( compilerOutputStyle != CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
116         {
117             throw new RuntimeException( "This compiler implementation doesn't have one output file for all files." );
118         }
119 
120         return outputFile;
121     }
122 
123     public boolean canUpdateTarget( CompilerConfiguration configuration )
124         throws CompilerException
125     {
126         return true;
127     }
128 
129     // ----------------------------------------------------------------------
130     // Utility Methods
131     // ----------------------------------------------------------------------
132 
133     public static String getPathString( List<String> pathElements )
134     {
135         StringBuilder sb = new StringBuilder();
136 
137         for ( String pathElement : pathElements )
138         {
139             sb.append( pathElement ).append( File.pathSeparator );
140         }
141 
142         return sb.toString();
143     }
144 
145     protected static Set<String> getSourceFilesForSourceRoot( CompilerConfiguration config, String sourceLocation )
146     {
147         DirectoryScanner scanner = new DirectoryScanner();
148 
149         scanner.setBasedir( sourceLocation );
150 
151         Set<String> includes = config.getIncludes();
152 
153         if ( includes != null && !includes.isEmpty() )
154         {
155             String[] inclStrs = includes.toArray( new String[includes.size()] );
156             scanner.setIncludes( inclStrs );
157         }
158         else
159         {
160             scanner.setIncludes( new String[]{ "**/*.java" } );
161         }
162 
163         Set<String> excludes = config.getExcludes();
164 
165         if ( excludes != null && !excludes.isEmpty() )
166         {
167             String[] exclStrs = excludes.toArray( new String[excludes.size()] );
168             scanner.setExcludes( exclStrs );
169         }
170 
171         scanner.scan();
172 
173         String[] sourceDirectorySources = scanner.getIncludedFiles();
174 
175         Set<String> sources = new HashSet<>();
176 
177         for ( String sourceDirectorySource : sourceDirectorySources )
178         {
179             File f = new File( sourceLocation, sourceDirectorySource );
180 
181             sources.add( f.getPath() );
182         }
183 
184         return sources;
185     }
186 
187     protected static String[] getSourceFiles( CompilerConfiguration config )
188     {
189         Set<String> sources = new HashSet<>();
190 
191         Set<File> sourceFiles = config.getSourceFiles();
192 
193         if ( sourceFiles != null && !sourceFiles.isEmpty() )
194         {
195             for ( File sourceFile : sourceFiles )
196             {
197                 sources.add( sourceFile.getAbsolutePath() );
198             }
199         }
200         else
201         {
202             for ( String sourceLocation : config.getSourceLocations() )
203             {
204                 sources.addAll( getSourceFilesForSourceRoot( config, sourceLocation ) );
205             }
206         }
207 
208         String[] result;
209 
210         if ( sources.isEmpty() )
211         {
212             result = new String[0];
213         }
214         else
215         {
216             result = sources.toArray( new String[sources.size()] );
217         }
218 
219         return result;
220     }
221 
222     protected static String makeClassName( String fileName, String sourceDir )
223         throws CompilerException
224     {
225         File origFile = new File( fileName );
226 
227         String canonical = null;
228 
229         if ( origFile.exists() )
230         {
231             canonical = getCanonicalPath( origFile ).replace( '\\', '/' );
232         }
233 
234         if ( sourceDir != null )
235         {
236             String prefix = getCanonicalPath( new File( sourceDir ) ).replace( '\\', '/' );
237 
238             if ( canonical != null )
239             {
240                 if ( canonical.startsWith( prefix ) )
241                 {
242                     String result = canonical.substring( prefix.length() + 1, canonical.length() - 5 );
243 
244                     result = result.replace( '/', '.' );
245 
246                     return result;
247                 }
248             }
249             else
250             {
251                 File t = new File( sourceDir, fileName );
252 
253                 if ( t.exists() )
254                 {
255                     String str = getCanonicalPath( t ).replace( '\\', '/' );
256 
257                     return str.substring( prefix.length() + 1, str.length() - 5 ).replace( '/', '.' );
258                 }
259             }
260         }
261 
262         if ( fileName.endsWith( ".java" ) )
263         {
264             fileName = fileName.substring( 0, fileName.length() - 5 );
265         }
266 
267         fileName = fileName.replace( '\\', '.' );
268 
269         return fileName.replace( '/', '.' );
270     }
271 
272     private static String getCanonicalPath( File origFile )
273         throws CompilerException
274     {
275         try
276         {
277             return origFile.getCanonicalPath();
278         }
279         catch ( IOException e )
280         {
281             throw new CompilerException(
282                 "Error while getting the canonical path of '" + origFile.getAbsolutePath() + "'.", e );
283         }
284     }
285 
286     /**
287      * @deprecated use (String[]) arguments.toArray( new String[ arguments.size() ] ); instead
288      */
289     protected static String[] toStringArray( List<String> arguments )
290     {
291         String[] args = new String[arguments.size()];
292 
293         int argLength = arguments.size();
294 
295         for ( int i = 0; i < argLength; i++ )
296         {
297             args[i] = arguments.get( i );
298         }
299 
300         return args;
301     }
302 }