diff --git a/0001-Port-to-JSR-269.patch b/0001-Port-to-JSR-269.patch new file mode 100644 index 0000000..ad017eb --- /dev/null +++ b/0001-Port-to-JSR-269.patch @@ -0,0 +1,438 @@ +From 6636088282b21b3d8b7d0d1c5f3251005f5cd02d Mon Sep 17 00:00:00 2001 +From: Michal Srb +Date: Tue, 6 May 2014 07:51:51 +0200 +Subject: [PATCH] Port to JSR-269 + +--- + .../args4j/apt/AnnotationProcessorFactoryImpl.java | 154 ------------------ + .../args4j/apt/AnnotationProcessorImpl.java | 176 +++++++++++++++++++++ + args4j-tools/src/org/kohsuke/args4j/apt/Main.java | 17 +- + .../src/org/kohsuke/args4j/apt/TxtWriter.java | 4 +- + .../src/org/kohsuke/args4j/apt/XmlWriter.java | 4 +- + 5 files changed, 189 insertions(+), 166 deletions(-) + delete mode 100644 args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorFactoryImpl.java + create mode 100644 args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorImpl.java + +diff --git a/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorFactoryImpl.java b/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorFactoryImpl.java +deleted file mode 100644 +index d7148f8..0000000 +--- a/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorFactoryImpl.java ++++ /dev/null +@@ -1,154 +0,0 @@ +-package org.kohsuke.args4j.apt; +- +-import com.sun.mirror.apt.AnnotationProcessor; +-import com.sun.mirror.apt.AnnotationProcessorEnvironment; +-import com.sun.mirror.apt.AnnotationProcessorFactory; +-import com.sun.mirror.declaration.AnnotationTypeDeclaration; +-import com.sun.mirror.declaration.ClassDeclaration; +-import com.sun.mirror.declaration.Declaration; +-import com.sun.mirror.declaration.FieldDeclaration; +-import com.sun.mirror.declaration.MethodDeclaration; +-import com.sun.mirror.declaration.TypeDeclaration; +-import com.sun.mirror.declaration.MemberDeclaration; +-import com.sun.mirror.type.ClassType; +-import com.sun.mirror.util.SimpleDeclarationVisitor; +-import org.kohsuke.args4j.Argument; +-import org.kohsuke.args4j.Option; +- +-import java.io.File; +-import java.io.FileWriter; +-import java.io.IOException; +-import java.io.FileInputStream; +-import java.util.Arrays; +-import java.util.Collection; +-import java.util.Collections; +-import java.util.HashSet; +-import java.util.Set; +-import java.util.Properties; +- +-/** +- * {@link AnnotationProcessorFactory} to be invoked by APT. +- * +- * This class receives options from the Main method through system properties (ouch!). +- * +- * @author Kohsuke Kawaguchi +- */ +-public class AnnotationProcessorFactoryImpl implements AnnotationProcessorFactory { +- +- private File outDir; +- private String format; +- private Properties resource = null; +- +- public AnnotationProcessorFactoryImpl() { +- outDir = new File(System.getProperty("args4j.outdir")); +- format = System.getProperty("args4j.format"); +- +- String res = System.getProperty("args4j.resource"); +- if(res!=null && res.length()>0) { +- try { +- resource = new Properties(); +- resource.load(new FileInputStream(res)); +- } catch (IOException e) { +- throw new Error(e); +- } +- } +- } +- +- public Collection supportedOptions() { +- return Collections.emptyList(); +- } +- +- public Collection supportedAnnotationTypes() { +- return Arrays.asList(Option.class.getName(),Argument.class.getName()); +- } +- +- public AnnotationProcessor getProcessorFor(final Set annotationTypeDeclarations, final AnnotationProcessorEnvironment env) { +- return new AnnotationProcessor() { +- public void process() { +- Collection params = env.getDeclarationsAnnotatedWith((AnnotationTypeDeclaration)env.getTypeDeclaration(Option.class.getName())); +- +- final Set optionBeans = new HashSet(); +- for (Declaration d : params) { +- d.accept(new SimpleDeclarationVisitor() { +- public void visitFieldDeclaration(FieldDeclaration f) { +- TypeDeclaration dt = f.getDeclaringType(); +- optionBeans.add(dt); +- } +- +- public void visitMethodDeclaration(MethodDeclaration m) { +- optionBeans.add(m.getDeclaringType()); +- } +- }); +- } +- +- for (TypeDeclaration t : optionBeans) { +- // make sure that they are on classes +- if(t instanceof ClassDeclaration) { +- ClassDeclaration cd = (ClassDeclaration)t; +- try { +- AnnotationVisitor writer = createAnnotationVisitor(cd); +- env.getMessager().printNotice("Processing "+cd.getQualifiedName()); +- scan(cd, writer); +- } catch (IOException e) { +- env.getMessager().printError(e.getMessage()); +- } +- } else { +- env.getMessager().printError(t.getPosition(), +- "args4j annotations need to be placed on a class"); +- } +- } +- } +- }; +- } +- +- private AnnotationVisitor createAnnotationVisitor(ClassDeclaration cd) throws IOException { +- FileWriter out = new FileWriter(new File(outDir,cd.getQualifiedName()+"."+format.toLowerCase())); +- AnnotationVisitor writer; +- if(format.equals("XML")) +- writer = new XmlWriter(out,cd); +- else if (format.equals("TXT")) +- writer = new TxtWriter(out, cd); +- else +- writer = new HtmlWriter(out); +- return new AnnotationVisitorReorderer(writer); +- } +- +- private void scan(ClassDeclaration decl, AnnotationVisitor visitor) { +- while(decl!=null) { +- for( FieldDeclaration f : decl.getFields() ) +- scan(f, visitor); +- +- for (MethodDeclaration m : decl.getMethods()) +- scan(m, visitor); +- +- ClassType sc = decl.getSuperclass(); +- if(sc==null) break; +- +- decl = sc.getDeclaration(); +- } +- +- visitor.done(); +- } +- +- private void scan(MemberDeclaration f, AnnotationVisitor visitor) { +- Option o = f.getAnnotation(Option.class); +- if(o==null) return; +- +- String usage = getUsage(o); +- if(isOptionHidden(usage)) return; +- +- visitor.onOption(new OptionWithUsage(o, usage)); +- } +- +- private boolean isOptionHidden(String usage) { +- return usage==null || usage.length()==0; +- } +- +- private String getUsage(Option o) { +- if(resource==null) +- return o.usage(); +- else +- return resource.getProperty(o.usage()); +- } +- +-} +diff --git a/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorImpl.java b/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorImpl.java +new file mode 100644 +index 0000000..14fd3c0 +--- /dev/null ++++ b/args4j-tools/src/org/kohsuke/args4j/apt/AnnotationProcessorImpl.java +@@ -0,0 +1,176 @@ ++package org.kohsuke.args4j.apt; ++ ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.FileWriter; ++import java.io.IOException; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Properties; ++import java.util.Set; ++ ++import javax.annotation.processing.AbstractProcessor; ++import javax.annotation.processing.Processor; ++import javax.annotation.processing.RoundEnvironment; ++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.SimpleElementVisitor8; ++import javax.lang.model.util.Types; ++import javax.tools.Diagnostic.Kind; ++ ++import org.kohsuke.args4j.Argument; ++import org.kohsuke.args4j.Option; ++ ++/** ++ * Annotation {@link Processor} to be invoked by javac. ++ * ++ * This class receives options from the Main method through system properties ++ * (ouch!). ++ * ++ * @author Kohsuke Kawaguchi ++ */ ++ ++public class AnnotationProcessorImpl extends AbstractProcessor { ++ ++ private File outDir; ++ private String format; ++ private Properties resource = null; ++ ++ public AnnotationProcessorImpl() { ++ outDir = new File(System.getProperty("args4j.outdir")); ++ format = System.getProperty("args4j.format"); ++ ++ String res = System.getProperty("args4j.resource"); ++ if (res != null && res.length() > 0) { ++ try { ++ resource = new Properties(); ++ resource.load(new FileInputStream(res)); ++ } catch (IOException e) { ++ throw new Error(e); ++ } ++ } ++ } ++ ++ @Override ++ public Set getSupportedAnnotationTypes() { ++ return new HashSet(Arrays.asList(Option.class.getName(), ++ Argument.class.getName())); ++ } ++ ++ @Override ++ public SourceVersion getSupportedSourceVersion() { ++ ++ // inspiration taken from metainf-services project ++ try { ++ return SourceVersion.valueOf("RELEASE_8"); ++ } catch (IllegalArgumentException x) { ++ } ++ try { ++ return SourceVersion.valueOf("RELEASE_7"); ++ } catch (IllegalArgumentException x) { ++ } ++ ++ return SourceVersion.RELEASE_6; ++ } ++ ++ private AnnotationVisitor createAnnotationVisitor(TypeElement te) ++ throws IOException { ++ FileWriter out = new FileWriter(new File(outDir, te.getQualifiedName() ++ + "." + format.toLowerCase())); ++ AnnotationVisitor writer; ++ if (format.equals("XML")) ++ writer = new XmlWriter(out, te); ++ else if (format.equals("TXT")) ++ writer = new TxtWriter(out, te); ++ else ++ writer = new HtmlWriter(out); ++ return new AnnotationVisitorReorderer(writer); ++ } ++ ++ private void scan(TypeElement decl, AnnotationVisitor visitor) { ++ ++ Types typeUtils = processingEnv.getTypeUtils(); ++ ++ while (decl != null) { ++ for (Element f : decl.getEnclosedElements()) { ++ scan(f, visitor); ++ } ++ decl = (TypeElement) typeUtils.asElement(decl.getSuperclass()); ++ } ++ ++ visitor.done(); ++ } ++ ++ private void scan(Element f, AnnotationVisitor visitor) { ++ Option o = f.getAnnotation(Option.class); ++ if (o == null) ++ return; ++ ++ String usage = getUsage(o); ++ if (isOptionHidden(usage)) ++ return; ++ ++ visitor.onOption(new OptionWithUsage(o, usage)); ++ } ++ ++ private boolean isOptionHidden(String usage) { ++ return usage == null || usage.length() == 0; ++ } ++ ++ private String getUsage(Option o) { ++ if (resource == null) ++ return o.usage(); ++ else ++ return resource.getProperty(o.usage()); ++ } ++ ++ @Override ++ public boolean process(Set annotations, ++ RoundEnvironment roundEnv) { ++ ++ Set params = roundEnv ++ .getElementsAnnotatedWith(Option.class); ++ ++ final Set optionBeans = new HashSet(); ++ ++ for (Element d : params) { ++ ++ d.accept(new SimpleElementVisitor8() { ++ @Override ++ public Void visitVariable(VariableElement e, Void p) { ++ TypeElement dt = (TypeElement) e.getEnclosingElement(); ++ optionBeans.add(dt); ++ return null; ++ } ++ ++ public Void visitExecutable(ExecutableElement m, Void p) { ++ optionBeans.add((TypeElement) m.getEnclosingElement()); ++ return null; ++ } ++ }, null); ++ } ++ ++ for (TypeElement t : optionBeans) { ++ // make sure that they are on classes ++ if (t.getKind().isClass()) { ++ try { ++ AnnotationVisitor writer = createAnnotationVisitor(t); ++ processingEnv.getMessager().printMessage(Kind.NOTE, ++ "Processing " + t.getQualifiedName()); ++ scan(t, writer); ++ } catch (IOException e) { ++ processingEnv.getMessager().printMessage(Kind.ERROR, ++ e.getMessage()); ++ } ++ } else { ++ processingEnv.getMessager().printMessage(Kind.ERROR, ++ "args4j annotations need to be placed on a class", t); ++ } ++ } ++ ++ return true; ++ } ++} +diff --git a/args4j-tools/src/org/kohsuke/args4j/apt/Main.java b/args4j-tools/src/org/kohsuke/args4j/apt/Main.java +index 92d0205..91bd47a 100644 +--- a/args4j-tools/src/org/kohsuke/args4j/apt/Main.java ++++ b/args4j-tools/src/org/kohsuke/args4j/apt/Main.java +@@ -13,6 +13,9 @@ import java.net.URLClassLoader; + import java.util.ArrayList; + import java.util.List; + ++import javax.tools.JavaCompiler; ++import javax.tools.ToolProvider; ++ + /** + * Entry point that invokes APT. + * +@@ -62,15 +65,13 @@ public class Main { + if(resourceName==null) resourceName = ""; // can't have null in properties + System.setProperty("args4j.resource",resourceName); + +- aptArgs.add(0,"-nocompile"); ++ aptArgs.add(0, "-proc:only"); ++ aptArgs.add(1, "-processor"); ++ aptArgs.add(2, AnnotationProcessorImpl.class.getName()); ++ ++ JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); + +- // locate tools.jar +- ClassLoader cl = loadToolsJar(); +- Class apt = cl.loadClass("com.sun.tools.apt.Main"); +- Method main = getProcessMethod(apt); +- return (Integer)main.invoke(null,new Object[]{ +- cl.loadClass("org.kohsuke.args4j.apt.AnnotationProcessorFactoryImpl").newInstance(), +- aptArgs.toArray(new String[0])}); ++ return javac.run(System.in, System.out, System.err, aptArgs.toArray(new String[0])); + } + + private void printUsage(CmdLineParser parser) { +diff --git a/args4j-tools/src/org/kohsuke/args4j/apt/TxtWriter.java b/args4j-tools/src/org/kohsuke/args4j/apt/TxtWriter.java +index fc73b5c..ca98d8b 100644 +--- a/args4j-tools/src/org/kohsuke/args4j/apt/TxtWriter.java ++++ b/args4j-tools/src/org/kohsuke/args4j/apt/TxtWriter.java +@@ -1,6 +1,6 @@ + package org.kohsuke.args4j.apt; + +-import com.sun.mirror.declaration.ClassDeclaration; ++import javax.lang.model.element.TypeElement; + import org.kohsuke.args4j.Option; + + import java.io.PrintWriter; +@@ -14,7 +14,7 @@ import java.io.Writer; + class TxtWriter implements AnnotationVisitor { + private final PrintWriter out; + +- public TxtWriter(Writer out, ClassDeclaration d) { ++ public TxtWriter(Writer out, TypeElement d) { + this.out = new PrintWriter(out); + this.out.println("Usage: " + d.getQualifiedName()); + } +diff --git a/args4j-tools/src/org/kohsuke/args4j/apt/XmlWriter.java b/args4j-tools/src/org/kohsuke/args4j/apt/XmlWriter.java +index 1fcc5e5..0b20f31 100644 +--- a/args4j-tools/src/org/kohsuke/args4j/apt/XmlWriter.java ++++ b/args4j-tools/src/org/kohsuke/args4j/apt/XmlWriter.java +@@ -1,6 +1,6 @@ + package org.kohsuke.args4j.apt; + +-import com.sun.mirror.declaration.ClassDeclaration; ++import javax.lang.model.element.TypeElement; + + import java.io.PrintWriter; + import java.io.Writer; +@@ -13,7 +13,7 @@ import java.io.Writer; + class XmlWriter implements AnnotationVisitor { + private final PrintWriter out; + +- public XmlWriter(Writer out, ClassDeclaration d) { ++ public XmlWriter(Writer out, TypeElement d) { + this.out = new PrintWriter(out); + this.out.println(""); + } +-- +1.9.0 + diff --git a/args4j.spec b/args4j.spec index 9adf376..5b8c76b 100644 --- a/args4j.spec +++ b/args4j.spec @@ -1,11 +1,13 @@ Name: args4j Version: 2.0.26 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Java command line arguments parser License: MIT URL: http://args4j.kohsuke.org/ Source0: https://github.com/kohsuke/%{name}/archive/%{name}-site-%{version}.tar.gz +Patch0: 0001-Port-to-JSR-269.patch + BuildArch: noarch BuildRequires: maven-local @@ -38,6 +40,8 @@ This package contains the API documentation for %{name}. %prep %setup -q -n %{name}-%{name}-site-%{version} +%patch0 -p1 + # removing classpath addition sed -i 's/true/false/g' %{name}-tools/pom.xml @@ -74,6 +78,9 @@ find -name '*.jar' -exec rm -f '{}' \; %doc %{name}/LICENSE.txt %changelog +* Tue May 06 2014 Michal Srb - 2.0.26-4 +- Port to JSR-269 + * Tue Mar 04 2014 Stanislav Ochotnicky - 2.0.26-3 - Use Requires: java-headless rebuild (#1067528)