Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2010-2011 eBusiness Information, Excilys Group 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.googlecode.androidannotations.helper;
  
  import static com.googlecode.androidannotations.helper.ModelConstants.GENERATION_SUFFIX;
  
  import java.util.Arrays;
  import java.util.List;
  import java.util.Set;
  
  
  import android.util.Log;
  
  
  public class ValidatorHelper {
  
  	private static final String SPRING_REST_TEMPLATE_QUALIFIED_NAME = "org.springframework.web.client.RestTemplate";
  	private static final String ANDROID_VIEW_QUALIFIED_NAME = "android.view.View";
  	private static final String ANDROID_MENU_ITEM_QUALIFIED_NAME = "android.view.MenuItem";
  	private static final String ANDROID_TEXT_VIEW_QUALIFIED_NAME = "android.widget.TextView";
  	private static final String ANDROID_VIEWGROUP_QUALIFIED_NAME = "android.view.ViewGroup";
  	private static final String ANDROID_APPLICATION_QUALIFIED_NAME = "android.app.Application";
  	public static final String ANDROID_CONTEXT_QUALIFIED_NAME = "android.content.Context";
  	private static final String ANDROID_ACTIVITY_QUALIFIED_NAME = "android.app.Activity";
  	private static final String ANDROID_SERVICE_QUALIFIED_NAME = "android.app.Service";
  	private static final String ANDROID_RECEIVER_QUALIFIED_NAME = "android.content.BroadcastReceiver";
  	private static final String ANDROID_PROVIDER_QUALIFIED_NAME = "android.content.ContentProvider";
  	private static final String ANDROID_BUNDLE_QUALIFIED_NAME = "android.os.Bundle";
  	private static final String ANDROID_MOTION_EVENT_QUALIFIED_NAME = "android.view.MotionEvent";
  	private static final String ANDROID_SQLITE_DB_QUALIFIED_NAME = "android.database.sqlite.SQLiteDatabase";
  	private static final String GUICE_INJECTOR_QUALIFIED_NAME = "com.google.inject.Injector";
  	private static final String ROBOGUICE_INJECTOR_PROVIDER_QUALIFIED_NAME = "roboguice.inject.InjectorProvider";
  
  	private static final List<StringVALID_PREF_RETURN_TYPES = Arrays.asList("int""boolean""float""long""java.lang.String");
  
  	private static final List<StringINVALID_PREF_METHOD_NAMES = Arrays.asList("edit""getSharedPreferences""clear""getEditor""apply");
  
  	private static final Collection<IntegerVALID_LOG_LEVELS = Arrays.asList(.....);
  
 	@SuppressWarnings("unchecked")
 	private static final List<Class<? extends Annotation>> VALID_ENHANCED_VIEW_SUPPORT_ANNOTATIONS = Arrays.asList(EActivity.classEViewGroup.classEView.classEBean.class);
 
 	@SuppressWarnings("unchecked")
 	private static final List<Class<? extends Annotation>> VALID_ENHANCED_COMPONENT_ANNOTATIONS = Arrays.asList(EApplication.classEActivity.classEViewGroup.classEView.classEBean.classEService.classEReceiver.classEProvider.class);
 
 
 	public ValidatorHelper(TargetAnnotationHelper targetAnnotationHelper) {
 		this. = targetAnnotationHelper;
 	}
 
 	public void isNotFinal(Element elementIsValid valid) {
 		if (.isFinal(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot be used on a final element");
 		}
 	}
 
 	public void isNotSynchronized(Element elementIsValid valid) {
 		if (.isSynchronized(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot be used on a synchronized element. If you think you shall need to use the synchronized keyword for a specific use case, please post on the mailing list.");
 		}
 	}
 
 	public void isNotAbstract(Element elementIsValid valid) {
 		if (.isAbstract(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot be used on an abstract element");
 		}
 	}
 
 	public void isInterface(TypeElement elementIsValid valid) {
 		if (!.isInterface(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on an interface");
 		}
 	}
 	
 	public void isTopLevel(TypeElement elementIsValid valid) {
 		if (!.isTopLevel(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on a top level type");
 		}
 	}
 
 	public void doesNotExtendOtherInterfaces(TypeElement elementIsValid valid) {
 		if (element.getInterfaces().size() > 0) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on an interface that does not extend other interfaces");
 		}
 	}
 
 	public void doesNotReturnPrimitive(ExecutableElement elementIsValid valid) {
 		if (element.getReturnType().getKind().isPrimitive()) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot return primitive");
 		}
 	}
 
 	public void doesNotReturnArray(ExecutableElement elementIsValid valid) {
 		if (element.getReturnType().getKind() == .) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot return array");
 		}
 	}
 
 	public void isNotPrivate(Element elementIsValid valid) {
 		if (.isPrivate(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s cannot be used on a private element");
 		}
 	}
 
 	public void enclosingElementHasEBeanAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		Element enclosingElement = element.getEnclosingElement();
 		hasClassAnnotation(elementenclosingElementvalidatedElementsEBean.classvalid);
 	}
 
 	public void enclosingElementHasEActivity(Element elementAnnotationElements validatedElementsIsValid valid) {
 		Element enclosingElement = element.getEnclosingElement();
 		hasClassAnnotation(elementenclosingElementvalidatedElementsEActivity.classvalid);
 	}
 
 	public void hasEActivity(Element elementAnnotationElements validatedElementsIsValid valid) {
 		hasClassAnnotation(elementelementvalidatedElementsEActivity.classvalid);
 	}
 
 	public void enclosingElementHasEnhancedViewSupportAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		Element enclosingElement = element.getEnclosingElement();
 		hasOneOfClassAnnotations(elementenclosingElementvalidatedElementsvalid);
 	}
 
 	public void enclosingElementHasEnhancedComponentAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		Element enclosingElement = element.getEnclosingElement();
 		hasOneOfClassAnnotations(elementenclosingElementvalidatedElementsvalid);
 	}
 
 	private void hasClassAnnotation(Element reportElementElement elementAnnotationElements validatedElementsClass<? extends AnnotationvalidAnnotationIsValid valid) {
 		ArrayList<Class<? extends Annotation>> validAnnotations = new ArrayList<Class<? extends Annotation>>();
 		validAnnotations.add(validAnnotation);
 		hasOneOfClassAnnotations(reportElementelementvalidatedElementsvalidAnnotationsvalid);
 	}
 
 	private void hasOneOfClassAnnotations(Element reportElementElement elementAnnotationElements validatedElementsList<Class<? extends Annotation>> validAnnotationsIsValid valid) {
 
 		boolean foundAnnotation = false;
 		for (Class<? extends AnnotationvalidAnnotation : validAnnotations) {
 			if (element.getAnnotation(validAnnotation) != null) {
 
 				Set<? extends ElementlayoutAnnotatedElements = validatedElements.getAnnotatedElements(validAnnotation);
 
 				/*
 				 * This is for the case where the element has the right
 				 * annotation, but that annotation was not validated. We do not
 				 * add any compile error (should already exist on the
 				 * annotation), but we still invalidate this element.
 				 */
 				if (!layoutAnnotatedElements.contains(element)) {
 					valid.invalidate();
 				}
 
 				foundAnnotation = true;
 				break;
 			}
 		}
 
 		if (!foundAnnotation) {
 			valid.invalidate();
 			.printAnnotationError(reportElement"%s can only be used in a class annotated with " + getFormattedValidEnhancedBeanAnnotationTypes(validAnnotations) + ".");
 		}
 	}
 
 	private String getFormattedValidEnhancedBeanAnnotationTypes(List<Class<? extends Annotation>> annotations) {
 		StringBuilder sb = new StringBuilder();
 		if (!annotations.isEmpty()) {
 			sb.append(TargetAnnotationHelper.annotationName(annotations.get(0)));
 
 			for (int i = 1; i < annotations.size(); i++) {
 				sb.append(", ");
 				sb.append(TargetAnnotationHelper.annotationName(annotations.get(i)));
 			}
 		}
 
 		return sb.toString();
 	}
 
 	public void hasExtraValue(Element elementIsValid valid) {
 		boolean error = false;
 		try {
 			Extra extra = element.getAnnotation(Extra.class);
 			if (extra.value() == null) {
 				error = true;
 			}
 			error = true;
 		}
 		if (error) {
 			valid.invalidate();
 			.printAnnotationError(element"%s must have a value, which is the extra name used when sending the intent");
 		}
 	}
 
 	public void hasViewByIdAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		String error = "can only be used with annotation";
 		elementHasAnnotation(ViewById.classelementvalidatedElementsvaliderror);
 	}
 
 		String error = "can only be used in an interface annotated with";
 		elementHasAnnotation(Rest.classelementvalidatedElementsvaliderror);
 
 		if (!valid.isValid()) {
 			enclosingElementHasRestAnnotation(elementvalidatedElementsvalid);
 			elementHasMethodRestAnnotation(elementvalidatedElementsvalid);
 		}
 
 	}
 
 	public void elementHasMethodRestAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		String error = "can only be used on a method annotated with Rest methods.";
 		elementHasAnnotationContainsIn(elementvalidatedElementsvaliderror);
 
 	}
 
 	public void enclosingElementHasRestAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		String error = "can only be used in an interface annotated with";
 		enclosingElementHasAnnotation(Rest.classelementvalidatedElementsvaliderror);
 	}
 
 	public void enclosingElementHasAnnotation(Class<? extends AnnotationannotationElement elementAnnotationElements validatedElementsIsValid validString error) {
 		Element enclosingElement = element.getEnclosingElement();
 		elementHasAnnotation(annotationenclosingElementvalidatedElementsvaliderror);
 	}
 
 	public void elementHasAnnotation(Class<? extends AnnotationannotationElement elementAnnotationElements validatedElementsIsValid validString error) {
 
 		Set<? extends ElementlayoutAnnotatedElements = validatedElements.getAnnotatedElements(annotation);
 
 		if (!layoutAnnotatedElements.contains(element)) {
 			valid.invalidate();
 			if (element.getAnnotation(annotation) == null) {
 				.printAnnotationError(element"%s " + error + " " + TargetAnnotationHelper.annotationName(annotation));
 			}
 		}
 	}
 
 	public void elementHasAnnotationContainsIn(List<Class<? extends Annotation>> annotationsElement elementAnnotationElements validatedElementsIsValid validString error) {
 		boolean isAnnoted = false;
 		for (Class<? extends Annotationannotation : annotations) {
 			if (elementHasAnnotation(annotationelementvalidatedElements)) {
 				isAnnoted = true;
 				break;
 			}
 		}
 
 		if (!isAnnoted) {
 			valid.invalidate();
 			.printAnnotationError(element"%s " + error);
 		}
 	}
 
 	public boolean elementHasAnnotation(Class<? extends AnnotationannotationElement elementAnnotationElements validatedElements) {
 		Set<? extends ElementlayoutAnnotatedElements = validatedElements.getAnnotatedElements(annotation);
 		return layoutAnnotatedElements.contains(element);
 	}
 
 	public void throwsOnlyRestClientException(ExecutableElement elementIsValid valid) {
 		List<? extends TypeMirrorthrownTypes = element.getThrownTypes();
 		if (thrownTypes.size() > 0) {
 			if (thrownTypes.size() > 1 || !thrownTypes.get(0).toString().equals("org.springframework.web.client.RestClientException")) {
 				valid.invalidate();
 				.printAnnotationError(element"%s annotated methods can only declare throwing a RestClientException");
 			}
 		}
 	}
 
 	public void elementHasGetOrPostAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 
 		if (!elementHasAnnotation(Get.classelement) && !elementHasAnnotation(Post.classelement)) {
 			.printAnnotationError(element"%s can only be used in an interface annotated with Get or Post annotation");
 		}
 	}
 
 	public void typeHasAnnotation(Class<? extends AnnotationannotationElement elementIsValid valid) {
 		TypeMirror elementType = element.asType();
 		typeHasAnnotation(annotationelementTypeelementvalid);
 	}
 
 	public void typeHasAnnotation(Class<? extends AnnotationannotationTypeMirror elementTypeElement reportingElementIsValid valid) {
 		Element typeElement = .getTypeUtils().asElement(elementType);
 		if (!elementHasAnnotationSafe(annotationtypeElement)) {
 			valid.invalidate();
 			.printAnnotationError(reportingElement"%s can only be used on an element annotated with " + TargetAnnotationHelper.annotationName(annotation));
 		}
 	}
 
 	public void typeOrTargetValueHasAnnotation(Class<? extends AnnotationannotationElement elementIsValid valid) {
 		DeclaredType targetAnnotationClassValue = .extractAnnotationClassValue(element);
 
 		if (targetAnnotationClassValue != null) {
 			typeHasAnnotation(annotationtargetAnnotationClassValueelementvalid);
 
 			if (!.getTypeUtils().isAssignabletargetAnnotationClassValueelement.asType())) {
 				valid.invalidate();
 				.printAnnotationError(element"The value of %s must be assignable into the annotated field");
 			}
 		} else {
 			typeHasAnnotation(annotationelementvalid);
 		}
 	}
 
 	private boolean elementHasAnnotationSafe(Class<? extends AnnotationannotationElement element) {
 		List<? extends AnnotationMirrorannotationMirrors = element.getAnnotationMirrors();
 		for (AnnotationMirror annotationMirror : annotationMirrors) {
 			if (annotationMirror.getAnnotationType().toString().equals(annotation.getName())) {
 				return true;
 			}
 		}
 		return false;
 	}
 
 	private boolean elementHasAnnotation(Class<? extends AnnotationannotationElement element) {
 		return element.getAnnotation(annotation) != null;
 	}
 
 	public void elementHasRestAnnotation(Element elementAnnotationElements validatedElementsIsValid valid) {
 		String error = "can only be used in an interface annotated with";
 		elementHasAnnotation(Rest.classelementvalidatedElementsvaliderror);
 	}
 
 		TypeMirror returnType = element.getReturnType();
 		TypeKind returnKind = returnType.getKind();
 		if (returnKind == .) {
 			DeclaredType declaredReturnType = (DeclaredTypereturnType;
 			if (!declaredReturnType.toString().startsWith("org.springframework.http.ResponseEntity<") && declaredReturnType.getTypeArguments().size() > 0) {
 				valid.invalidate();
 				.printAnnotationError(element"%s annotated methods cannot return parameterized types, except for ResponseEntity");
 			}
 		}
 	}
 
 	public void hasHttpHeadersReturnType(ExecutableElement elementIsValid valid) {
 		String returnType = element.getReturnType().toString();
 		if (!returnType.equals("org.springframework.http.HttpHeaders")) {
 			valid.invalidate();
 			.printAnnotationError(element"%s annotated methods can only return a HttpHeaders, not " + returnType);
 		}
 	}
 
 	public void hasSetOfHttpMethodReturnType(ExecutableElement elementIsValid valid) {
 		TypeMirror returnType = element.getReturnType();
 		String returnTypeString = returnType.toString();
 		if (!returnTypeString.equals("java.util.Set<org.springframework.http.HttpMethod>")) {
 			valid.invalidate();
 			.printAnnotationError(element"%s annotated methods can only return a Set of HttpMethod, not " + returnTypeString);
 		} else {
 			DeclaredType declaredType = (DeclaredTypereturnType;
 			List<? extends TypeMirrortypeArguments = declaredType.getTypeArguments();
 			if (typeArguments.size() != 1) {
 				valid.invalidate();
 				.printAnnotationError(element"%s annotated methods can only return a parameterized Set (with HttpMethod)");
 			} else {
 				TypeMirror typeArgument = typeArguments.get(0);
 				if (!typeArgument.toString().equals("org.springframework.http.HttpMethod")) {
 					valid.invalidate();
 					.printAnnotationError(element"%s annotated methods can only return a parameterized Set of HttpMethod, not " + typeArgument.toString());
 				}
 			}
 		}
 	}
 
 	public void urlVariableNamesExistInParameters(ExecutableElement elementList<StringvariableNamesIsValid valid) {
 
 		List<? extends VariableElementparameters = element.getParameters();
 
 		List<StringparametersName = new ArrayList<String>();
 		for (VariableElement parameter : parameters) {
 			parametersName.add(parameter.getSimpleName().toString());
 		}
 
 		for (String variableName : variableNames) {
 			if (!parametersName.contains(variableName)) {
 				valid.invalidate();
 				.printAnnotationError(element"%s annotated method has an url variable which name could not be found in the method parameters: " + variableName);
 				return;
 			}
 		}
 	}
 
 	public void doesntThrowException(Element elementIsValid valid) {
 		ExecutableElement executableElement = (ExecutableElementelement;
 
 		if (executableElement.getThrownTypes().size() > 0) {
 			valid.invalidate();
 			.printAnnotationError(element"%s annotated methods should not declare throwing any exception");
 		}
 	}
 
 	public void returnTypeIsVoidOrBoolean(ExecutableElement executableElementIsValid valid) {
 		TypeMirror returnType = executableElement.getReturnType();
 
 		TypeKind returnKind = returnType.getKind();
 
 		if (returnKind != . && returnKind != . && !returnType.toString().equals("java.lang.Boolean")) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with a boolean or a void return type");
 		}
 	}
 
 	public void returnTypeIsVoid(ExecutableElement executableElementIsValid valid) {
 		TypeMirror returnType = executableElement.getReturnType();
 
 		if (returnType.getKind() != .) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with a void return type");
 		}
 	}
 
 	public void zeroOrOneParameter(ExecutableElement executableElementIsValid valid) {
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() > 1) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with zero or one parameter, instead of " + parameters.size());
 		}
 	}
 
 	public void zeroParameter(ExecutableElement executableElementIsValid valid) {
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() > 0) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with zero parameter, instead of " + parameters.size());
 		}
 	}
 
 	public void zeroOrOneViewParameters(ExecutableElement executableElementIsValid valid) {
 	}
 
 	public void zeroOrOneMenuItemParameters(ExecutableElement executableElementIsValid valid) {
 	}
 
 	public void zeroOrOneSpecificParameter(ExecutableElement executableElementString parameterTypeQualifiedNameIsValid valid) {
 
 		zeroOrOneParameter(executableElementvalid);
 
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() == 1) {
 			VariableElement parameter = parameters.get(0);
 			TypeMirror parameterType = parameter.asType();
 			if (!parameterType.toString().equals(parameterTypeQualifiedName)) {
 				valid.invalidate();
 				.printAnnotationError(executableElement"%s can only be used on a method with no parameter or a parameter of type " + parameterTypeQualifiedName + ", not " + parameterType);
 			}
 		}
 	}
 
 	public void zeroOrOneBundleParameter(ExecutableElement executableElementIsValid valid) {
 	}
 
 	public void extendsActivity(Element elementIsValid valid) {
 	}
 
 	public void extendsService(Element elementIsValid valid) {
 	}
 
 	public void extendsReceiver(Element elementIsValid valid) {
 	}
 
 	public void extendsProvider(Element elementIsValid valid) {
 	}
 
 	public void extendsView(Element elementIsValid valid) {
 	}
 
 	public void extendsTextView(Element elementIsValid valid) {
 	}
 
 	public void extendsViewGroup(Element elementIsValid valid) {
 	}
 
 	public void extendsApplication(Element elementIsValid valid) {
 	}
 
 	public void extendsContext(Element elementIsValid valid) {
 	}
 
 	public void upperclassOfRegisteredApplication(Element elementAndroidManifest manifestIsValid valid) {
 		String applicationClassName = manifest.getApplicationClassName();
 		if (applicationClassName != null) {
 			if (applicationClassName.endsWith()) {
 				applicationClassName = applicationClassName.substring(0, applicationClassName.length() - .length());
 			}
 			TypeMirror elementType = element.asType();
 			TypeMirror manifestType = .typeElementFromQualifiedName(applicationClassName).asType();
 			if (!.isSubtype(manifestTypeelementType)) {
 				valid.invalidate();
 				.printAnnotationError(element"%s can only be used on an element that is an instance of the following class (or one of it's superclass): " + applicationClassName);
 			}
 		} else {
 			valid.invalidate();
 			.printAnnotationError(element"No application class is registered in the AndroidManifest.xml");
 		}
 	}
 
 	public void applicationRegistered(Element elementAndroidManifest manifestIsValid valid) {
 
 		String applicationClassName = manifest.getApplicationClassName();
 		if (applicationClassName != null) {
 
 			TypeElement typeElement = (TypeElementelement;
 
 			String componentQualifiedName = typeElement.getQualifiedName().toString();
 			String generatedComponentQualifiedName = componentQualifiedName + .;
 
 			if (!applicationClassName.equals(generatedComponentQualifiedName)) {
 				if (applicationClassName.equals(componentQualifiedName)) {
 					valid.invalidate();
 					.printAnnotationError(element"The AndroidManifest.xml file contains the original component, and not the AndroidAnnotations generated component. Please register " + generatedComponentQualifiedName + " instead of " + componentQualifiedName);
 				} else {
 					.printAnnotationWarning(element"The component " + generatedComponentQualifiedName + " is not registered in the AndroidManifest.xml file.");
 				}
 			}
 		} else {
 			valid.invalidate();
 			.printAnnotationError(element"No application class registered in the AndroidManifest.xml");
 		}
 
 	}
 
 	public void isSharedPreference(Element elementAnnotationElements validatedElementsIsValid valid) {
 
 		TypeMirror type = element.asType();
 
 		/*
 		 * The type is not available yet because it has just been generated
 		 */
 		if (type instanceof ErrorType) {
 			String elementTypeName = type.toString();
 
 			boolean sharedPrefValidatedInRound = false;
 			if (elementTypeName.endsWith()) {
 				String prefTypeName = elementTypeName.substring(0, elementTypeName.length() - .length());
 
 				Set<? extends ElementsharedPrefElements = validatedElements.getAnnotatedElements(SharedPref.class);
 
 				for (Element sharedPrefElement : sharedPrefElements) {
 					TypeElement sharedPrefTypeElement = (TypeElementsharedPrefElement;
 
 					String sharedPrefQualifiedName = sharedPrefTypeElement.getQualifiedName().toString();
 
 					if (sharedPrefQualifiedName.endsWith(prefTypeName)) {
 						sharedPrefValidatedInRound = true;
 						break;
 					}
 				}
 			}
 
 			if (!sharedPrefValidatedInRound) {
 				valid.invalidate();
 			}
 
 		} else {
 			extendsType(elementSharedPreferencesHelper.class.getName(), valid);
 		}
 
 	}
 
 	public void extendsType(Element elementString typeQualifiedNameIsValid valid) {
 		TypeMirror elementType = element.asType();
 
 		TypeMirror expectedType = .typeElementFromQualifiedName(typeQualifiedName).asType();
 		if (!.isSubtype(elementTypeexpectedType)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on an element that extends " + typeQualifiedName);
 		}
 	}
 
 	public void hasOneOrTwoParametersAndFirstIsBoolean(ExecutableElement executableElementIsValid valid) {
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() < 1 || parameters.size() > 2) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with 1 or 2 parameter, instead of " + parameters.size());
 		} else {
 			VariableElement firstParameter = parameters.get(0);
 
 			TypeKind parameterKind = firstParameter.asType().getKind();
 
 			if (parameterKind != . && !firstParameter.toString().equals("java.lang.Boolean")) {
 				valid.invalidate();
 				.printAnnotationError(executableElement"the first parameter should be a boolean");
 			}
 		}
 	}
 
 	public void allowedType(Element elementIsValid validTypeMirror fieldTypeMirrorList<StringallowedTypes) {
 
 		String qualifiedName = fieldTypeMirror.toString();
 
 		if (!allowedTypes.contains(qualifiedName)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on a field which is a " + allowedTypes.toString() + ", not " + qualifiedName);
 		}
 	}
 
 	public void hasRoboGuiceJars(Element elementIsValid valid) {
 
 			valid.invalidate();
 			.printAnnotationError(element"Could not find the RoboGuice framework in the classpath, the following class is missing: " + );
 		}
 
 			valid.invalidate();
 			.printAnnotationError(element"Could not find the RoboApplication class in the classpath, are you using RoboGuice 1.1.1 ?");
 		}
 
 		try {
 			if (elementUtils.getTypeElement() == null) {
 				valid.invalidate();
 				.printAnnotationError(element"Could not find the Guice framework in the classpath, the following class is missing: " + );
 			}
 		} catch (RuntimeException e) {
 			valid.invalidate();
 			.printAnnotationError(element"Could not find the Guice framework in the classpath, the following class is missing: " + );
 		}
 	}
 
 	public void hasSpringAndroidJars(Element elementIsValid valid) {
 
 		if (elementUtils.getTypeElement() == null) {
 			valid.invalidate();
 			.printAnnotationError(element"Could not find the SpringAndroid framework in the classpath, the following class is missing: org.springframework.web.client.RestTemplate");
 		}
 	}
 
 	public void androidService(AndroidSystemServices androidSystemServicesElement elementIsValid valid) {
 		TypeMirror serviceType = element.asType();
 		if (!androidSystemServices.contains(serviceType)) {
 			valid.invalidate();
 			.printAnnotationError(element"Unknown service type: " + serviceType.toString());
 		}
 	}
 
 	public void hasOneMotionEventOrTwoMotionEventViewParameters(ExecutableElement executableElementIsValid valid) {
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() < 1 || parameters.size() > 2) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"%s can only be used on a method with 1 (MotionEvent) or 2 (MotionEvent, View) parameters, instead of " + parameters.size());
 		} else {
 			VariableElement firstParameter = parameters.get(0);
 			String firstParameterType = firstParameter.asType().toString();
 			if (!firstParameterType.equals()) {
 				valid.invalidate();
 				.printAnnotationError(executableElement"the first parameter must be a " +  + ", not a " + firstParameterType);
 			}
 			if (parameters.size() == 2) {
 				VariableElement secondParameter = parameters.get(1);
 				String secondParameterType = secondParameter.asType().toString();
 				if (!secondParameterType.equals()) {
 					valid.invalidate();
 					.printAnnotationError(executableElement"the second parameter must be a " +  + ", not a " + secondParameterType);
 				}
 			}
 		}
 	}
 
 	public void hasOneOrTwoParametersAndFirstIsDb(ExecutableElement executableElementIsValid valid) {
 		List<? extends VariableElementparameters = executableElement.getParameters();
 
 		if (parameters.size() < 1) {
 			valid.invalidate();
 			.printAnnotationError(executableElement"There should be at least 1 parameter: a " + );
 		} else {
 			VariableElement firstParameter = parameters.get(0);
 			String firstParameterType = firstParameter.asType().toString();
 			if (!firstParameterType.equals()) {
 				valid.invalidate();
 				.printAnnotationError(executableElement"the first parameter must be a " +  + ", not a " + firstParameterType);
 			}
 		}
 	}
 
 	public void isDeclaredType(Element elementIsValid validTypeMirror uiFieldTypeMirror) {
 		if (!(uiFieldTypeMirror instanceof DeclaredType)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s can only be used on a field which is a declared type");
 		}
 	}
 
 	public boolean isPrefMethod(Element element) {
 		if (!element.getKind().equals(.)) {
 			.printError(element"Only methods are allowed in an " + .annotationName() + " annotated interface");
 		} else {
 			ExecutableElement executableElement = (ExecutableElementelement;
 			String methodName = executableElement.getSimpleName().toString();
 			if (executableElement.getParameters().size() > 0) {
 				.printError(element"Method " + methodName + " should have no parameters in an " + .annotationName() + " annotated interface");
 			} else {
 
 				String returnType = executableElement.getReturnType().toString();
 				if (!.contains(returnType)) {
 					.printError(element"Method " + methodName + " should only return preference simple types in an " + .annotationName() + " annotated interface");
 				} else {
 					if (.contains(methodName)) {
 						.printError(element"The method name " + methodName + " is forbidden in an " + .annotationName() + " annotated interface");
 					} else {
 						return true;
 					}
 				}
 			}
 		}
 		return false;
 	}
 
 		checkDefaultAnnotation(methodDefaultString.class"String"new DefaultAnnotationCondition() {
 			public boolean correctReturnType(TypeMirror returnType) {
 				return returnType.toString().equals("java.lang.String");
 			}
 		});
 	}
 
 	private interface DefaultAnnotationCondition {
 		boolean correctReturnType(TypeMirror returnType);
 	}
 
 
 		private final TypeKind typeKind;
 
 		public TypeKindAnnotationCondition(TypeKind typeKind) {
 			this. = typeKind;
 		}
 
 		public boolean correctReturnType(TypeMirror returnType) {
 			return returnType.getKind() == ;
 		}
 
 	}
 
 	private <T extends Annotationvoid checkDefaultAnnotation(ExecutableElement methodClass<T> annotationClassString expectedReturnTypeDefaultAnnotationCondition condition) {
 		T defaultAnnotation = method.getAnnotation(annotationClass);
 		if (defaultAnnotation != null) {
 			if (!condition.correctReturnType(method.getReturnType())) {
 				.printAnnotationError(methodannotationClass, TargetAnnotationHelper.annotationName(annotationClass) + " can only be used on a method that returns a " + expectedReturnType);
 			}
 		}
 	}
 
 	@SuppressWarnings("unchecked")
 	private static final List<Class<? extends Annotation>> REST_ANNOTATION_CLASSES = Arrays.asList(Get.classHead.classOptions.classPost.classPut.classDelete.class);
 
 	public void unannotatedMethodReturnsRestTemplate(TypeElement typeElementIsValid valid) {
 		List<? extends ElementenclosedElements = typeElement.getEnclosedElements();
 		boolean foundGetRestTemplateMethod = false;
 		boolean foundSetRestTemplateMethod = false;
 		for (Element enclosedElement : enclosedElements) {
 			if (enclosedElement.getKind() != .) {
 				valid.invalidate();
 				.printError(enclosedElement"Only methods are allowed in a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 			} else {
 
 				boolean hasRestAnnotation = false;
 				for (Class<? extends AnnotationannotationClass : ) {
 					if (enclosedElement.getAnnotation(annotationClass) != null) {
 						hasRestAnnotation = true;
 						break;
 					}
 				}
 
 				if (!hasRestAnnotation) {
 					ExecutableElement executableElement = (ExecutableElementenclosedElement;
 					TypeMirror returnType = executableElement.getReturnType();
 						if (executableElement.getParameters().size() > 0) {
 							valid.invalidate();
 							.printError(enclosedElement"The method returning a RestTemplate should not declare any parameter in a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 						} else {
 							if (foundGetRestTemplateMethod) {
 								valid.invalidate();
 								.printError(enclosedElement"Only one method should declare returning a RestTemplate in a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 							} else {
 								foundGetRestTemplateMethod = true;
 							}
 						}
 					} else if (returnType.getKind() == .) {
 						List<? extends VariableElementparameters = executableElement.getParameters();
 						if (parameters.size() == 1) {
 							VariableElement firstParameter = parameters.get(0);
 								if (!foundSetRestTemplateMethod) {
 									foundSetRestTemplateMethod = true;
 								} else {
 									valid.invalidate();
 									.printError(enclosedElement"You can only have oneRestTemplate setter method on a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 
 								}
 							} else {
 								valid.invalidate();
 								.printError(enclosedElement"The method to set a RestTemplate should have only one RestTemplate parameter on a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 
 							}
 						} else {
 							valid.invalidate();
 							.printError(enclosedElement"The method to set a RestTemplate should have only one RestTemplate parameter on a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface");
 						}
 					} else {
 						valid.invalidate();
 						.printError(enclosedElement"All methods should be annotated in a " + TargetAnnotationHelper.annotationName(Rest.class) + " annotated interface, except the ones that returns or set a RestTemplate");
 					}
 				}
 			}
 		}
 	}
 
 	public void notAlreadyValidated(Element elementAnnotationElements validatedElementsIsValid valid) {
 		if (validatedElements.getAllElements().contains(element)) {
 			valid.invalidate();
 			.printAnnotationError(element"%s annotated element cannot be used with the other annotations used on this element.");
 		}
 	}
 
 	public void hasEmptyConstructor(Element elementIsValid valid) {
 
 		List<ExecutableElementconstructors = ElementFilter.constructorsIn(element.getEnclosedElements());
 
 		if (constructors.size() == 1) {
 
 			ExecutableElement constructor = constructors.get(0);
 
 			if (!.isPrivate(constructor)) {
 				if (constructor.getParameters().size() != 0) {
 					.printAnnotationError(element"%s annotated element should have an empty constructor");
 					valid.invalidate();
 				}
 			} else {