Kostas Papadimitriou avatar Kostas Papadimitriou committed b8fbd8f

unique validator

Comments (0)

Files changed (2)

validation/Unique.java

+package validation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import net.sf.oval.configuration.annotation.Constraint;
+
+/**
+ * This field must be greater than.
+ * Message key: validation.min
+ * $1: field name
+ * $2: reference value
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Constraint(checkWith = UniqueCheck.class)
+public @interface Unique {
+
+    String message() default UniqueCheck.mes;
+    String[] with();
+}
+

validation/UniqueCheck.java

+package validation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.Query;
+
+import org.apache.commons.lang.StringUtils;
+
+import play.db.jpa.JPA;
+import play.db.jpa.Model;
+import net.sf.oval.Validator;
+import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
+import net.sf.oval.context.FieldContext;
+import net.sf.oval.context.OValContext;
+
+@SuppressWarnings("serial")
+public class UniqueCheck extends AbstractAnnotationCheck<Unique> {
+
+    final static String mes = "validation.unique";
+
+    String[] fields;
+
+    @Override
+    public void configure(Unique unique) {
+        this.fields = unique.with();
+        setMessage(unique.message());
+    }
+
+    public boolean isSatisfied(Object validatedObject, Object value, OValContext context, Validator validator) {
+        requireMessageVariablesRecreation();
+        
+        if (value == null || value.toString().length() == 0) { 
+            return false; 
+        }
+        
+        // Model typecast
+        Model validatedModel = (Model) validatedObject;
+        
+        // field name
+        String field = ((FieldContext) context).getField().getName();
+        
+        // query parameters
+        HashMap<Integer, Object> queryParams = new HashMap<Integer, Object>();
+        int paramsIndex = 1;
+        
+        // query
+        StringBuffer hql = new StringBuffer();
+        hql.append("SELECT COUNT(*) FROM "); 
+        hql.append(validatedObject.getClass().getSimpleName()); 
+        hql.append(" AS o WHERE o."); 
+        hql.append(field);
+        hql.append("=?");
+        queryParams.put(paramsIndex++, value);
+        
+        // existing database entry (exclude this id)
+        if (validatedModel.id != null && validatedModel.id > 0L)
+        {
+            hql.append(" AND id IS NOT ?");
+        	queryParams.put(paramsIndex++, validatedModel.id);
+        }
+        
+        for (String field_name : fields)
+        {
+        	hql.append(" AND o." + field_name + "=?");
+        	Object methodValue = getModelField(field_name, validatedModel);
+        	if (methodValue == null)
+        	{
+        		return false;
+        	}
+        	
+        	queryParams.put(paramsIndex++, methodValue);
+        }
+        
+        // create query
+        Query query = JPA.em().createQuery(hql.toString());
+        
+        // add parameters
+        for (Integer key: queryParams.keySet())
+        {
+        	query.setParameter(key, queryParams.get(key));
+        }
+        Long count = (Long) query.getSingleResult();
+        
+        // should return 0 if no similar objects exist in db
+        return count.equals(0L);
+    }
+    
+    public Object getModelField(String field_name, Model obj) throws RuntimeException
+    {
+    	String methodName = "get" + StringUtils.capitalize(field_name);
+    	Object val;
+		try {
+			val = (Object) obj.getClass().getMethod(methodName).invoke(obj);
+	    	return val; 
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (NoSuchMethodException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} 
+		
+		return null;
+    }
+
+    @Override
+    public Map<String, String> createMessageVariables() {
+        Map<String, String> messageVariables = new HashMap<String, String>();
+//        messageVariables.put("min", fields);
+        return messageVariables;
+    }
+   
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.