package org.springframework.roo.classpath.operations.jsr303;

import java.util.ArrayList;
import java.util.List;

import org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue;
import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder;
import org.springframework.roo.classpath.details.annotations.ClassAttributeValue;
import org.springframework.roo.classpath.details.annotations.EnumAttributeValue;
import org.springframework.roo.classpath.details.annotations.StringAttributeValue;
import org.springframework.roo.classpath.operations.Cardinality;
import org.springframework.roo.classpath.operations.Fetch;
import org.springframework.roo.model.EnumDetails;
import org.springframework.roo.model.JavaSymbolName;
import org.springframework.roo.model.JavaType;

/**
 * Properties used by the many-to-one side of a relationship (called a "reference").
 * 
 * <p>
 * For example, an Order-LineItem link would have the LineItem contain a "reference" back to Order.
 *  
 * <p>
 * Limited support for collection mapping is provided. This reflects the pragmatic goals of ROO and the fact a user can
 * edit the generated files by hand anyway.
 * 
 * <p>
 * This field is intended for use with JSR 220 and will create a @ManyToOne and @JoinColumn annotation.
 *
 * @author Ben Alex
 * @since 1.0
 */
public class ReferenceField extends FieldDetails {
	private JavaType fieldType;
	private String joinColumnName;
	private Fetch fetch = null;
	private Cardinality cardinality = null;

	public ReferenceField(String physicalTypeIdentifier, JavaType fieldType, JavaSymbolName fieldName, Cardinality cardinality) {		
		super(physicalTypeIdentifier, fieldType, fieldName);
		this.fieldType = fieldType;
		this.cardinality = cardinality;
	}

	public String getJoinColumnName() {
		return joinColumnName;
	}

	public void setJoinColumnName(String joinColumnName) {
		this.joinColumnName = joinColumnName;
	}

	public Fetch getFetch() {
		return fetch;
	}

	public void setFetch(Fetch fetch) {
		this.fetch = fetch;
	}

	public void decorateAnnotationsList(List<AnnotationMetadataBuilder> annotations) {
		super.decorateAnnotationsList(annotations);
		List<AnnotationAttributeValue<?>> attributes = new ArrayList<AnnotationAttributeValue<?>>();
		attributes.add(new ClassAttributeValue(new JavaSymbolName("targetEntity"), fieldType));
		
		if (fetch != null) {
			JavaSymbolName value = new JavaSymbolName("EAGER");
			if (fetch == Fetch.LAZY) {
				value = new JavaSymbolName("LAZY");
			}
			attributes.add(new EnumAttributeValue(new JavaSymbolName("fetch"), new EnumDetails(new JavaType("javax.persistence.FetchType"), value)));
		}
		
		switch (cardinality) {
			case ONE_TO_MANY:
				annotations.add(new AnnotationMetadataBuilder(new JavaType("javax.persistence.OneToMany"), attributes));
				break;
			case MANY_TO_MANY:
				annotations.add(new AnnotationMetadataBuilder(new JavaType("javax.persistence.ManyToMany"), attributes));
				break;
			case ONE_TO_ONE:
				annotations.add(new AnnotationMetadataBuilder(new JavaType("javax.persistence.OneToOne"), attributes));
				break;
			default:
				annotations.add(new AnnotationMetadataBuilder(new JavaType("javax.persistence.ManyToOne"), attributes));
				break;
		}
		
		List<AnnotationAttributeValue<?>> jcAttrs = new ArrayList<AnnotationAttributeValue<?>>();
		if (joinColumnName != null) {
			jcAttrs.add(new StringAttributeValue(new JavaSymbolName("name"), joinColumnName));
		}
		annotations.add(new AnnotationMetadataBuilder(new JavaType("javax.persistence.JoinColumn"), jcAttrs));
	}
}

@@ -286,90 +286,8 @@
 er;%0A
-import org.springframework.roo.classpath.details.annotations.ClassAttributeValue;%0A
 impo
@@ -1308,37 +1308,8 @@
 s %7B%0A
-%09private JavaType fieldType;%0A
 %09pri
@@ -1595,38 +1595,8 @@
 e);%0A
-%09%09this.fieldType = fieldType;%0A
 %09%09th
@@ -2134,98 +2134,8 @@
 ();%0A
-%09%09attributes.add(new ClassAttributeValue(new JavaSymbolName(%22targetEntity%22), fieldType));%0A
 %09%09%0A%09
@@ -3058,17 +3058,25 @@
 ue%3C?%3E%3E j
-c
+oinColumn
 Attrs = 
@@ -3157,17 +3157,25 @@
 ) %7B%0A%09%09%09j
-c
+oinColumn
 Attrs.ad
@@ -3248,19 +3248,16 @@
 ame));%0A%09
-%09%7D%0A
 %09%09annota
@@ -3343,17 +3343,25 @@
 umn%22), j
-c
+oinColumn
 Attrs));
@@ -3361,13 +3361,17 @@
 ttrs));%0A
+%09%09%7D%0A
 %09%7D%0A%7D%0A

Remove unneeded targetEntity and @JoinColumn from @ManyToOne and @OneToOne