pax_global_header00006660000000000000000000000064116520300250014504gustar00rootroot0000000000000052 comment=a0cdeb1524f8395f98138a398f661af62594eef9 maven-stapler-plugin-1.16/000077500000000000000000000000001165203002500155055ustar00rootroot00000000000000maven-stapler-plugin-1.16/.cvsignore000066400000000000000000000000311165203002500174770ustar00rootroot00000000000000target *.iws *.iml *.ipr maven-stapler-plugin-1.16/.gitignore000066400000000000000000000000311165203002500174670ustar00rootroot00000000000000*.iml *.ipr *.iws target maven-stapler-plugin-1.16/pom.xml000066400000000000000000000123041165203002500170220ustar00rootroot00000000000000 4.0.0 org.kohsuke.stapler maven-stapler-plugin maven-plugin 1.16 Maven Stapler plugin Maven2 plugin for developing stapler applications scm:git:git://github.com/stapler/${project.artifactId}.git scm:git:ssh://git@github.com/stapler/${project.artifactId}.git https://github.com/stapler/${project.artifactId} 2-clause BSD license repo http://www.opensource.org/licenses/bsd-license.php maven.jenkins-ci.org http://maven.jenkins-ci.org:8081/content/repositories/releases/ maven-compiler-plugin 1.5 1.5 org.apache.maven.plugins maven-idea-plugin JDK1.5 true maven-plugin-plugin stapler org.jvnet.wagon-svn wagon-svn 1.9 maven2-repository.dev.java.net Java.net Repository for Maven http://download.java.net/maven/2/ org.kohsuke.stapler stapler 1.100 org.apache.maven maven-plugin-api 2.0.1 org.apache.maven maven-core 2.0.1 org.codehaus.plexus plexus-utils 1.5.9 org.apache.maven maven-project 2.0.1 org.apache.maven maven-artifact 2.0.1 qdox qdox 1.6.1 org.apache.maven.plugins maven-compiler-plugin 2.0.2 org.codehaus.plexus plexus-compiler-javac 1.5.3 org.codehaus.plexus plexus-compiler-manager 1.5.3 dom4j dom4j 1.6.1 org.jvnet.maven-jellydoc-plugin maven-jellydoc-plugin 1.5 jaxen jaxen 1.1.1 com.google.guava guava r06 org.kohsuke.metainf-services metainf-services 1.2 default-tools.jar java.vendor Sun Microsystems Inc. com.sun tools 1.5 system ${java.home}/../lib/tools.jar maven-stapler-plugin-1.16/src/000077500000000000000000000000001165203002500162745ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/000077500000000000000000000000001165203002500172205ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/java/000077500000000000000000000000001165203002500201415ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/java/org/000077500000000000000000000000001165203002500207305ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/java/org/kohsuke/000077500000000000000000000000001165203002500224015ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/000077500000000000000000000000001165203002500240535ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/AbstractCompilerMojo.java000066400000000000000000000501671165203002500310120ustar00rootroot00000000000000// COPIED FROM MAVEN: DO NOT MODIFY package org.kohsuke.stapler; /* * Copyright 2001-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.CompilationFailureException; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.compiler.Compiler; import org.codehaus.plexus.compiler.CompilerConfiguration; import org.codehaus.plexus.compiler.CompilerError; import org.codehaus.plexus.compiler.CompilerException; import org.codehaus.plexus.compiler.CompilerOutputStyle; import org.codehaus.plexus.compiler.manager.CompilerManager; import org.codehaus.plexus.compiler.manager.NoSuchCompilerException; import org.codehaus.plexus.compiler.util.scan.InclusionScanException; import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.mapping.SingleTargetSourceMapping; import org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping; import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping; import org.codehaus.plexus.util.StringUtils; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; /** * TODO: At least one step could be optimized, currently the plugin will do two * scans of all the source code if the compiler has to have the entire set of * sources. This is currently the case for at least the C# compiler and most * likely all the other .NET compilers too. * * @author others * @author Trygve Laugstøl * @version $Id: AbstractCompilerMojo.java 383 2007-08-19 17:12:03Z kohsuke $ */ public abstract class AbstractCompilerMojo extends AbstractMojo { // ---------------------------------------------------------------------- // Configurables // ---------------------------------------------------------------------- /** * Set to true to include debugging information in the compiled class files. * The default value is true. * * @parameter expression="${maven.compiler.debug}" default-value="true" */ private boolean debug; /** * Set to true to show messages about what the compiler is doing. * * @parameter expression="${maven.compiler.verbose}" default-value="false" */ private boolean verbose; /** * Sets whether to show source locations where deprecated APIs are used. * * @parameter expression="${maven.compiler.showDeprecation}" default-value="false" */ private boolean showDeprecation; /** * Set to true to optimize the compiled code using the compiler's optimization methods. * * @parameter expression="${maven.compiler.optimize}" default-value="false" */ private boolean optimize; /** * Set to true to show compilation warnings. * * @parameter expression="${maven.compiler.showWarnings}" default-value="false" */ private boolean showWarnings; /** * The -source argument for the Java compiler. * * @parameter expression="${maven.compiler.source}" */ private String source; /** * The -target argument for the Java compiler. * * @parameter expression="${maven.compiler.target}" */ private String target; /** * The -encoding argument for the Java compiler. * * @parameter expression="${maven.compiler.encoding}" */ private String encoding; /** * Sets the granularity in milliseconds of the last modification * date for testing whether a source needs recompilation. * * @parameter expression="${lastModGranularityMs}" default-value="0" */ private int staleMillis; /** * The compiler id of the compiler to use. See this * guide for more information. * * @parameter expression="${maven.compiler.compilerId}" default-value="javac" */ private String compilerId; /** * Version of the compiler to use, ex. "1.3", "1.5", if fork is set to true. * * @parameter expression="${maven.compiler.compilerVersion}" */ private String compilerVersion; /** * Allows running the compiler in a separate process. * If "false" it uses the built in compiler, while if "true" it will use an executable. * * @parameter default-value="false" */ private boolean fork; /** * Initial size, in megabytes, of the memory allocation pool, ex. "64", "64m" * if fork is set to true. * * @parameter expression="${maven.compiler.meminitial}" */ private String meminitial; /** * Sets the maximum size, in megabytes, of the memory allocation pool, ex. "128", "128m" * if fork is set to true. * * @parameter expression="${maven.compiler.maxmem}" */ private String maxmem; /** * Sets the executable of the compiler to use when fork is true. * * @parameter expression="${maven.compiler.executable}" */ private String executable; /** *

* Sets the arguments to be passed to the compiler (prepending a dash) if fork is set to true. *

*

* This is because the list of valid arguments passed to a Java compiler * varies based on the compiler version. *

