001    /*
002     * Copyright (C) 2006-2007 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.codehaus.gmaven.plugin.compile;
018    
019    import org.apache.maven.shared.io.scan.mapping.SourceMapping;
020    import org.apache.maven.shared.io.scan.mapping.SuffixMapping;
021    import org.apache.maven.shared.model.fileset.FileSet;
022    import org.codehaus.gmaven.feature.Component;
023    import org.codehaus.gmaven.feature.Configuration;
024    import org.codehaus.gmaven.plugin.CompilerMojoSupport;
025    import org.codehaus.gmaven.runtime.ClassCompiler;
026    
027    import java.io.File;
028    import java.util.Iterator;
029    import java.util.Set;
030    
031    /**
032     * Support for compile mojos that generate classes.
033     *
034     * @version $Id: AbstractCompileMojo.java 105 2010-07-05 22:23:14Z user57 $
035     * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
036     */
037    public abstract class AbstractCompileMojo
038        extends CompilerMojoSupport
039        implements ClassCompiler.Keys
040    {
041        protected AbstractCompileMojo() {
042            super(ClassCompiler.KEY);
043        }
044    
045        /**
046         * Sets the encoding to be used when reading source files.
047         *
048         * @parameter expression="${sourceEncoding}" default-value="${project.build.sourceEncoding}"
049         * 
050         * @noinspection UnusedDeclaration
051         */
052        private String sourceEncoding;
053    
054        /**
055         * Turns verbose operation on or off.
056         *
057         * @parameter expression="${verbose}" default-value="false"
058         *
059         * @noinspection UnusedDeclaration
060         */
061        private boolean verbose;
062    
063        /**
064         * Turns debugging operation on or off.
065         *
066         * @parameter expression="${debug}" default-value="false"
067         *
068         * @noinspection UnusedDeclaration
069         */
070        private boolean debug;
071    
072        /**
073         * Enable compiler to report stack trace information if a problem occurs.
074         *
075         * @parameter expression="${stacktrace}" default-value="false"
076         *
077         * @noinspection UnusedDeclaration
078         */
079        private boolean stacktrace;
080    
081        /**
082         * Sets the error tolerance, which is the number of non-fatal errors (per unit)
083         * that should be tolerated before compilation is aborted.
084         *
085         * @parameter expression="${tolerance}" default-value="0"
086         *
087         * @noinspection UnusedDeclaration
088         */
089        private int tolerance;
090        
091        /**
092         * Allow setting the bytecode compatibility.
093         *
094         * @parameter expression="${targetBytecode}"
095         *
096         * @noinspection UnusedDeclaration
097         */
098        private String targetBytecode;
099        
100        /**
101         * Sets the warning level.
102         *
103         * @paramater expression="${waningLevel}" default-value="0"
104         *
105         * @noinspection UnusedDeclaration
106         */
107        private int warningLevel;
108        
109        /**
110         * Sets the name of the base class for scripts. It must be a subclass of <tt>groovy.lang.Script</tt>.
111         *
112         * @parameter expression="${scriptBaseClassname}"
113         *
114         * @noinspection UnusedDeclaration
115         */ 
116        private String scriptBaseClassname;
117    
118        /**
119         * Set the default extention for Groovy script source files.
120         *
121         * @parameter expression="${defaultScriptExtension}" default-value=".groovy"
122         *
123         * @noinspection UnusedDeclaration
124         */
125        private String defaultScriptExtension;
126    
127        protected abstract Set getForcedCompileSources();
128    
129        protected void process(final Component component) throws Exception {
130            assert component != null;
131    
132            ClassCompiler compiler = (ClassCompiler)component;
133    
134            compiler.setTargetDirectory(getOutputDirectory());
135            
136            compiler.setClassPath(createClassPath());
137    
138            Configuration config = component.config();
139    
140            config.set(VERBOSE, verbose);
141    
142            config.set(DEBUG, debug);
143    
144            config.set(TOLERANCE, tolerance);
145            
146            if (targetBytecode != null) {
147                config.set(TARGET_BYTECODE, targetBytecode);
148            }
149    
150            config.set(WARNING_LEVEL, warningLevel);
151            
152            if (sourceEncoding != null) {
153                config.set(SOURCE_ENCODING, sourceEncoding);
154            }
155    
156            if (scriptBaseClassname != null) {
157                config.set(SCRIPT_BASE_CLASSNAME, scriptBaseClassname);
158            }
159            
160            if (defaultScriptExtension != null) {
161                config.set(DEFAULT_SCRIPT_EXTENSION, defaultScriptExtension);
162            }
163    
164            compile(compiler, sources != null ? sources : getDefaultSources());
165        }
166    
167        protected void compile(final ClassCompiler compiler, final FileSet[] sources) throws Exception {
168            assert compiler != null;
169            assert sources != null;
170    
171            for (int i=0; i<sources.length; i++) {
172                SourceMapping[] mappings = {
173                    new SuffixMapping(".groovy", ".class"),
174                    new SuffixMapping(".java", ".class"),
175                };
176    
177                File[] files = scanForSources(sources[i], mappings);
178    
179                for (int j=0; j < files.length; j++) {
180                    log.debug(" + " + files[j]);
181    
182                    compiler.add(files[j]);
183                }
184            }
185    
186            Set forced = getForcedCompileSources();
187    
188            if (!forced.isEmpty()) {
189                log.debug("Forcing to compile:");
190    
191                for (Iterator iter=forced.iterator(); iter.hasNext();) {
192                    File file = (File)iter.next();
193    
194                    log.debug(" + {}", file);
195    
196                    compiler.add(file);
197                }
198            }
199    
200            int count = compiler.compile();
201    
202            if (count == 0) {
203                log.info("No sources found to compile");
204            }
205            else {
206                log.info("Compiled " + count + " Groovy class" + (count > 1 ? "es" : ""));
207            }
208        }
209    }