/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* 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.
*/
package com.querydsl.apt;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.*;
/**
* {@code TypeExtractor} is a visitor implementation which extracts a concrete type from a generic {@link TypeElement}
*
* @author tiwe
*
*/
class TypeExtractor extends SimpleTypeVisitorAdapter<TypeElement, Void> {
private final boolean skipEnum;
public TypeExtractor(boolean skipEnum) {
this.skipEnum = skipEnum;
}
@Override
public TypeElement visitPrimitive(PrimitiveType t, Void p) {
return null;
}
@Override
public TypeElement visitNull(NullType t, Void p) {
return null;
}
@Override
public TypeElement visitArray(ArrayType t, Void p) {
return visit(t.getComponentType());
}
@Override
public TypeElement visitDeclared(DeclaredType t, Void p) {
if (t.asElement() instanceof TypeElement) {
TypeElement typeElement = (TypeElement) t.asElement();
switch (typeElement.getKind()) {
case ENUM: return skipEnum ? null : typeElement;
case CLASS: return typeElement;
case INTERFACE: return visitInterface(t);
default: throw new IllegalArgumentException("Illegal type: " + typeElement);
}
} else {
return null;
}
}
private TypeElement visitInterface(DeclaredType t) {
if (t.getTypeArguments().isEmpty()) {
return (TypeElement) t.asElement();
} else {
int count = t.getTypeArguments().size();
if (t.asElement().toString().startsWith("java.util")) {
return t.getTypeArguments().get(count - 1).accept(this, null);
} else {
return (TypeElement) t.asElement();
}
}
}
@Override
public TypeElement visitError(ErrorType t, Void p) {
return visitDeclared(t, p);
}
@Override
public TypeElement visitTypeVariable(TypeVariable t, Void p) {
if (t.getUpperBound() != null) {
return visit(t.getUpperBound());
} else if (t.getLowerBound() != null) {
return visit(t.getLowerBound());
} else {
return null;
}
}
@Override
public TypeElement visitWildcard(WildcardType t, Void p) {
if (t.getExtendsBound() != null) {
return visit(t.getExtendsBound());
} else if (t.getSuperBound() != null) {
return visit(t.getSuperBound());
} else {
return null;
}
}
@Override
public TypeElement visitExecutable(ExecutableType t, Void p) {
return null;
}
@Override
public TypeElement visitNoType(NoType t, Void p) {
return null;
}
}