* * @parameter */ private Map compilerArguments; /** *

* Sets the unformatted argument string to be passed to the compiler if fork is set to true. *

*

* This is because the list of valid arguments passed to a Java compiler * varies based on the compiler version. *

* * @parameter */ private String compilerArgument; /** * Sets the name of the output file when compiling a set of * sources to a single file. * * @parameter expression="${project.build.finalName}" */ private String outputFileName; // ---------------------------------------------------------------------- // Read-only parameters // ---------------------------------------------------------------------- /** * The directory to run the compiler from if fork is true. * * @parameter expression="${basedir}" * @required * @readonly */ private File basedir; /** * The target directory of the compiler if fork is true. * * @parameter expression="${project.build.directory}" * @required * @readonly */ private File buildDirectory; /** * Plexus compiler manager. * * @component */ private CompilerManager compilerManager; protected abstract SourceInclusionScanner getSourceInclusionScanner( int staleMillis ); protected abstract SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding ); protected abstract List getClasspathElements(); protected abstract List getCompileSourceRoots(); protected abstract File getOutputDirectory(); public void execute() throws MojoExecutionException, CompilationFailureException { // ---------------------------------------------------------------------- // Look up the compiler. This is done before other code than can // cause the mojo to return before the lookup is done possibly resulting // in misconfigured POMs still building. // ---------------------------------------------------------------------- Compiler compiler; getLog().debug( "Using compiler '" + compilerId + "'." ); try { compiler = compilerManager.getCompiler( compilerId ); } catch ( NoSuchCompilerException e ) { throw new MojoExecutionException( "No such compiler '" + e.getCompilerId() + "'." ); } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- List compileSourceRoots = removeEmptyCompileSourceRoots( getCompileSourceRoots() ); if ( compileSourceRoots.isEmpty() ) { getLog().info( "No sources to compile" ); return; } if ( getLog().isDebugEnabled() ) { getLog().debug( "Source directories: " + compileSourceRoots.toString().replace( ',', '\n' ) ); getLog().debug( "Classpath: " + getClasspathElements().toString().replace( ',', '\n' ) ); getLog().debug( "Output directory: " + getOutputDirectory() ); } // ---------------------------------------------------------------------- // Create the compiler configuration // ---------------------------------------------------------------------- CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.setOutputLocation( getOutputDirectory().getAbsolutePath() ); compilerConfiguration.setClasspathEntries( getClasspathElements() ); compilerConfiguration.setSourceLocations( compileSourceRoots ); compilerConfiguration.setOptimize( optimize ); compilerConfiguration.setDebug( debug ); compilerConfiguration.setVerbose( verbose ); compilerConfiguration.setShowWarnings( showWarnings ); compilerConfiguration.setShowDeprecation( showDeprecation ); compilerConfiguration.setSourceVersion( source ); compilerConfiguration.setTargetVersion( target ); compilerConfiguration.setSourceEncoding( encoding ); if (( compilerArguments != null ) || ( compilerArgument != null )) { LinkedHashMap cplrArgsCopy = new LinkedHashMap(); if ( compilerArguments != null ) { for ( Iterator i = compilerArguments.entrySet().iterator(); i.hasNext(); ) { Map.Entry me = (Map.Entry) i.next(); String key = (String) me.getKey(); String value = (String) me.getValue(); if ( !key.startsWith( "-" )) { key = "-" + key; } cplrArgsCopy.put( key, value ); } } if ( !StringUtils.isEmpty( compilerArgument) ) { cplrArgsCopy.put( compilerArgument, null ); } compilerConfiguration.setCustomCompilerArguments( cplrArgsCopy ); } compilerConfiguration.setFork( fork ); if( fork ) { if ( !StringUtils.isEmpty( meminitial ) ) { String value = getMemoryValue( meminitial ); if ( value != null ) { compilerConfiguration.setMeminitial( value ); } else { getLog().info( "Invalid value for meminitial '" + meminitial + "'. Ignoring this option." ); } } if ( !StringUtils.isEmpty( maxmem ) ) { String value = getMemoryValue( maxmem ); if ( value != null ) { compilerConfiguration.setMaxmem( value ); } else { getLog().info( "Invalid value for maxmem '" + maxmem + "'. Ignoring this option." ); } } } compilerConfiguration.setExecutable( executable ); compilerConfiguration.setWorkingDirectory( basedir ); compilerConfiguration.setCompilerVersion( compilerVersion ); compilerConfiguration.setBuildDirectory( buildDirectory ); compilerConfiguration.setOutputFileName( outputFileName ); // TODO: have an option to always compile (without need to clean) Set staleSources; boolean canUpdateTarget; try { staleSources = computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( staleMillis ) ); canUpdateTarget = compiler.canUpdateTarget( compilerConfiguration ); if ( compiler.getCompilerOutputStyle().equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) && !canUpdateTarget ) { getLog().info( "RESCANNING!" ); // TODO: This second scan for source files is sub-optimal String inputFileEnding = compiler.getInputFileEnding( compilerConfiguration ); Set sources = computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( inputFileEnding ) ); compilerConfiguration.setSourceFiles( sources ); } else { compilerConfiguration.setSourceFiles( staleSources ); } } catch ( CompilerException e ) { throw new MojoExecutionException( "Error while computing stale sources.", e ); } if ( staleSources.isEmpty() ) { getLog().info( "Nothing to compile - all classes are up to date" ); return; } // ---------------------------------------------------------------------- // Dump configuration // ---------------------------------------------------------------------- if ( getLog().isDebugEnabled() ) { getLog().debug( "Classpath:" ); for ( Iterator it = getClasspathElements().iterator(); it.hasNext(); ) { String s = (String) it.next(); getLog().debug( " " + s ); } getLog().debug( "Source roots:" ); for ( Iterator it = getCompileSourceRoots().iterator(); it.hasNext(); ) { String root = (String) it.next(); getLog().debug( " " + root ); } if ( fork ) { try { if ( compilerConfiguration.getExecutable() != null ) { getLog().debug( "Excutable: " ); getLog().debug( " " + compilerConfiguration.getExecutable() ); } String[] cl = compiler.createCommandLine( compilerConfiguration ); if ( cl != null && cl.length > 0 ) { StringBuffer sb = new StringBuffer(); sb.append( cl[0] ); for ( int i = 1; i < cl.length; i++ ) { sb.append( " " ); sb.append( cl[i] ); } getLog().debug( "Command line options:" ); getLog().debug( sb ); } } catch ( CompilerException ce ) { getLog().debug( ce ); } } } // ---------------------------------------------------------------------- // Compile! // ---------------------------------------------------------------------- List messages; try { messages = compiler.compile( compilerConfiguration ); } catch ( Exception e ) { // TODO: don't catch Exception throw new MojoExecutionException( "Fatal error compiling", e ); } boolean compilationError = false; for ( Iterator i = messages.iterator(); i.hasNext(); ) { CompilerError message = (CompilerError) i.next(); if ( message.isError() ) { compilationError = true; } } if ( compilationError ) { throw new CompilationFailureException( messages ); } else { for ( Iterator i = messages.iterator(); i.hasNext(); ) { CompilerError message = (CompilerError) i.next(); getLog().warn( message.toString() ); } } } private String getMemoryValue( String setting ) { String value = null; // Allow '128' or '128m' if ( isDigits( setting ) ) { value = setting + "m"; } else { if ( ( isDigits( setting.substring( 0, setting.length() - 1 ) ) ) && ( setting.toLowerCase().endsWith( "m" ) ) ) { value = setting; } } return value; } private boolean isDigits( String string ) { for ( int i = 0; i < string.length(); i++ ) { if ( !Character.isDigit( string.charAt( i ) ) ) { return false; } } return true; } private Set computeStaleSources( CompilerConfiguration compilerConfiguration, Compiler compiler, SourceInclusionScanner scanner ) throws MojoExecutionException, CompilerException { CompilerOutputStyle outputStyle = compiler.getCompilerOutputStyle(); SourceMapping mapping; File outputDirectory; if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE ) { mapping = new SuffixMapping( compiler.getInputFileEnding( compilerConfiguration ), compiler .getOutputFileEnding( compilerConfiguration ) ); outputDirectory = getOutputDirectory(); } else if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES ) { mapping = new SingleTargetSourceMapping( compiler.getInputFileEnding( compilerConfiguration ), compiler .getOutputFile( compilerConfiguration ) ); outputDirectory = buildDirectory; } else { throw new MojoExecutionException( "Unknown compiler output style: '" + outputStyle + "'." ); } scanner.addSourceMapping( mapping ); Set staleSources = new HashSet(); for ( Iterator it = getCompileSourceRoots().iterator(); it.hasNext(); ) { String sourceRoot = (String) it.next(); File rootFile = new File( sourceRoot ); if ( !rootFile.isDirectory() ) { continue; } try { staleSources.addAll( scanner.getIncludedSources( rootFile, outputDirectory ) ); } catch ( InclusionScanException e ) { throw new MojoExecutionException( "Error scanning source root: \'" + sourceRoot + "\' " + "for stale files to recompile.", e ); } } return staleSources; } /** * @todo also in ant plugin. This should be resolved at some point so that it does not need to * be calculated continuously - or should the plugins accept empty source roots as is? */ private static List removeEmptyCompileSourceRoots( List compileSourceRootsList ) { List newCompileSourceRootsList = new ArrayList(); if ( compileSourceRootsList != null ) { // copy as I may be modifying it for ( Iterator i = compileSourceRootsList.iterator(); i.hasNext(); ) { String srcDir = (String) i.next(); if ( !newCompileSourceRootsList.contains( srcDir ) && new File( srcDir ).exists() ) { newCompileSourceRootsList.add( srcDir ); } } } return newCompileSourceRootsList; } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/AbstractProcessorImpl.java000066400000000000000000000025431165203002500312070ustar00rootroot00000000000000package org.kohsuke.stapler; import javax.annotation.processing.AbstractProcessor; import javax.lang.model.element.Element; import javax.tools.FileObject; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; import static javax.tools.Diagnostic.Kind.*; import static javax.tools.StandardLocation.*; /** * @author Kohsuke Kawaguchi */ @SuppressWarnings({"Since15"}) abstract class AbstractProcessorImpl extends AbstractProcessor { protected void error(String msg) { processingEnv.getMessager().printMessage(ERROR, msg); } protected String getJavadoc(Element md) { return processingEnv.getElementUtils().getDocComment(md); } protected void notice(String msg, Element location) { processingEnv.getMessager().printMessage(NOTE, msg, location); } protected void writePropertyFile(Properties p, String name) throws IOException { FileObject f = createResource(name); OutputStream os = f.openOutputStream(); p.store(os,null); os.close(); } protected FileObject getResource(String name) throws IOException { return processingEnv.getFiler().getResource(CLASS_OUTPUT, "", name); } protected FileObject createResource(String name) throws IOException { return processingEnv.getFiler().createResource(CLASS_OUTPUT, "", name); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/AnnotationProcessorFactoryImpl.java000066400000000000000000000050231165203002500331020ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.AnnotationProcessorFactory; import com.sun.mirror.apt.AnnotationProcessors; import com.sun.mirror.declaration.AnnotationTypeDeclaration; import java.util.Collection; import java.util.Collections; import java.util.Set; /** * @author Kohsuke Kawaguchi * @deprecated * Requiring 1.6 for development-time. Annotation processing is now a part of the core stapler. */ public final class AnnotationProcessorFactoryImpl implements AnnotationProcessorFactory { public Collection supportedOptions() { return Collections.emptyList(); } public Collection supportedAnnotationTypes() { return Collections.singleton("*"); } public AnnotationProcessor getProcessorFor(Set set, AnnotationProcessorEnvironment env) { return AnnotationProcessors.getCompositeAnnotationProcessor( new ExportedBeanAnnotationProcessor(env), new ConstructorProcessor(env), new QueryParameterAnnotationProcessor(env) ); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/AptCompiler.java000066400000000000000000000207241165203002500271420ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import org.codehaus.plexus.compiler.CompilerConfiguration; import org.codehaus.plexus.compiler.CompilerException; import org.codehaus.plexus.compiler.CompilerError; import org.codehaus.plexus.compiler.javac.JavacCompiler; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.CommandLineException; import java.io.File; import java.io.PrintWriter; import java.io.IOException; import java.io.BufferedReader; import java.io.StringReader; import java.io.FileWriter; import java.util.Collections; import java.util.List; import java.net.URL; import java.net.MalformedURLException; /** * {@link Compiler} for APT. * *

