package org.springframework.roo.classpath.details;

import org.springframework.roo.classpath.details.annotations.AnnotationMetadata;
import org.springframework.roo.support.util.Assert;

/**
 * Convenience class to hold annotation details which should be introduced
 * to a field via an AspectJ ITD
 * 
 * @author Stefan Schmidt
 * @since 1.1
 */
public final class DeclaredFieldAnnotationDetails {
	
	private FieldMetadata fieldMetadata;
	
	private AnnotationMetadata fieldAnnotation;
	
	private boolean removeAnnotation;

	/**
	 * Constructor must contain {@link FieldMetadata} of existing field (may already contain field annotations) and a list
	 * of new Annotations which should be introduced by an AspectJ ITD. The added annotations can not already be present 
	 * in {@link FieldMetadata}.
	 * 
	 * @param fieldMetadata FieldMetadata of existing field (may not be null)
	 * @param fieldAnnotation Annotation to be added to field via an ITD (may not be null)
	 * @param removeAnnotation if true, will cause the specified annotation to be REMOVED via AspectJ's "-" syntax (usually would be false)
	 */
	public DeclaredFieldAnnotationDetails(FieldMetadata fieldMetadata, AnnotationMetadata fieldAnnotation, boolean removeAnnotation) {
		Assert.notNull(fieldMetadata, "Field metadata required");
		Assert.notNull(fieldAnnotation, "Field annotation required");
		this.fieldMetadata = fieldMetadata;
		this.fieldAnnotation = fieldAnnotation;
		this.removeAnnotation = removeAnnotation;
	}

	/**
	 * Overloaded constructor which is used in the most typical case of ADDING an annotation to a field, not removing one.
	 * 
	 * @param fieldMetadata FieldMetadata of existing field (may not be null)
	 * @param fieldAnnotation Annotation to be added to field via an ITD (may not be null)
	 */
	public DeclaredFieldAnnotationDetails(FieldMetadata fieldMetadata, AnnotationMetadata fieldAnnotation) {
		this(fieldMetadata, fieldAnnotation, false);
	}

	public FieldMetadata getFieldMetadata() {
		return fieldMetadata;
	}

	public AnnotationMetadata getFieldAnnotation() {
		return fieldAnnotation;
	}

	public final boolean isRemoveAnnotation() {
		return removeAnnotation;
	}
}

@@ -391,18 +391,16 @@
 tails %7B%0A
-%09%0A
 %09private
@@ -429,18 +429,16 @@
 tadata;%0A
-%09%0A
 %09private
@@ -478,10 +478,8 @@
 on;%0A
-%09%0A
 %09pri
@@ -1350,16 +1350,396 @@
 ired%22);%0A
+%09%09if (removeAnnotation) %7B%0A%09%09%09Assert.isTrue(fieldAnnotation.getAttributeNames().isEmpty(), %22Field annotation '@%22 + fieldAnnotation.getAnnotationType().getSimpleTypeName() + %22' (on the target field '%22 + fieldMetadata.getFieldType().getFullyQualifiedTypeName() + %22.%22 + fieldMetadata.getFieldName().getSymbolName() + %22) must not have any attributes when requesting its removal%22);%0A%09%09%7D%0A
 %09%09this.f

Check that presented field annotation to the constructor of DeclaredMethodAnnotationDetails has no attributes when requesting its removal from an ITD