package org.dynamicfinder.jpa;

import java.io.Serializable;

import org.dynamicfinder.Nullable;
import org.dynamicfinder.Restriction;
import org.dynamicfinder.RestrictionLogic;
import org.dynamicfinder.RestrictionType;

/**
 * Define data structure for query restriction for Java Persistence API.
 * @author xsalefter (xsalefter[at]gmail.com)
 */
public class JpaRestriction implements Restriction, Serializable {

	private static final long serialVersionUID = 1238053379229080782L;

	private Integer parameter;
	private final String field;
	private final RestrictionType restrictionType;
	private final Object value;
	private final Nullable nullable;
	private final RestrictionLogic restrictionLogic;

	public JpaRestriction(
			final String field, 
			final Object...values) {
		super();
		this.field = field;
		this.restrictionType = RestrictionType.EQUAL;
		this.value = values;
		this.nullable = Nullable.DISCARD;
		this.restrictionLogic = RestrictionLogic.AND;
	}

	public JpaRestriction(
			final String field,
			final RestrictionType restrictionType,
			final Object...values) {
		super();
		this.field = field;
		this.restrictionType = restrictionType;
		this.value = values;
		this.nullable = Nullable.DISCARD;
		this.restrictionLogic = RestrictionLogic.AND;
	}

	public JpaRestriction(
			final String field,
			final RestrictionType restrictionType,
			final RestrictionLogic restrictionLogic,
			final Object...values) {
		super();
		this.field = field;
		this.restrictionType = restrictionType;
		this.value = values;
		this.nullable = Nullable.DISCARD;
		this.restrictionLogic = restrictionLogic;
	}

	public JpaRestriction(
			final String field,
			final RestrictionType restrictionType,
			final Nullable nullable,
			final Object...values) {
		super();
		this.field = field;
		this.restrictionType = restrictionType;
		this.value = values;
		this.nullable = nullable;
		this.restrictionLogic = RestrictionLogic.AND;
	}

	public JpaRestriction(
			final String field,
			final RestrictionType restrictionType,
			final Nullable nullable,
			final RestrictionLogic restrictionLogic,
			final Object...values) {
		super();
		this.field = field;
		this.restrictionType = restrictionType;
		this.value = values;
		this.nullable = nullable;
		this.restrictionLogic = restrictionLogic;
	}

	public final Integer getParameter() {
		return parameter;
	}

	public void setParameter(Integer parameter) {
		if (this.getParameter()  == null)
			this.parameter = parameter;
	}

	public final String getField() {
		return field;
	}

	public final RestrictionType getRestrictionType() {
		return restrictionType;
	}

	public final Object getValue() {
		if (this.isSingleValueRestrictionType()) {
			final Object[] result = (Object[]) this.value;
			return result.length != 0 ? result[0] : null;
		}
		return value;
	}

	public final Nullable getNullable() {
		return nullable;
	}

	public final RestrictionLogic getRestrictionLogic() {
		return restrictionLogic;
	}

	private boolean isSingleValueRestrictionType() {
		return this.restrictionType.equals(RestrictionType.EQUAL) ||
			   this.restrictionType.equals(RestrictionType.NOT_EQUAL) ||
			   this.restrictionType.equals(RestrictionType.GREATER) ||
			   this.restrictionType.equals(RestrictionType.GREATER_EQUAL) ||
			   this.restrictionType.equals(RestrictionType.LESSER) ||
			   this.restrictionType.equals(RestrictionType.LESSER_EQUAL) ||
			   this.restrictionType.equals(RestrictionType.LIKE) ||
			   this.restrictionType.equals(RestrictionType.LIKE_WITH_POSTFIX) ||
			   this.restrictionType.equals(RestrictionType.LIKE_WITH_PREFIX);
	}
}

@@ -3602,11 +3602,944 @@
 FIX);%0A%09%7D
+%0A%0A%09@Override%0A%09public int hashCode() %7B%0A%09%09final int prime = 31;%0A%09%09int result = 1;%0A%09%09result = prime * result + ((getField() == null) ? 0 : getField().hashCode());%0A%09%09result = prime * result%0A%09%09%09%09+ ((getNullable() == null) ? 0 : getNullable().hashCode());%0A%09%09result = prime%0A%09%09%09%09* result%0A%09%09%09%09+ ((getRestrictionLogic() == null) ? 0 : getRestrictionLogic().hashCode());%0A%09%09result = prime * result%0A%09%09%09%09+ ((getRestrictionType() == null) ? 0 : getRestrictionType().hashCode());%0A%09%09return result;%0A%09%7D%0A%0A%09@Override%0A%09public boolean equals(Object obj) %7B%0A%09%09if (obj == null) %7B return false; %7D%0A%0A%09%09if (!(obj instanceof JpaRestriction)) %7B return false; %7D%0A%0A%09%09JpaRestriction other = (JpaRestriction) obj;%0A%0A%09%09return %0A%09%09%09this.getField().equals( other.getField() ) &&%0A%09%09%09this.getRestrictionType().equals( other.getRestrictionType() ) && %0A%09%09%09this.getRestrictionLogic().equals( other.getRestrictionLogic() ) &&%0A%09%09%09this.getNullable().equals( other.getNullable() );%0A%09%7D
 %0A%7D%0A

Add equals and hashCode.