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.stubgen; 018 019 import org.apache.maven.plugin.MojoExecutionException; 020 import org.apache.maven.plugin.MojoFailureException; 021 import org.apache.maven.shared.io.scan.mapping.SourceMapping; 022 import org.apache.maven.shared.io.scan.mapping.SuffixMapping; 023 import org.apache.maven.shared.model.fileset.FileSet; 024 import org.codehaus.gmaven.feature.Component; 025 import org.codehaus.gmaven.plugin.CompilerMojoSupport; 026 import org.codehaus.gmaven.runtime.StubCompiler; 027 028 import java.io.File; 029 import java.io.IOException; 030 import java.util.ArrayList; 031 import java.util.Iterator; 032 import java.util.List; 033 034 /** 035 * Support for Java stub generation mojos. 036 * 037 * <p> 038 * Stub generation basically parses Groovy sources, and then creates the bare-minimum 039 * Java source equivilent so that the maven-compiler-plugin's compile and testCompile 040 * goals can execute and resolve Groovy classes that may be referenced by Java sources. 041 * </p> 042 * 043 * <p> 044 * This is important, since our compile and testCompile goals execute *after* the 045 * normal Java compiler does. 046 * </p> 047 * 048 * @version $Id: AbstractGenerateStubsMojo.java 49 2009-10-16 14:03:56Z user57 $ 049 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> 050 * @author Jason Smith 051 */ 052 public abstract class AbstractGenerateStubsMojo 053 extends CompilerMojoSupport 054 { 055 protected AbstractGenerateStubsMojo() { 056 super(StubCompiler.KEY); 057 } 058 059 public void execute() throws MojoExecutionException, MojoFailureException { 060 super.execute(); 061 062 // Treatment for MGROOVY-187. 063 try { 064 resetStubModifiedDates(); 065 } 066 catch (Exception e) { 067 throw new MojoExecutionException("Failed to get output folder.", e); 068 } 069 } 070 071 /** 072 * Modifies the dates of the created stubs to 1970, ensuring that the Java 073 * compiler will not come along and overwrite perfectly good compiled Groovy 074 * just because it has a newer source stub. Basically, this prevents the 075 * stubs from causing a side effect with the Java compiler, but still allows 076 * the stubs to work with JavaDoc. Ideally, the code for this should be 077 * added to the code that creates the stubs, but as that code is sprinkled 078 * across several different runtimes, I am putting this into the common area. 079 */ 080 private void resetStubModifiedDates() throws Exception { 081 List stubs = recurseFiles(getOutputDirectory()); 082 083 for (Iterator i = stubs.iterator(); i.hasNext();) { 084 File file = (File) i.next(); 085 file.setLastModified(0L); 086 } 087 } 088 089 /** 090 * Get all files, recursively, in a folder. 091 * TODO: Should be moved into a utility class. 092 * 093 * @param folder The folder to look in. 094 * @return A list of <code>File</code> instances. 095 */ 096 private List recurseFiles(final File folder) { 097 assert folder != null; 098 099 List result = new ArrayList(); 100 File[] files = folder.listFiles(); 101 102 if (files != null) { 103 for (int i = 0; i < files.length; i++) { 104 if (files[i].isDirectory()) { 105 result.addAll(recurseFiles(files[i])); 106 } 107 else { 108 result.add(files[i]); 109 } 110 } 111 } 112 113 return result; 114 } 115 116 protected abstract void forceCompile(final File file); 117 118 protected void process(final Component component) throws Exception { 119 assert component != null; 120 121 StubCompiler compiler = (StubCompiler)component; 122 123 compiler.setTargetDirectory(getOutputDirectory()); 124 125 compiler.setClassPath(createClassPath()); 126 127 // 128 // TODO: Bridge mojo config to component config 129 // 130 131 compile(compiler, sources != null ? sources : getDefaultSources()); 132 } 133 134 protected void compile(final StubCompiler compiler, final FileSet[] sources) throws Exception { 135 assert compiler != null; 136 assert sources != null; 137 138 // Seems like we have to add the output dir each time so that the m-p-p site muck works 139 addSourceRoot(getOutputDirectory()); 140 141 for (int i=0; i<sources.length; i++) { 142 addSourceRoot(sources[i]); 143 144 SourceMapping[] mappings = { 145 new SuffixMapping(".groovy", ".java"), 146 }; 147 148 File[] files = scanForSources(sources[i], mappings); 149 150 for (int j=0; j < files.length; j++) { 151 log.debug(" + " + files[j]); 152 153 compiler.add(files[j]); 154 155 // For now assume we compile this puppy 156 forceCompile(files[j]); 157 } 158 } 159 160 int count = compiler.compile(); 161 162 if (count == 0) { 163 log.info("No sources found for Java stub generation"); 164 } 165 else { 166 log.info("Generated " + count + " Java stub" + (count > 1 ? "s" : "")); 167 } 168 } 169 170 private void addSourceRoot(final FileSet fileSet) throws IOException { 171 assert fileSet != null; 172 173 // Hook up as a source root so other plugins (like the m-compiler-p) can process anything in here if needed 174 File basedir = new File(fileSet.getDirectory()); 175 176 addSourceRoot(basedir); 177 } 178 }