blob: b60beac731a71fa5552ce880d417f8fed8e6bd08 [file] [log] [blame]
/*
* 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.netbeans.modules.web.beans.analysis;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.classpath.GlobalPathRegistry;
import org.netbeans.api.java.source.ClasspathInfo;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.java.source.Task;
import org.netbeans.modules.j2ee.metadata.model.support.JavaSourceTestCase;
import org.netbeans.modules.parsing.api.indexing.IndexingManager;
import org.netbeans.modules.web.beans.testutilities.CdiTestUtilities;
import org.openide.filesystems.FileObject;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
/**
* @author ads
*
*/
public abstract class BaseAnalisysTestCase extends JavaSourceTestCase {
protected static final ResultProcessor NO_ERRORS_PROCESSOR = new ResultProcessor (){
@Override
public void process( TestProblems result ) {
Set<Element> elements = result.getErrors().keySet();
String msg = "";
if ( !elements.isEmpty()) {
msg = result.getErrors().values().iterator().next();
}
assertTrue( "Expected no errors, but found :" +msg , elements.isEmpty() );
elements = result.getWarings().keySet();
if ( !elements.isEmpty()) {
msg = result.getWarings().values().iterator().next();
}
assertTrue( "Expected no warnings, but found :" +msg , elements.isEmpty() );
}
};
protected static final ResultProcessor WARNINGS_PROCESSOR = new ResultProcessor (){
@Override
public void process( TestProblems result ) {
Set<Element> elements = result.getErrors().keySet();
String msg = "";
if ( !elements.isEmpty()) {
msg = result.getErrors().values().iterator().next();
}
assertTrue( "Expected no errors, but found :" +msg , elements.isEmpty() );
}
};
public BaseAnalisysTestCase( String testName ) {
super(testName);
}
/* (non-Javadoc)
* @see org.netbeans.modules.j2ee.metadata.model.support.JavaSourceTestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
super.setUp();
GlobalPathRegistry.getDefault().register(ClassPath.SOURCE,
new ClassPath[] { ClassPath.getClassPath(srcFO, ClassPath.SOURCE) });
GlobalPathRegistry.getDefault().register(ClassPath.BOOT,
new ClassPath[] { bootCP });
myClassPathInfo = ClasspathInfo.create(srcFO);
myUtilities = new CdiTestUtilities( srcFO );
myUtilities.initAnnotations();
}
/* (non-Javadoc)
* @see org.netbeans.modules.j2ee.metadata.model.support.JavaSourceTestCase#tearDown()
*/
@Override
protected void tearDown() {
}
protected void runAnalysis( FileObject fileObject ,
final ResultProcessor processor ) throws IOException
{
IndexingManager.getDefault().refreshIndexAndWait(srcFO.getURL(), null);
JavaSource js = JavaSource.create(myClassPathInfo, fileObject );
final AbstractAnalysisTask task = createTask();
js.runWhenScanFinished( new Task<CompilationController>() {
@Override
public void run( CompilationController controller ) throws Exception {
controller.toPhase( Phase.ELEMENTS_RESOLVED );
task.run( controller );
processor.process((TestProblems)task.getResult());
}
}, true);
}
protected CdiTestUtilities getUtilities(){
return myUtilities;
}
protected void checkFieldElement(TestProblems result , String enclosingClass,
String expectedName )
{
checkFieldElement(result, enclosingClass, expectedName, false );
}
protected void checkFieldElement(TestProblems result , String enclosingClass,
String expectedName , boolean checkOnlyFields )
{
checkElement(result, enclosingClass, expectedName, VariableElement.class,
checkOnlyFields);
}
protected void checkMethodElement(TestProblems result , String enclosingClass,
String expectedName , boolean checkOnlyFields)
{
checkElement(result, enclosingClass, expectedName, ExecutableElement.class,
checkOnlyFields);
}
protected void checkMethodElement(Map<Element,String> map , String enclosingClass,
String expectedName )
{
ElementMatcher matcher = new SimpleNameMatcher( expectedName );
checkElement(map, enclosingClass, matcher, ExecutableElement.class,
false);
}
protected void checkFieldElement(Map<Element,String> map , String enclosingClass,
String expectedName )
{
ElementMatcher matcher = new SimpleNameMatcher( expectedName );
checkElement(map, enclosingClass, matcher, VariableElement.class,
false);
}
protected void checkMethodElement(TestProblems result , String enclosingClass,
String expectedName )
{
checkMethodElement(result, enclosingClass, expectedName, false );
}
protected void checkCtor(TestProblems result , String enclosingClass)
{
ElementMatcher matcher = new CtorMatcher();
checkElement(result, enclosingClass, matcher, ExecutableElement.class, false);
}
protected <T extends Element> void checkElement(TestProblems result , String enclosingClass,
String expectedName , Class<T> elementClass, boolean checkOnlyFields )
{
ElementMatcher matcher = new SimpleNameMatcher( expectedName );
checkElement(result, enclosingClass, matcher, elementClass, checkOnlyFields);
}
protected <T extends Element> void checkElement(TestProblems result , String enclosingClass,
ElementMatcher matcher, Class<T> elementClass, boolean checkOnlyFields )
{
checkElement(result.getErrors(), enclosingClass, matcher, elementClass,
checkOnlyFields);
}
protected <T extends Element> void checkElement(Map<Element,String> map , String enclosingClass,
ElementMatcher matcher, Class<T> elementClass, boolean checkOnlyFields )
{
Set<Element> elements = map.keySet();
Set<Element> classElements = new HashSet<Element>();
TypeElement enclosingClazz = null;
for( Element element : elements ){
Element enclosingElement = element.getEnclosingElement();
TypeElement clazz = null;
boolean forAdd = false ;
if ( enclosingElement instanceof TypeElement ){
forAdd = true;
clazz = (TypeElement) enclosingElement;
}
else if ( element instanceof TypeElement ){
if ( !checkOnlyFields ){
forAdd = true;
}
clazz = (TypeElement)element;
}
else {
assertTrue("Found element which parent is not a type definition " +
"and is not a definition itself ", false);
}
if ( forAdd && clazz.getQualifiedName().contentEquals( enclosingClass )){
enclosingClazz = clazz;
//System.out.println( "Found element : "+element);
classElements.add( element );
}
}
assertNotNull("Expected enclosing class doesn't contain errors", enclosingClazz );
assertEquals( "Expected exactly one error element", 1 , classElements.size());
Element element = classElements.iterator().next();
assertTrue( "Element has a class "+element.getClass(),
elementClass.isAssignableFrom( element.getClass() ) );
boolean match = matcher.matches( element );
if ( !match ){
assertTrue( matcher.getMessage(), match);
}
}
protected void checkParamElement(TestProblems result , String enclosingClass,
String methodName , String paramName )
{
checkParamElement(result.getErrors(), enclosingClass, methodName, paramName);
}
protected void checkParamElement(Map<Element,String> map, String enclosingClass,
String methodName , String paramName )
{
Set<Element> elements = map.keySet();
Set<Element> classElements = new HashSet<Element>();
TypeElement enclosingClazz = null;
ExecutableElement method = null;
for( Element element : elements ){
Element enclosingElement = element.getEnclosingElement();
TypeElement clazz = null;
ExecutableElement methodElement = null;
boolean forAdd = false ;
if ( enclosingElement instanceof TypeElement ){
forAdd = true;
clazz = (TypeElement) enclosingElement;
}
else if ( element instanceof TypeElement ){
clazz = (TypeElement)element;
}
else if ( enclosingElement instanceof ExecutableElement ) {
forAdd = true;
methodElement = (ExecutableElement)enclosingElement;
}
else {
assertTrue("Found element which parent is not a type definition, " +
"not a definition itself and not method", false);
}
if ( forAdd && methodElement != null &&
methodElement.getSimpleName().contentEquals( methodName ))
{
method = methodElement;
enclosingClazz = (TypeElement)method.getEnclosingElement();
classElements.add( element );
}
}
assertNotNull("Expected enclosing class doesn't contain errors", enclosingClazz );
assertNotNull("Expected enclosing method doesn't contain errors", method );
assertEquals( "Expected exactly one error element", 1 , classElements.size());
Element element = classElements.iterator().next();
assertEquals(paramName, element.getSimpleName().toString());
}
protected void checkTypeElement( TestProblems result , String expectedName ){
checkTypeElement(result.getErrors(), expectedName);
assertEquals( "Found unexpected warnings" , 0, result.getWarings().size() );
}
protected void checkTypeElement( Map<Element,String> map, String expectedName ){
Set<Element> elements = map.keySet();
if ( elements.size() > 1 ){
for( Element element : elements ){
System.out.println( "Found element : "+element.toString());
}
}
assertEquals( "Expected exactly one error element", 1 , elements.size());
Element element = elements.iterator().next();
assertTrue( element instanceof TypeElement );
String fqn = ((TypeElement)element).getQualifiedName().toString();
assertEquals(expectedName, fqn);
}
interface ElementMatcher {
boolean matches(Element element);
String getMessage();
}
class SimpleNameMatcher implements ElementMatcher {
SimpleNameMatcher( String simpleName ){
myName = simpleName;
}
public boolean matches(Element element){
myMessage = "Found "+element.getSimpleName()+" element, expected "+myName;
return myName.contentEquals( element.getSimpleName());
}
public String getMessage() {
return myMessage;
}
private String myName;
private String myMessage;
}
class CtorMatcher implements ElementMatcher {
public boolean matches(Element element){
myKind = element.getKind();
return myKind== ElementKind.CONSTRUCTOR;
}
public String getMessage() {
return "Found element has "+myKind+" , not CTOR";
}
private ElementKind myKind;
}
protected abstract AbstractAnalysisTask createTask();
private ClasspathInfo myClassPathInfo;
private CdiTestUtilities myUtilities;
protected static interface ResultProcessor {
void process ( TestProblems result );
}
}