/* * Copyright (c) 2007, 2018 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package org.jemmy.support.test; import java.util.*; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.SimpleAnnotationValueVisitor6; import javax.lang.model.util.SimpleTypeVisitor6; import javax.tools.Diagnostic; import org.jemmy.control.ControlType; /** * JemmySupport annotation processor. * One would supposed to hook this to the compilation process by adding next * arguments to javac call *
 * -processor Proccessor -Aactions=<actions> -s <destination>
 * 
* where actions could, at the moment, contain "docks" * and/or "dump".
* "docks" means that dock classes will be generated into a dir passed by * -s option.
* "dump" means that there will be support.xml file generated * into a dir passed by -s option.
* * @author shura */ @SupportedSourceVersion(SourceVersion.RELEASE_6) public class Proccessor extends AbstractProcessor { private static final String DOCKS = "docks"; private static final String DUMP = "dump"; private static final String ACTIONS = "actions"; private final Set types = new HashSet(); private final Set options = new HashSet(); /** * */ public Proccessor() { types.add(ControlType.class.getName()); options.add(ACTIONS); } ProcessingEnvironment getProccessingEnvironment() { return processingEnv; } @Override public Set getSupportedAnnotationTypes() { return types; } private static boolean onlyOnlce = false; @Override public boolean process(Set set, RoundEnvironment re) { if (onlyOnlce) { return false; } onlyOnlce = true; List docks = new LinkedList(); for (Element e : re.getElementsAnnotatedWith(ControlType.class)) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Loading support information from " + toString(e.asType())); for (TypeMirror c : getClassArrayValue(getElementValue( findAnnotations(e, ControlType.class).get(0), "value"))) { docks.add(new ControlSupport((DeclaredType) e.asType(), (DeclaredType) c, processingEnv)); } } ControlSupport.linkSuperClasses(docks, processingEnv); String actions = processingEnv.getOptions().get(ACTIONS); if (actions.contains(DOCKS)) { new DockGenerator(processingEnv, docks).generate(); } if (actions.contains(DUMP)) { try { new DumpGenerator(processingEnv, docks).generate(); } catch (Exception ex) { throw new RuntimeException(ex); } } return true; } @Override public Set getSupportedOptions() { return options; } static List findAnnotations(Element e, Class annotationType) { List res = new LinkedList(); for (AnnotationMirror am : e.getAnnotationMirrors()) { if (am.getAnnotationType().toString().equals(annotationType.getName())) { res.add(am); } } return res; } static AnnotationMirror findAnnotation(Element e, Class annotationType) { List res = findAnnotations(e, annotationType); if (res.size() > 0) { return res.get(0); } else { return null; } } static AnnotationValue getElementValue(AnnotationMirror am, String name) { Map values = am.getElementValues(); for (ExecutableElement ee : values.keySet()) { if (ee.getSimpleName().contentEquals(name)) { return values.get(ee); } } return null; } private static final StringTypeGetter stringTypeVisitor = new StringTypeGetter(false); static String toString(TypeMirror type) { return type.accept(stringTypeVisitor, null); } private static final StringTypeGetter stringTypeVisitorDollar = new StringTypeGetter(true); static String toStringDollar(TypeMirror type) { return type.accept(stringTypeVisitorDollar, null); } private static final StringValueGetter stringValueVisitor = new StringValueGetter(); static String getStringValue(AnnotationValue v) { return v.accept(stringValueVisitor, null); } private static final StringArrayValueGetter stringArrayValueVisitor = new StringArrayValueGetter(); static List getStringArrayValue(AnnotationValue v) { return v.accept(stringArrayValueVisitor, null); } private static final BooleanArrayValueGetter booleanArrayValueVisitor = new BooleanArrayValueGetter(); static List getBooleanArrayValue(AnnotationValue v) { return v.accept(booleanArrayValueVisitor, null); } private static final ClassArrayValueGetter classArrayValueVisitor = new ClassArrayValueGetter(); static List getClassArrayValue(AnnotationValue v) { return v.accept(classArrayValueVisitor, null); } private static final ClassValueGetter classValueVisitor = new ClassValueGetter(); static DeclaredType getClassValue(AnnotationValue v) { return (DeclaredType) v.accept(classValueVisitor, null); } private static class ClassArrayValueGetter extends SimpleAnnotationValueVisitor6, Object> { @Override public List visitArray(List list, Object p) { List result = new ArrayList(); for (AnnotationValue av : list) { result.add((DeclaredType) av.accept(new ClassValueGetter(), null)); } return result; } } private static class StringArrayValueGetter extends SimpleAnnotationValueVisitor6, Object> { @Override public List visitArray(List list, Object p) { List result = new ArrayList(); for (AnnotationValue av : list) { result.add(av.accept(new StringValueGetter(), null)); } return result; } } private static class BooleanArrayValueGetter extends SimpleAnnotationValueVisitor6, Object> { @Override public List visitArray(List list, Object p) { List result = new ArrayList(); for (AnnotationValue av : list) { result.add(av.accept(new BooleanValueGetter(), null)); } return result; } } private static class ClassValueGetter extends SimpleAnnotationValueVisitor6 { @Override public TypeMirror visitType(TypeMirror tm, Object p) { return tm; } } private static class StringValueGetter extends SimpleAnnotationValueVisitor6 { @Override public String visitString(String tm, Object p) { return tm; } } private static class BooleanValueGetter extends SimpleAnnotationValueVisitor6 { @Override public Boolean visitBoolean(boolean b, Object p) { return b; } } private static class StringTypeGetter extends SimpleTypeVisitor6 { private final boolean dollar; public StringTypeGetter(boolean dollar) { this.dollar = dollar; } @Override public String visitDeclared(DeclaredType dt, Object p) { System.out.println(""); ElementKind kind = ((TypeElement) dt.asElement()).getEnclosingElement().getKind(); if(dollar && (kind == ElementKind.CLASS || kind == ElementKind.INTERFACE)) { return ((TypeElement)(((TypeElement) dt.asElement()).getEnclosingElement())).getQualifiedName().toString() + "$" + ((TypeElement) dt.asElement()).getSimpleName().toString(); } else { return ((TypeElement) dt.asElement()).getQualifiedName().toString(); } } @Override public String visitPrimitive(PrimitiveType pt, Object p) { return pt.toString(); } @Override public String visitArray(ArrayType at, Object p) { return at.getComponentType().accept(this, p) + "[]"; } @Override public String visitTypeVariable(TypeVariable tv, Object p) { return tv.getUpperBound().accept(this, p); } @Override public String visitExecutable(ExecutableType et, Object p) { return et.getReturnType().accept(this, p); } @Override public String visitNoType(NoType notype, Object p) { return "void"; } } }