/******************************************************************************* * Copyright (c) 2007 BEA Systems, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * wharley@bea.com - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.compiler.apt.tests.processors.inherited; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; 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 org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor; /** * A processor that tests the dispatch functionality in the presence of annotations that are * @Inherited. To enable this processor, add * -Aorg.eclipse.jdt.compiler.apt.tests.processors.inherited.InheritedAnnoProc to the command line. * * @since 3.3 */ @SupportedAnnotationTypes("*") @SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedOptions("org.eclipse.jdt.compiler.apt.tests.processors.inherited.InheritedAnnoProc") public class InheritedAnnoProc extends BaseProcessor { // Initialized in collectElements: private TypeElement _inheritedAnno; private TypeElement _notInheritedAnno; private TypeElement _elementA; private TypeElement _elementAChild; private TypeElement _elementANotAnnotated; private TypeElement _elementAIntf; private TypeElement _elementAEnum; private Element _elementAi; private Element _elementAfoo; private Element _elementAinit; // c'tor with no param private Element _elementAinitI; // c'tor with int param private Element _elementAa; // method with c'tor-like name private TypeElement _elementB; private TypeElement _elementBChild; private TypeElement _elementBNotAnnotated; private Element _elementBfoo; private Element _elementBi; // Always return false from this processor, because it supports "*". // The return value does not signify success or failure! @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { return false; } Map<String, String> options = processingEnv.getOptions(); if (!options.containsKey(this.getClass().getName())) { // Disable this processor unless we are intentionally performing the test. return false; } if (!collectElements()) { return false; } if (!examineGetRootElements(roundEnv)) { return false; } if (!examineGetElementsAnnotatedWith(roundEnv)) { return false; } reportSuccess(); return false; } private boolean collectElements() { _inheritedAnno = _elementUtils.getTypeElement("org.eclipse.jdt.compiler.apt.tests.annotations.InheritedAnno"); _notInheritedAnno = _elementUtils.getTypeElement("NotInheritedAnno"); if (null == _inheritedAnno || null == _notInheritedAnno) { reportError("collectElements: Couldn't load annotation type"); return false; } _elementA = _elementUtils.getTypeElement("InheritanceA"); for (Element e : _elementA.getEnclosedElements()) { String name = e.getSimpleName().toString(); if ("AChild".equals(name)) { _elementAChild = (TypeElement)e; } else if ("ANotAnnotated".equals(name)) { _elementANotAnnotated = (TypeElement)e; } else if ("AIntf".equals(name)) { _elementAIntf = (TypeElement)e; } else if ("AEnum".equals(name)) { _elementAEnum = (TypeElement)e; } else if ("i".equals(name)) { _elementAi = e; } else if ("foo".equals(name)) { _elementAfoo = e; } else if ("InheritanceA".equals(name)) { _elementAa = e; } else if ("<init>".equals(name)) { if (((ExecutableElement)e).getParameters().isEmpty()) { _elementAinit = e; } else { _elementAinitI = e; } } } if (null == _elementA || null == _elementAChild || null == _elementANotAnnotated || null == _elementAi || null == _elementAfoo || null == _elementAinitI || null == _elementAa || null == _elementAIntf || null == _elementAEnum || null == _elementAinit) { reportError("collectElements: couldn't load elements from InheritanceA"); return false; } _elementB = _elementUtils.getTypeElement("InheritanceB"); for (Element e : _elementB.getEnclosedElements()) { String name = e.getSimpleName().toString(); if ("BChild".equals(name)) { _elementBChild = (TypeElement)e; } else if ("BNotAnnotated".equals(name)) { _elementBNotAnnotated = (TypeElement)e; } else if ("i".equals(name)) { _elementBi = e; } else if ("foo".equals(name)) { _elementBfoo = e; } } if (null == _elementB || null == _elementBChild || null == _elementBNotAnnotated || null == _elementBi || null == _elementBfoo) { reportError("collectElements: couldn't load elements from InheritanceB"); return false; } return true; } /** * Test the getRootElements implementation. * @param roundEnv * @return true if tests passed */ private boolean examineGetRootElements(RoundEnvironment roundEnv) { // Expect to see all elements (unaffected by presence of @Inherited) final Element[] expected = {_notInheritedAnno, _elementA, _elementB}; Set<? extends Element> elements = new HashSet<Element>(roundEnv.getRootElements()); for (Element element : expected) { if (!elements.remove(element)) { reportError("examineRootElements: root elements did not contain expected element " + element.getSimpleName()); return false; } } if (!elements.isEmpty()) { reportError("examineRootElements: root elements contained unexpected elements " + elements); return false; } return true; } private boolean examineGetElementsAnnotatedWith(RoundEnvironment roundEnv) { // Elements we expect to get from getElementsAnnotatedWith(@InheritedAnno) final Element[] expectedInherited = { _elementA, _elementAChild, _elementAIntf, _elementAEnum, _elementAi, _elementAfoo, _elementAinit, _elementAinitI, _elementAa, _elementB, _elementBChild }; Set<? extends Element> actualInherited = new HashSet<Element>(roundEnv.getElementsAnnotatedWith(_inheritedAnno)); for (Element element : expectedInherited) { if (!actualInherited.remove(element)) { reportError("examineGetElementsAnnotatedWith(@InheritedAnno): did not contain expected element " + element.getSimpleName()); return false; } } if (!actualInherited.isEmpty()) { reportError("examineGetElementsAnnotatedWith(@InheritedAnno): contained unexpected elements " + actualInherited); return false; } // Elements we expect to get from getElementsAnnotatedWith(@NotInheritedAnno) final Element[] expectedNotInherited = { _elementA, _elementAChild, _elementAIntf, _elementAEnum, _elementAi, _elementAfoo, _elementAinit, _elementAinitI, _elementAa }; Set<? extends Element> actualNotInherited = new HashSet<Element>(roundEnv.getElementsAnnotatedWith(_notInheritedAnno)); for (Element element : expectedNotInherited) { if (!actualNotInherited.remove(element)) { reportError("examineGetElementsAnnotatedWith(@NotInheritedAnno): did not contain expected element " + element.getSimpleName()); return false; } } if (!actualNotInherited.isEmpty()) { reportError("examineGetElementsAnnotatedWith(@NotInheritedAnno): contained unexpected elements " + actualNotInherited); return false; } return true; } }