* In Maven, {@link Compiler} handles the actual compiler invocation. * * @author Kohsuke Kawaguchi */ public class AptCompiler extends JavacCompiler { public List compile( CompilerConfiguration config ) throws CompilerException { // force 1.5 config.setTargetVersion("1.5"); config.setSourceVersion("1.5"); File destinationDir = new File( config.getOutputLocation() ); if ( !destinationDir.exists() ) { destinationDir.mkdirs(); } String[] sourceFiles = getSourceFiles( config ); if ( sourceFiles.length == 0 ) { return Collections.EMPTY_LIST; } getLogger().info( "Compiling " + sourceFiles.length + " " + "source file" + ( sourceFiles.length == 1 ? "" : "s" ) + " to " + destinationDir.getAbsolutePath() ); if (config.isFork()) { // forking a compiler requires classpath set up and passing AnnotationProcessorFactory. config.addClasspathEntry(whichJar(AnnotationProcessorFactoryImpl.class)); config.addCompilerCustomArgument("-factory",AnnotationProcessorFactoryImpl.class.getName()); } // this is where the META-INF/services get generated. config.addCompilerCustomArgument("-s",new File(config.getOutputLocation()).getAbsolutePath()); String[] args = buildCompilerArguments( config, sourceFiles ); if (config.isFork()) { String executable = config.getExecutable(); if (StringUtils.isEmpty(executable)) { File apt = new File(new File(System.getProperty("java.home")),"bin/apt"); // Mac puts $JAVA_HOME to JDK if (!apt.exists()) // on other platforms $JAVA_HOME is JRE in JDK. apt = new File(new File(System.getProperty("java.home")),"../bin/apt"); executable = apt.getAbsolutePath(); } return compileOutOfProcess(config, executable, args); } else { return compileInProcess(args); } } private String whichJar(Class c) throws CompilerException { try { String url = c.getClassLoader().getResource(c.getName().replace('.', '/') + ".class").toExternalForm(); if (url.startsWith("jar:")) { url = url.substring(4); url = url.substring(0,url.indexOf('!')); return new URL(url).getPath(); } throw new CompilerException("Failed to infer classpath for "+c); } catch (MalformedURLException e) { throw new CompilerException("Failed to infer classpath for "+c,e); } } /** * Compile the java sources in the current JVM, without calling an external executable, * using com.sun.tools.javac.Main class * * @param args arguments for the compiler as they would be used in the command line javac * @return List of CompilerError objects with the errors encountered. * @throws CompilerException */ protected List compileInProcess( String[] args ) throws CompilerException { com.sun.tools.apt.Main aptTool = new com.sun.tools.apt.Main(); int r = aptTool.process(new AnnotationProcessorFactoryImpl(), new PrintWriter(System.out,true),args); if(r!=0) throw new CompilerException("APT failed: "+r); // TODO: should I try to parse the output? return Collections.emptyList(); } protected List compileOutOfProcess(CompilerConfiguration config, String executable, String[] args) throws CompilerException { Commandline cli = new Commandline(); cli.setWorkingDirectory(config.getWorkingDirectory().getAbsolutePath()); cli.setExecutable(executable); try { File argumentsFile = createFileWithArguments(args); cli.addArguments(new String[]{"@" + argumentsFile.getCanonicalPath().replace(File.separatorChar, '/')}); if (!StringUtils.isEmpty(config.getMaxmem())) { cli.addArguments(new String[]{"-J-Xmx" + config.getMaxmem()}); } if (!StringUtils.isEmpty(config.getMeminitial())) { cli.addArguments(new String[]{"-J-Xms" + config.getMeminitial()}); } } catch (IOException e) { throw new CompilerException("Error creating file with javac arguments", e); } CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer(); CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer(); int returnCode; List messages; try { returnCode = CommandLineUtils.executeCommandLine(cli, out, err); messages = parseModernStream(new BufferedReader(new StringReader(err.getOutput()))); } catch (CommandLineException e) { throw new CompilerException("Error while executing the external compiler.", e); } catch (IOException e) { throw new CompilerException("Error while executing the external compiler.", e); } if (returnCode != 0 && messages.isEmpty()) { if (err.getOutput().length() == 0) { throw new CompilerException("Unknown error trying to execute the external compiler: " + EOL + cli.toString()); } else { messages.add(new CompilerError("Failure executing javac, but could not parse the error:" + EOL + err.getOutput(), true)); } } return messages; } private File createFileWithArguments(String[] args) throws IOException { PrintWriter writer = null; try { File tempFile = File.createTempFile(JavacCompiler.class.getName(), "arguments"); tempFile.deleteOnExit(); writer = new PrintWriter(new FileWriter(tempFile)); for (int i = 0; i < args.length; i++) { String argValue = args[i].replace(File.separatorChar, '/'); writer.write("\"" + argValue + "\""); writer.write(EOL); } writer.flush(); return tempFile; } finally { if (writer != null) { writer.close(); } } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/AptMojo.java000066400000000000000000000021371165203002500262720ustar00rootroot00000000000000// TAKEN FROM GLASSFISH. TODO: FIND CDDL HEADER package org.kohsuke.stapler; import org.apache.maven.plugin.CompilationFailureException; import org.apache.maven.plugin.MojoExecutionException; import java.lang.reflect.Field; /** * @goal apt-compile * @phase compile * @requiresDependencyResolution compile * @author Kohsuke Kawaguchi */ public class AptMojo extends CompilerMojo { public void execute() throws MojoExecutionException, CompilationFailureException { // overwrite the compilerId value. This seems to be the only way to //do so without touching the copied files. setField("compilerId", "stapler-apt"); super.execute(); } private void setField(String name, String value) { try { Field field = AbstractCompilerMojo.class.getDeclaredField(name); field.setAccessible(true); field.set(this, value); } catch (NoSuchFieldException e) { throw new AssertionError(e); // impossible } catch (IllegalAccessException e) { throw new AssertionError(e); // impossible } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/CompilerMojo.java000066400000000000000000000101651165203002500273200ustar00rootroot00000000000000// COPIED FROM MAVEN: DO NOT MODIFY package org.kohsuke.stapler; /* * Copyright 2001-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.CompilationFailureException; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Compiles application sources * * @author Jason van Zyl * @version $Id: CompilerMojo.java 383 2007-08-19 17:12:03Z kohsuke $ * @phase compile * @requiresDependencyResolution compile */ public class CompilerMojo extends AbstractCompilerMojo { /** * The source directories containing the sources to be compiled. * * @parameter expression="${project.compileSourceRoots}" * @required * @readonly */ private List compileSourceRoots; /** * Project classpath. * * @parameter expression="${project.compileClasspathElements}" * @required * @readonly */ private List classpathElements; /** * The directory for compiled classes. * * @parameter expression="${project.build.outputDirectory}" * @required * @readonly */ private File outputDirectory; /** * Project artifacts. * * @parameter expression="${project.artifact}" * @required * @readonly * @todo this is an export variable, really */ private Artifact projectArtifact; /** * A list of inclusion filters for the compiler. * * @parameter */ private Set includes = new HashSet(); /** * A list of exclusion filters for the compiler. * * @parameter */ private Set excludes = new HashSet(); protected List getCompileSourceRoots() { return compileSourceRoots; } protected List getClasspathElements() { return classpathElements; } protected File getOutputDirectory() { return outputDirectory; } public void execute() throws MojoExecutionException, CompilationFailureException { super.execute(); projectArtifact.setFile( outputDirectory ); } protected SourceInclusionScanner getSourceInclusionScanner( int staleMillis ) { SourceInclusionScanner scanner = null; if ( includes.isEmpty() && excludes.isEmpty() ) { scanner = new StaleSourceScanner( staleMillis ); } else { if ( includes.isEmpty() ) { includes.add( "**/*.java" ); } scanner = new StaleSourceScanner( staleMillis, includes, excludes ); } return scanner; } protected SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding ) { SourceInclusionScanner scanner = null; if ( includes.isEmpty() && excludes.isEmpty() ) { includes = Collections.singleton( "**/*." + inputFileEnding ); scanner = new SimpleSourceInclusionScanner( includes, Collections.EMPTY_SET ); } else { if ( includes.isEmpty() ) { includes.add( "**/*." + inputFileEnding ); } scanner = new SimpleSourceInclusionScanner( includes, excludes ); } return scanner; } }maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/ConstructorProcessor.java000066400000000000000000000073601165203002500311510ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.Filer.Location; import com.sun.mirror.declaration.ClassDeclaration; import com.sun.mirror.declaration.ConstructorDeclaration; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeDeclaration; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; /** * Handles {@link DataBoundConstructor} annotation and captures parameter names. * * @author Kohsuke Kawaguchi * @deprecated * Requiring 1.6 for development-time. Annotation processing is now a part of the core stapler. */ public class ConstructorProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; public ConstructorProcessor(AnnotationProcessorEnvironment env) { this.env = env; } public void process() { try { for( TypeDeclaration d : env.getTypeDeclarations() ) { if(!(d instanceof ClassDeclaration)) continue; ClassDeclaration cd = (ClassDeclaration) d; for( ConstructorDeclaration c : cd.getConstructors()) { if(c.getAnnotation(DataBoundConstructor.class)!=null) { write(c); continue; } String javadoc = c.getDocComment(); if(javadoc!=null && javadoc.contains("@stapler-constructor")) { write(c); } } } } catch (IOException e) { env.getMessager().printError(e.getMessage()); } } private void write(ConstructorDeclaration c) throws IOException { StringBuffer buf = new StringBuffer(); for( ParameterDeclaration p : c.getParameters() ) { if(buf.length()>0) buf.append(','); buf.append(p.getSimpleName()); } File f = new File(c.getDeclaringType().getQualifiedName().replace('.', '/') + ".stapler"); env.getMessager().printNotice("Generating "+f); OutputStream os = env.getFiler().createBinaryFile(Location.CLASS_TREE,"", f); Properties p = new Properties(); p.put("constructor",buf.toString()); p.store(os,null); os.close(); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/ConstructorProcessor6.java000066400000000000000000000045661165203002500312440ustar00rootroot00000000000000package org.kohsuke.stapler; import org.kohsuke.MetaInfServices; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.util.ElementScanner6; import java.io.IOException; import java.util.Properties; import java.util.Set; /** * @author Kohsuke Kawaguchi */ @SuppressWarnings({"Since15"}) @SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) public class ConstructorProcessor6 extends AbstractProcessorImpl { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { ElementScanner6 scanner = new ElementScanner6() { @Override public Void visitExecutable(ExecutableElement e, Void aVoid) { if(e.getAnnotation(DataBoundConstructor.class)!=null) { write(e); } else { String javadoc = getJavadoc(e); if(javadoc!=null && javadoc.contains("@stapler-constructor")) { write(e); } } return super.visitExecutable(e, aVoid); } }; for( Element e : roundEnv.getRootElements() ) scanner.scan(e,null); return false; } private void write(ExecutableElement c) { try { StringBuilder buf = new StringBuilder(); for( VariableElement p : c.getParameters() ) { if(buf.length()>0) buf.append(','); buf.append(p.getSimpleName()); } TypeElement t = (TypeElement) c.getEnclosingElement(); String name = t.getQualifiedName().toString().replace('.', '/') + ".stapler"; notice("Generating " + name, c); Properties p = new Properties(); p.put("constructor",buf.toString()); writePropertyFile(p, name); } catch (IOException x) { error(x.toString()); } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/ExportedBeanAnnotationProcessor.java000066400000000000000000000200261165203002500332310ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.Filer.Location; import com.sun.mirror.declaration.AnnotationTypeDeclaration; import com.sun.mirror.declaration.Declaration; import com.sun.mirror.declaration.FieldDeclaration; import com.sun.mirror.declaration.MemberDeclaration; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.TypeDeclaration; import com.sun.mirror.util.SimpleDeclarationVisitor; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.TreeSet; /** * Handles {@link ExportedBean} and {@link Exported} annotations. * * @author Kohsuke Kawaguchi * @deprecated * Requiring 1.6 for development-time. Annotation processing is now a part of the core stapler. */ public class ExportedBeanAnnotationProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; public ExportedBeanAnnotationProcessor(AnnotationProcessorEnvironment env) { this.env = env; } public void process() { try { File out = new File(env.getOptions().get("-d")); AnnotationTypeDeclaration $exposed = (AnnotationTypeDeclaration) env.getTypeDeclaration(Exported.class.getName()); // collect all exposed properties Map> props = new HashMap>(); for( Declaration d : env.getDeclarationsAnnotatedWith($exposed)) { MemberDeclaration md = (MemberDeclaration) d; TypeDeclaration owner = md.getDeclaringType(); List list = props.get(owner); if(list==null) props.put(owner,list=new ArrayList()); list.add(md); } File beans = new File(out,"META-INF/exposed.stapler-beans"); Set exposedBeanNames = new TreeSet(); if(beans.exists()) { BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(beans))); String line; while((line=in.readLine())!=null) exposedBeanNames.add(line.trim()); in.close(); } for (Entry> e : props.entrySet()) { exposedBeanNames.add(e.getKey().getQualifiedName()); final Properties javadocs = new Properties(); for (MemberDeclaration md : e.getValue()) { md.accept(new SimpleDeclarationVisitor() { public void visitFieldDeclaration(FieldDeclaration f) { String javadoc = f.getDocComment(); if(javadoc!=null) javadocs.put(f.getSimpleName(), javadoc); } public void visitMethodDeclaration(MethodDeclaration m) { String javadoc = m.getDocComment(); if(javadoc!=null) javadocs.put(m.getSimpleName()+"()", javadoc); } // way too tedious. //private String getSignature(MethodDeclaration m) { // final StringBuilder buf = new StringBuilder(m.getSimpleName()); // buf.append('('); // boolean first=true; // for (ParameterDeclaration p : m.getParameters()) { // if(first) first = false; // else buf.append(','); // p.getType().accept(new SimpleTypeVisitor() { // public void visitPrimitiveType(PrimitiveType pt) { // buf.append(pt.getKind().toString().toLowerCase()); // } // public void visitDeclaredType(DeclaredType dt) { // buf.append(dt.getDeclaration().getQualifiedName()); // } // // public void visitArrayType(ArrayType at) { // at.getComponentType().accept(this); // buf.append("[]"); // } // // public void visitTypeVariable(TypeVariable tv) { // // // TODO // super.visitTypeVariable(typeVariable); // } // // public void visitVoidType(VoidType voidType) { // // TODO // super.visitVoidType(voidType); // } // }); // } // buf.append(')'); // // TODO // return null; //} }); } File javadocFile = new File(e.getKey().getQualifiedName().replace('.', '/') + ".javadoc"); env.getMessager().printNotice("Generating "+javadocFile); OutputStream os = env.getFiler().createBinaryFile(Location.CLASS_TREE,"", javadocFile); try { javadocs.store(os,null); } finally { os.close(); } } beans.getParentFile().mkdirs(); PrintWriter w = new PrintWriter(new OutputStreamWriter(new FileOutputStream(beans),"UTF-8")); for (String beanName : exposedBeanNames) w.println(beanName); w.close(); } catch (IOException x) { env.getMessager().printError(x.toString()); } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/ExportedBeanAnnotationProcessor6.java000066400000000000000000000137021165203002500333220ustar00rootroot00000000000000package org.kohsuke.stapler; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Multimap; import org.kohsuke.MetaInfServices; import org.kohsuke.stapler.export.Exported; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.Collection; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.TreeSet; /** * @author Kohsuke Kawaguchi */ @SuppressWarnings({"Since15"}) @SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) public class ExportedBeanAnnotationProcessor6 extends AbstractProcessorImpl { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { try { if (roundEnv.processingOver()) { return false; } // collect all exposed properties Multimap props = LinkedListMultimap.create(); for (Element exported : roundEnv.getElementsAnnotatedWith(Exported.class)) { props.put((TypeElement)exported.getEnclosingElement(), exported); } Set exposedBeanNames = scanExisting(); for (Entry> e : props.asMap().entrySet()) { exposedBeanNames.add(e.getKey().getQualifiedName().toString()); final Properties javadocs = new Properties(); for (Element md : e.getValue()) { switch (md.getKind()) { case FIELD: case METHOD: String javadoc = getJavadoc(md); if(javadoc!=null) javadocs.put(md.getSimpleName().toString(), javadoc); break; default: throw new AssertionError("Unexpected element type: "+md); } // TODO: possibly a proper method signature generation, but it's too tedious // way too tedious. //private String getSignature(MethodDeclaration m) { // final StringBuilder buf = new StringBuilder(m.getSimpleName()); // buf.append('('); // boolean first=true; // for (ParameterDeclaration p : m.getParameters()) { // if(first) first = false; // else buf.append(','); // p.getType().accept(new SimpleTypeVisitor() { // public void visitPrimitiveType(PrimitiveType pt) { // buf.append(pt.getKind().toString().toLowerCase()); // } // public void visitDeclaredType(DeclaredType dt) { // buf.append(dt.getDeclaration().getQualifiedName()); // } // // public void visitArrayType(ArrayType at) { // at.getComponentType().accept(this); // buf.append("[]"); // } // // public void visitTypeVariable(TypeVariable tv) { // // // TODO // super.visitTypeVariable(typeVariable); // } // // public void visitVoidType(VoidType voidType) { // // TODO // super.visitVoidType(voidType); // } // }); // } // buf.append(')'); // // TODO // return null; //} } String javadocFile = e.getKey().getQualifiedName().toString().replace('.', '/') + ".javadoc"; notice("Generating "+ javadocFile, e.getKey()); writePropertyFile(javadocs, javadocFile); } FileObject beans = createResource(STAPLER_BEAN_FILE); PrintWriter w = new PrintWriter(new OutputStreamWriter(beans.openOutputStream(),"UTF-8")); for (String beanName : exposedBeanNames) w.println(beanName); w.close(); } catch (IOException x) { error(x.toString()); } return false; } private Set scanExisting() throws IOException { Set exposedBeanNames = new TreeSet(); FileObject beans = getResource(STAPLER_BEAN_FILE); try { BufferedReader in = new BufferedReader(new InputStreamReader(beans.openInputStream(),"UTF-8")); String line; while((line=in.readLine())!=null) exposedBeanNames.add(line.trim()); in.close(); } catch (FileNotFoundException e) { // no existing file, which is fine } return exposedBeanNames; } private static final String STAPLER_BEAN_FILE = "META-INF/exposed.stapler-beans"; } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/L10nProgress.java000066400000000000000000000137271165203002500271670ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.Collection; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Represents the progress of l10n effort. * * @author ssogabe * @see http://d.hatena.ne.jp/ssogabe/20081213/1229175653 */ public class L10nProgress { /** * Locales used in the set of files parsed. */ private final Set locales = new TreeSet(); private final List messages = new ArrayList(); /** * Information per directory. */ public final class HudsonMessages { private final File dir; private final Map map = new HashMap(); public HudsonMessages(final File dir) { this.dir = dir; } public String getDirectoryName() { return dir.getName(); } private void setCnt(final String locale, final int cnt) { map.put(locale, cnt); } public int getCnt(final String locale) { final Integer cnt = map.get(locale); return cnt != null ? cnt : 0; } /** * Gets the ratio of localization against the default locale. */ public int ratio(String locale) { return (int) (((double) getCnt(locale) / getCnt("")) * 100); } /** * Dumps this object as a row in the Hatena diary format. */ public void toHatena(StringBuilder b) { b.append("|").append(getDirectoryName()).append("(").append(getCnt("")).append(") |"); for (final String locale : locales) { b.append(getCnt(locale)).append("(").append(ratio(locale)).append("%)|"); } b.append("\n"); } } /** * Gets the pseudo {@link HudsonMessages} that represents the sum of all {@link #messages}. */ public HudsonMessages getTotal() { HudsonMessages sum = new HudsonMessages(new File("total")); ArrayList localesPlusOne = new ArrayList(locales); localesPlusOne.add(""); for (String locale : localesPlusOne) { int cnt=0; for (HudsonMessages m : messages) cnt += m.getCnt(locale); sum.setCnt(locale,cnt); } return sum; } /** * Returns the number of entries in the given property file. */ private int getMessageCnt(final File file) { final Properties props = new Properties(); int cnt = 0; try { props.load(new FileInputStream(file)); cnt = props.size(); } catch (final IOException e) { e.printStackTrace(); } return cnt; } /** * Prints the result in the Hatena diary table format. */ public String toHatena() { final StringBuilder b = new StringBuilder(); // header b.append("|*Messages(#)|"); for (final String locale : locales) { b.append("*").append(locale).append("|"); } b.append("\n"); for (final HudsonMessages m : messages) m.toHatena(b); getTotal().toHatena(b); return b.toString(); } public void parse(File dir) { final HudsonMessages m = new HudsonMessages(dir); final File[] files = dir.listFiles(); for (final File f : files) { final Matcher matcher = FILENAME_PATTERN.matcher(f.getName()); if (matcher.matches()) { final String locale = matcher.group(1); if (!locale.equals("")) { locales.add(locale); } m.setCnt(locale, getMessageCnt(f)); } } messages.add(m); } public void parse(Collection dirs) { for (final File dir : dirs) parse(dir); } /** * Parse the given directory and all its descendants. */ public void parseRecursively(final File dir) { for (final File f : dir.listFiles()) { if (f.isDirectory()) { parseRecursively(f); } else if (f.isFile() && MESSAGES_FILE.equals(f.getName())) { parse(f.getParentFile()); } } } private static final String MESSAGES_FILE = "Messages.properties"; private static final Pattern FILENAME_PATTERN = Pattern.compile("^Messages_?([a-zA-Z_]*)\\.properties$"); } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/LocalizerMojo.java000066400000000000000000000256201165203002500274740ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.maven.model.Resource; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import java.util.regex.Matcher; /** * Alias for stapler:l10n mojo. Left for compatibility. * * @author Kohsuke Kawaguchi * @goal i18n */ public class LocalizerMojo extends AbstractMojo { /** * The locale to generate properties for. * * @parameter expression="${locale}" * @required */ protected String locale; /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; public void execute() throws MojoExecutionException, MojoFailureException { // create parser try { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); parser = spf.newSAXParser(); } catch (SAXException e) { throw new Error(e); // impossible } catch (ParserConfigurationException e) { throw new Error(e); // impossible } for( Resource res : (List)project.getResources() ) { File dir = new File(res.getDirectory()); processDirectory(dir); } } private void process(File file) throws MojoExecutionException { if(file.isDirectory()) processDirectory(file); else if(file.getName().endsWith(".jelly")) processJelly(file); } private void processDirectory(File dir) throws MojoExecutionException { File[] children = dir.listFiles(); if(children==null) return; for (File child : children) process(child); } private void processJelly(File file) throws MojoExecutionException { Set props = findAllProperties(file); if(props.isEmpty()) return; // nothing to generate here. String fileName = file.getName(); fileName=fileName.substring(0,fileName.length()-".jelly".length()); fileName+='_'+locale+".properties"; File resourceFile = new File(file.getParentFile(),fileName); if(resourceFile.exists()) { Properties resource; try { resource = new Properties(resourceFile); } catch (IOException e) { throw new MojoExecutionException("Failed to read "+resourceFile,e); } // find unnecessary properties = those which are present in the resource file but not in Jelly HashSet unnecessaries = new HashSet((Set) resource.keySet()); unnecessaries.removeAll(props); for (String s : unnecessaries) getLog().warn("Unused property "+s+" in "+resourceFile); // figure out missing properties props.removeAll(resource.keySet()); // add NL to the end if necessary try { // then add them to the end RandomAccessFile f = new RandomAccessFile(resourceFile,"rw"); if(f.length()>0) { // add the terminating line end if needed f.seek(f.length()-1); int ch = f.read(); if(!(ch=='\r' || ch=='\n')) f.write(System.getProperty("line.separator").getBytes()); } f.close(); } catch (IOException e) { throw new MojoExecutionException("Failed to write "+resourceFile,e); } } if(props.isEmpty()) return; // no change to make getLog().info("Updating "+resourceFile); try { // then add them to the end RandomAccessFile f = new RandomAccessFile(resourceFile,"rw"); if(f.length()>0) { // add the terminating line end if needed f.seek(f.length()-1); int ch = f.read(); if(!(ch=='\r' || ch=='\n')) f.write(System.getProperty("line.separator").getBytes()); } f.close(); PrintWriter w = new PrintWriter(new FileWriter(resourceFile,true)); for (String p : props) { w.println(escape(p)+"="); } w.close(); } catch (IOException e) { throw new MojoExecutionException("Failed to write "+resourceFile,e); } } /** * Escapes the property key in the proper format. */ private String escape(String key) { StringBuilder buf = new StringBuilder(key.length()); for( int i=0; i findAllProperties(File file) throws MojoExecutionException { getLog().debug("Parsing "+file); try { // we'd like to preserve order, but don't want duplicates final Set properties = new LinkedHashSet(); parser.parse(file,new DefaultHandler() { private final StringBuilder buf = new StringBuilder(); private Locator locator; public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { findExpressions(); for( int i=0; i=0) exp=exp.substring(0,op); properties.add(exp); } else { Matcher m = RESOURCE_LITERAL_STRING.matcher(exp); while(m.find()) { String literal = m.group(); getLog().debug("Found "+literal); literal = literal.substring(2,literal.length()-1); // unquote and remove '%' // if parameters follow, remove them int op = literal.indexOf('('); if(op>=0) literal=literal.substring(0,op); properties.add(literal); } } } }); return properties; } catch (SAXException e) { throw new MojoExecutionException("Failed to parse "+file, e); } catch (IOException e) { throw new MojoExecutionException("Failed to parse "+file, e); } } SAXParser parser; // "%...." string literal that starts with '%' private static final Pattern RESOURCE_LITERAL_STRING = Pattern.compile("(\"%[^\"]+\")|('%[^']+')"); } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/LocalizerMojo2.java000066400000000000000000000030351165203002500275520ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; /** * Generate localized message bundles. * * @author Kohsuke Kawaguchi * @goal l10n */ public class LocalizerMojo2 extends LocalizerMojo { } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/LocalizerProgressMojo.java000066400000000000000000000045511165203002500312210ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import java.io.File; import java.util.Collection; /** * Prints out the progress of localization. * * @author ssogabe * @see http://d.hatena.ne.jp/ssogabe/20081213/1229175653 * @goal l10n-progress */ public class LocalizerProgressMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; public void execute() throws MojoExecutionException, MojoFailureException { L10nProgress r = new L10nProgress(); for( Resource root : (Collection)project.getResources() ) { r.parseRecursively(new File(root.getDirectory())); } System.out.println(r.toHatena()); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/Properties.java000066400000000000000000000035431165203002500270570ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import java.io.File; import java.io.FileInputStream; import java.io.IOException; /** * @author Kohsuke Kawaguchi */ public class Properties extends java.util.Properties { public Properties() { super(); } /** * Loads from the file. */ public Properties(File src) throws IOException { FileInputStream in = new FileInputStream(src); try { load(in); } finally { in.close(); } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/QueryParameterAnnotationProcessor.java000066400000000000000000000072471165203002500336310ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.apt.Filer.Location; import com.sun.mirror.declaration.ClassDeclaration; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeDeclaration; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.IOException; import java.io.OutputStream; /** * Handles {@link QueryParameter} annotation and captures parameter names. * @author Kohsuke Kawaguchi * @deprecated * Requiring 1.6 for development-time. Annotation processing is now a part of the core stapler. */ public class QueryParameterAnnotationProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; public QueryParameterAnnotationProcessor(AnnotationProcessorEnvironment env) { this.env = env; } public void process() { try { for( TypeDeclaration d : env.getTypeDeclarations() ) { if(!(d instanceof ClassDeclaration)) continue; ClassDeclaration cd = (ClassDeclaration) d; for( MethodDeclaration m : cd.getMethods()) { if(hasQueryParameterAnnotation(m)) write(m); } } } catch (IOException e) { env.getMessager().printError(e.getMessage()); } } private boolean hasQueryParameterAnnotation(MethodDeclaration m) { for (ParameterDeclaration p : m.getParameters()) if(p.getAnnotation(QueryParameter.class)!=null) return true; return false; } private void write(MethodDeclaration m) throws IOException { StringBuffer buf = new StringBuffer(); for( ParameterDeclaration p : m.getParameters() ) { if(buf.length()>0) buf.append(','); buf.append(p.getSimpleName()); } File f = new File(m.getDeclaringType().getQualifiedName().replace('.', '/')+"/"+m.getSimpleName()+ ".stapler"); env.getMessager().printNotice("Generating "+f); OutputStream os = env.getFiler().createBinaryFile(Location.CLASS_TREE,"", f); IOUtils.write(buf,os,"UTF-8"); os.close(); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/QueryParameterAnnotationProcessor6.java000066400000000000000000000044251165203002500337120ustar00rootroot00000000000000package org.kohsuke.stapler; import org.apache.commons.io.IOUtils; import org.kohsuke.MetaInfServices; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.tools.FileObject; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import java.util.Set; /** * @author Kohsuke Kawaguchi */ @SuppressWarnings({"Since15"}) @SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) public class QueryParameterAnnotationProcessor6 extends AbstractProcessorImpl { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { try { Set params = roundEnv.getElementsAnnotatedWith(QueryParameter.class); Set methods = new HashSet(); for (Element p : params) methods.add((ExecutableElement)p.getEnclosingElement()); for (ExecutableElement m : methods) { write(m); } } catch (IOException e) { error(e.getMessage()); } return false; } /** * @param m * Method whose parameter has {@link QueryParameter} */ private void write(ExecutableElement m) throws IOException { StringBuffer buf = new StringBuffer(); for( VariableElement p : m.getParameters() ) { if(buf.length()>0) buf.append(','); buf.append(p.getSimpleName()); } TypeElement t = (TypeElement)m.getEnclosingElement(); FileObject f = createResource(t.getQualifiedName().toString().replace('.', '/') + "/" + m.getSimpleName() + ".stapler"); notice("Generating " + f, m); OutputStream os = f.openOutputStream(); try { IOUtils.write(buf, os, "UTF-8"); } finally { os.close(); } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/StaplerMojo.java000066400000000000000000000104761165203002500271650ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.thoughtworks.qdox.JavaDocBuilder; import com.thoughtworks.qdox.model.JavaClass; import com.thoughtworks.qdox.model.JavaMethod; import com.thoughtworks.qdox.model.JavaParameter; import com.thoughtworks.qdox.model.JavaSource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; /** * Looks for '@stapler-constructor' on a constructor. * * @author Kohsuke Kawaguchi * @goal stapler * @phase generate-resources * @deprecated replaced by the apt mojo. */ public class StaplerMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * The directory to place generated property files. * * @parameter expression="${project.build.outputDirectory}" * @required * @readonly */ protected File classesDirectory; public void execute() throws MojoExecutionException, MojoFailureException { try { // parse the source JavaDocBuilder builder = new JavaDocBuilder(); for (Object o : project.getCompileSourceRoots()) builder.addSourceTree(new File((String) o)); // look for a constructor that has '@stapler-constructor' for( JavaSource js : builder.getSources() ) { for (JavaClass jc : js.getClasses()) { for( JavaMethod jm : jc.getMethods() ) { if(jm.getTagByName("stapler-constructor")!=null) { if(!jm.isConstructor()) throw new MojoExecutionException( jc.getFullyQualifiedName()+'#'+jm.getName()+" is not a constructor"); StringBuffer buf = new StringBuffer(); for( JavaParameter p : jm.getParameters() ) { if(buf.length()>0) buf.append(','); buf.append(p.getName()); } File dst = new File(classesDirectory,jc.getFullyQualifiedName().replace('.',File.separatorChar)+".stapler"); dst.getParentFile().mkdirs(); OutputStream os = new FileOutputStream(dst); Properties p = new Properties(); p.put("constructor",buf.toString()); p.store(os,null); } } } } } catch (IOException e) { throw new MojoExecutionException("Failed to process @stapler-constructor",e); } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/TaglibDocMojo.java000066400000000000000000000244371165203002500274050ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import com.sun.xml.txw2.TXW; import com.sun.xml.txw2.output.StreamSerializer; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.reporting.MavenReport; import org.apache.maven.reporting.MavenReportException; import org.codehaus.doxia.sink.Sink; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentFactory; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.jvnet.maven.jellydoc.Attribute; import org.jvnet.maven.jellydoc.JellydocMojo; import org.jvnet.maven.jellydoc.Library; import org.jvnet.maven.jellydoc.Tag; import org.jvnet.maven.jellydoc.Tags; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; /** * Scans Jelly tag libraries from tag files, and generate taglib.xml * compatible with maven-jellydoc-plugin * *

* For productive debugging of this mojo, run "mvn site:run" with debugger. * Every request will trigger a whole rendering, and you can do hot-swap of * byte code for changes. * * @author Kohsuke Kawaguchi * @goal jelly-taglibdoc * @phase generate-sources * @requiresDependencyResolution compile */ public class TaglibDocMojo extends AbstractMojo implements MavenReport { /** * The Maven Project Object * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * The plugin dependencies. * * @parameter expression="${plugin.artifacts}" * @required * @readonly */ private List pluginArtifacts; /** * Version of this plugin. * * @parameter expression="${plugin.version}" * @required * @readonly */ private String pluginVersion; /** * Regular expression for taglib URIs. If specified, * only those taglibs that match these patterns will be generated into * documentation. * * @parameter expression="${patterns}" */ private String[] patterns = new String[]{".*"}; /** * Factory for creating artifact objects * * @component */ private ArtifactFactory factory; /** * Used for resolving artifacts * * @component */ private ArtifactResolver resolver; /** * The local repository where the artifacts are located. * * @parameter expression="${localRepository}" */ private ArtifactRepository localRepository; /** * @component */ private MavenProjectHelper helper; private JellydocMojo jellydoc; public void execute() throws MojoExecutionException, MojoFailureException { writeTaglibXml(); getJellydocMojo().generateSchema(); } private JellydocMojo getJellydocMojo() { if(jellydoc==null) { jellydoc = new JellydocMojo() { @Override public void execute() throws MojoExecutionException, MojoFailureException { TaglibDocMojo.this.execute(); } }; jellydoc.factory = factory; jellydoc.helper = helper; jellydoc.localRepository = localRepository; jellydoc.project = project; jellydoc.resolver = resolver; } return jellydoc; } private void writeTaglibXml() throws MojoExecutionException { try { File taglibsXml = new File(project.getBasedir(), "target/taglib.xml"); taglibsXml.getParentFile().mkdirs(); Tags tags = TXW.create(Tags.class,new StreamSerializer(new FileOutputStream(taglibsXml))); for(Resource res : (List)project.getResources()) scanTagLibs(new File(res.getDirectory()),"",tags); tags.commit(); } catch (IOException e) { throw new MojoExecutionException("Failed to generate taglibs.xml",e); } } /** * Recurisely search for taglibs and call {@link #parseTagLib(File, String, Library)}. */ private void scanTagLibs(File dir, String uri, Tags tags) throws IOException { if(new File(dir,"taglib").exists()) { boolean match = patterns.length==0; for (String p : patterns) { if(Pattern.matches(p,uri)) { match = true; break; } } if(match) parseTagLib(dir,uri,tags.library()); } // scan subdirs File[] subdirs = dir.listFiles(new FileFilter() { public boolean accept(File f) { return f.isDirectory(); } }); if(subdirs==null) return; for (File subdir : subdirs) scanTagLibs(subdir,uri+'/'+subdir.getName(), tags); } private void parseTagLib(File dir, String uri, Library lib) throws IOException { getLog().info("Processing "+dir); List markerFile = FileUtils.readLines(new File(dir, "taglib")); if(markerFile.size()==0) markerFile.add(uri); // write the attributes lib.name(markerFile.get(0).toString()); lib.prefix(uri.substring(uri.lastIndexOf('/')+1)).uri(uri); // doc lib.doc()._pcdata(join(markerFile)); File[] tagFiles = dir.listFiles(new FileFilter() { public boolean accept(File f) { return f.getName().endsWith(".jelly"); } }); if(tagFiles==null) return; for (File tagFile : tagFiles) parseTagFile(tagFile,lib.tag()); } /** * Parses a given tag file and writes to {@link Tag}. */ private void parseTagFile(File tagFile, Tag tag) throws IOException { try { String name = tagFile.getName(); name = name.substring(0,name.length()-6); // cut off ".jelly" tag.name(name); DocumentFactory f = new DocumentFactory(); f.setXPathNamespaceURIs(NAMESPACE_MAP); Document jelly = new SAXReader(f).read(tagFile); Element doc = (Element) jelly.selectSingleNode(".//s:documentation"); // does this tag have a body? if(jelly.selectSingleNode("//d:invokeBody")==null) tag.noContent(true); if(doc==null) { tag.doc(""); } else { tag.doc(doc.getText()); for(Element attr : (List)doc.selectNodes("s:attribute")) { Attribute aw = tag.attribute(); for (org.dom4j.Attribute a : (List)attr.attributes()) aw._attribute(a.getName(),a.getValue()); aw.doc(attr.getText()); } } } catch (DocumentException e) { IOException x = new IOException("Failed to parse " + tagFile); x.initCause(e); throw x; } } private String join(List list) { StringBuilder buf = new StringBuilder(); for (Object item : list) { if(buf.length()>0) buf.append('\n'); buf.append(item); } return buf.toString(); } // // MavenReport implementation // public void generate(Sink sink, Locale locale) throws MavenReportException { getJellydocMojo().generate(sink,locale); } public String getOutputName() { return getJellydocMojo().getOutputName(); } public String getName(Locale locale) { return getJellydocMojo().getName(locale); } public String getCategoryName() { return getJellydocMojo().getCategoryName(); } public String getDescription(Locale locale) { return getJellydocMojo().getDescription(locale); } public void setReportOutputDirectory(File outputDirectory) { getJellydocMojo().setReportOutputDirectory(outputDirectory); } public File getReportOutputDirectory() { return getJellydocMojo().getReportOutputDirectory(); } public boolean isExternalReport() { return getJellydocMojo().isExternalReport(); } public boolean canGenerateReport() { return getJellydocMojo().canGenerateReport(); } private static final Map NAMESPACE_MAP = new HashMap(); static { NAMESPACE_MAP.put("s", "jelly:stapler"); NAMESPACE_MAP.put("d", "jelly:define"); } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/TestAptMojo.java000066400000000000000000000046511165203002500271350ustar00rootroot00000000000000/* * Copyright (c) 2004-2010, Kohsuke Kawaguchi * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.kohsuke.stapler; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.CompilationFailureException; import java.lang.reflect.Field; /** * @goal apt-test-compile * @phase test-compile * @requiresDependencyResolution test * @author Kohsuke Kawaguchi */ public class TestAptMojo extends TestCompilerMojo { public void execute() throws MojoExecutionException, CompilationFailureException { // overwrite the compilerId value. This seems to be the only way to //do so without touching the copied files. setField("compilerId", "stapler-apt"); super.execute(); } private void setField(String name, String value) { try { Field field = AbstractCompilerMojo.class.getDeclaredField(name); field.setAccessible(true); field.set(this, value); } catch (NoSuchFieldException e) { throw new AssertionError(e); // impossible } catch (IllegalAccessException e) { throw new AssertionError(e); // impossible } } } maven-stapler-plugin-1.16/src/main/java/org/kohsuke/stapler/TestCompilerMojo.java000066400000000000000000000106431165203002500301610ustar00rootroot00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.kohsuke.stapler; import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner; import org.apache.maven.plugin.CompilationFailureException; import org.apache.maven.plugin.MojoExecutionException; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Compiles application test sources * * @author Jason van Zyl * @version $Id: TestCompilerMojo.java 670 2008-06-28 00:28:29Z kohsuke $ * @phase test-compile * @requiresDependencyResolution test */ public class TestCompilerMojo extends AbstractCompilerMojo { /** * Set this to 'true' to bypass unit tests entirely. * Its use is NOT RECOMMENDED, but quite convenient on occasion. * * @parameter expression="${maven.test.skip}" */ private boolean skip; /** * The source directories containing the test-source to be compiled. * * @parameter expression="${project.testCompileSourceRoots}" * @required * @readonly */ private List compileSourceRoots; /** * Project test classpath. * * @parameter expression="${project.testClasspathElements}" * @required * @readonly */ private List classpathElements; /** * The directory where compiled test classes go. * * @parameter expression="${project.build.testOutputDirectory}" * @required * @readonly */ private File outputDirectory; /** * A list of inclusion filters for the compiler. * * @parameter */ private Set testIncludes = new HashSet(); /** * A list of exclusion filters for the compiler. * * @parameter */ private Set testExcludes = new HashSet(); public void execute() throws MojoExecutionException, CompilationFailureException { if ( skip ) { getLog().info( "Not compiling test sources" ); } else { super.execute(); } } protected List getCompileSourceRoots() { return compileSourceRoots; } protected List getClasspathElements() { return classpathElements; } protected File getOutputDirectory() { return outputDirectory; } protected SourceInclusionScanner getSourceInclusionScanner( int staleMillis ) { SourceInclusionScanner scanner = null; if ( testIncludes.isEmpty() && testExcludes.isEmpty() ) { scanner = new StaleSourceScanner( staleMillis ); } else { if ( testIncludes.isEmpty() ) { testIncludes.add( "**/*.java" ); } scanner = new StaleSourceScanner( staleMillis, testIncludes, testExcludes ); } return scanner; } protected SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding ) { SourceInclusionScanner scanner = null; if ( testIncludes.isEmpty() && testExcludes.isEmpty() ) { testIncludes = Collections.singleton( "**/*." + inputFileEnding ); scanner = new SimpleSourceInclusionScanner( testIncludes, Collections.EMPTY_SET ); } else { if ( testIncludes.isEmpty() ) { testIncludes.add( "**/*." + inputFileEnding ); } scanner = new SimpleSourceInclusionScanner( testIncludes, testExcludes ); } return scanner; } } maven-stapler-plugin-1.16/src/main/resources/000077500000000000000000000000001165203002500212325ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/resources/META-INF/000077500000000000000000000000001165203002500223725ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/resources/META-INF/plexus/000077500000000000000000000000001165203002500237125ustar00rootroot00000000000000maven-stapler-plugin-1.16/src/main/resources/META-INF/plexus/components.xml000066400000000000000000000075711165203002500266330ustar00rootroot00000000000000 org.apache.maven.lifecycle.mapping.LifecycleMapping stapler-jar org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping default org.apache.maven.plugins:maven-resources-plugin:resources org.kohsuke.stapler:maven-stapler-plugin:apt-compile org.apache.maven.plugins:maven-resources-plugin:testResources org.kohsuke.stapler:maven-stapler-plugin:apt-test-compile org.apache.maven.plugins:maven-surefire-plugin:test org.apache.maven.plugins:maven-jar-plugin:jar org.apache.maven.plugins:maven-install-plugin:install org.apache.maven.plugins:maven-deploy-plugin:deploy org.apache.maven.lifecycle.mapping.LifecycleMapping stapler-war org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping default org.apache.maven.plugins:maven-resources-plugin:resources org.kohsuke.stapler:maven-stapler-plugin:apt-compile org.apache.maven.plugins:maven-resources-plugin:testResources org.kohsuke.stapler:maven-stapler-plugin:apt-test-compile org.apache.maven.plugins:maven-surefire-plugin:test org.apache.maven.plugins:maven-war-plugin:war org.apache.maven.plugins:maven-install-plugin:install org.apache.maven.plugins:maven-deploy-plugin:deploy org.apache.maven.artifact.handler.ArtifactHandler stapler-jar org.apache.maven.artifact.handler.DefaultArtifactHandler jar stapler-jar stapler-jar java true org.apache.maven.artifact.handler.ArtifactHandler stapler-war org.apache.maven.artifact.handler.DefaultArtifactHandler war stapler-war stapler-war java false org.codehaus.plexus.compiler.Compiler stapler-apt org.kohsuke.stapler.AptCompiler