Author: simoneg
Date: Fri Dec 11 15:37:34 2009
New Revision: 889664

URL: http://svn.apache.org/viewvc?rev=889664&view=rev
Log:
LABS-501 : Query by example system

Added:
    
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
    
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
Modified:
    labs/magma/trunk/foundation-database/pom.xml

Modified: labs/magma/trunk/foundation-database/pom.xml
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/pom.xml?rev=889664&r1=889663&r2=889664&view=diff
==============================================================================
--- labs/magma/trunk/foundation-database/pom.xml (original)
+++ labs/magma/trunk/foundation-database/pom.xml Fri Dec 11 15:37:34 2009
@@ -43,9 +43,9 @@
                        <version>1.0</version>
                </dependency>
                <dependency>
-                       <groupId>junit</groupId>
-                       <artifactId>junit</artifactId>
-                       <version>4.4</version>
+                       <groupId>org.apache.magma.tools</groupId>
+                       <artifactId>magma-test-utilities</artifactId>
+                       <version>0.0.3-SNAPSHOT</version>
                        <scope>test</scope>
                </dependency>
                <dependency>

Added: 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java?rev=889664&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
 (added)
+++ 
labs/magma/trunk/foundation-database/src/main/java/org/apache/magma/database/QueryByExampleBuilder.java
 Fri Dec 11 15:37:34 2009
@@ -0,0 +1,200 @@
+package org.apache.magma.database;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.Transient;
+
+import org.apache.commons.beanutils.MethodUtils;
+import org.apache.magma.basics.MagmaException;
+
+public class QueryByExampleBuilder<T> {
+
+       private FieldSettings defaults = new FieldSettings();
+       private Map<String, FieldSettings> settings;
+       private List<String> ignoreds = new ArrayList<String>();
+       private boolean useOr = false;
+
+       public QueryByExampleBuilder() {
+               addIgnore("class");
+               defaults.caseSensitive = false;
+               defaults.considerZero = false;
+               defaults.containsLike = true;
+               defaults.keywordsLike = false;
+               defaults.startsLike = false;
+       }
+       
+       public FieldSettings getSettings() {
+               return this.defaults;
+       }
+       
+       public void addSettings(String field, FieldSettings settings) {
+               if (this.settings == null) this.settings = new HashMap<String, 
FieldSettings>();
+               settings.setParent(defaults);
+               this.settings.put(field, settings);
+       }
+       
+       public void addIgnore(String field) {
+               this.ignoreds.add(field);
+       }
+       
+       public Query generateQuery(T qbe) {
+               StringBuilder sb = new StringBuilder();
+               boolean wheresent = false;
+               List<Object> params = new ArrayList<Object>();
+               try {
+                       BeanInfo infos = 
Introspector.getBeanInfo(qbe.getClass());
+                       PropertyDescriptor[] descs = 
infos.getPropertyDescriptors();
+                       for (PropertyDescriptor desc : descs) {
+                               String name = desc.getName();
+                               if (ignoreds.contains(name)) continue;
+                               Class<?> type = desc.getPropertyType();
+                               type = MethodUtils.toNonPrimitiveClass(type);
+                               if (type == null) continue;
+                               Method rm = desc.getReadMethod();
+                               if (rm == null || desc.getWriteMethod() == 
null) continue;
+                               if (rm.isAnnotationPresent(Transient.class)) 
continue;
+                               FieldSettings settings = null;
+                               if (this.settings != null) {
+                                       settings = this.settings.get(name);
+                               }
+                               if (settings == null) settings = this.defaults;
+                               String clause = "";
+                               if (type.equals(String.class)) {
+                                       String val = (String) rm.invoke(qbe);
+                                       if (val == null || val.length() == 0) 
continue;
+                                       boolean like = false;
+                                       if (settings.getStartsLike()) {
+                                               val = val + "%";
+                                               like = true;
+                                       } else if (settings.getContainsLike() 
|| settings.getKeywordsLike()) {
+                                               val = "%" + val + "%";
+                                               like = true;
+                                       }
+                                       if (settings.getKeywordsLike()) {
+                                               val = val.replace(' ', '%');
+                                               like = true;
+                                       }
+                                       clause = "x." + name;
+                                       if (!settings.getCaseSensitive()) {
+                                               clause = "LOWER(" + clause + 
")";
+                                               val = val.toLowerCase();
+                                       }
+                                       if (like) {
+                                               clause += " LIKE ";
+                                       } else {
+                                               clause += " = ";
+                                       }
+                                       clause += "?" + (params.size() + 1);
+                                       params.add(val);
+                               } else if (Number.class.isAssignableFrom(type)) 
{
+                                       Number val = (Number)rm.invoke(qbe);
+                                       if (val == null) continue;
+                                       if (!settings.getConsiderZero() && 
val.intValue() == 0) continue;
+                                       clause = "x." + name;
+                                       clause += "=?" + (params.size() + 1);
+                                       params.add(val);                        
        
+                               } else {
+                                       Object val = rm.invoke(qbe);
+                                       if (val == null) continue;
+                                       clause = "x." + name;
+                                       clause += "=?" + (params.size() + 1);
+                                       params.add(val);                        
                                        
+                               }
+                               if (clause != null) {
+                                       if (wheresent) {
+                                               sb.append(this.useOr ? " OR " : 
" AND ");
+                                       } else {
+                                               sb.append(" WHERE ");
+                                               wheresent = true;
+                                       }
+                                       sb.append(clause);
+                               }
+                       }
+               } catch (Exception e) {
+                       throw new MagmaException(e, "Error creating query from 
QBE {0}", qbe.getClass());
+               }
+               
+               Query ret = new Query();
+               ret.query = sb.toString();
+               ret.params = params.toArray();
+               return ret;
+       }
+       
+       public class Query {
+               public String query;
+               public Object[] params;
+       }
+       
+       public class FieldSettings {
+               private Boolean considerZero = null;
+               private Boolean caseSensitive = null;
+               private Boolean containsLike = null;
+               private Boolean startsLike = null;
+               private Boolean keywordsLike = null;
+               private FieldSettings parent;
+               
+               public Boolean getConsiderZero() {
+                       if (considerZero != null) return considerZero;
+                       if (parent != null) return parent.getConsiderZero();
+                       return null;
+               }
+               public void setConsiderZero(Boolean considerZero) {
+                       this.considerZero = considerZero;
+               }
+               public Boolean getCaseSensitive() {
+                       if (caseSensitive != null) return caseSensitive;
+                       if (parent != null) return parent.getCaseSensitive();
+                       return null;
+               }
+               public void setCaseSensitive(Boolean caseSensitive) {
+                       this.caseSensitive = caseSensitive;
+               }
+               public Boolean getContainsLike() {
+                       if (containsLike != null) return containsLike;
+                       if (parent != null) return parent.getContainsLike();
+                       return null;
+               }
+               public void setContainsLike(Boolean containsLike) {
+                       this.containsLike = containsLike;
+               }
+               public Boolean getStartsLike() {
+                       if (startsLike != null) return startsLike;
+                       if (parent != null) return parent.getStartsLike();
+                       return null;
+               }
+               public void setStartsLike(Boolean startsLike) {
+                       this.startsLike = startsLike;
+               }
+               public Boolean getKeywordsLike() {
+                       if (keywordsLike != null) return keywordsLike;
+                       if (parent != null) return parent.getKeywordsLike();
+                       return null;
+               }
+               public void setKeywordsLike(Boolean keywordsLike) {
+                       this.keywordsLike = keywordsLike;
+               }
+               FieldSettings getParent() {
+                       return parent;
+               }
+               void setParent(FieldSettings parent) {
+                       this.parent = parent;
+               }
+       }
+
+       public boolean isUseOr() {
+               return useOr;
+       }
+
+       public void setUseOr(boolean useOr) {
+               this.useOr = useOr;
+       }
+       
+}

Added: 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java?rev=889664&view=auto
==============================================================================
--- 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
 (added)
+++ 
labs/magma/trunk/foundation-database/src/test/java/org/apache/magma/database/TestQbe.java
 Fri Dec 11 15:37:34 2009
@@ -0,0 +1,89 @@
+package org.apache.magma.database;
+
+import static org.junit.Assert.*;
+import static org.junit.matchers.JUnitMatchers.*;
+import static org.hamcrest.CoreMatchers.*;
+
+import java.util.Date;
+
+import org.apache.magma.database.QueryByExampleBuilder.Query;
+import static org.apache.magma.testing.AssertStringStructure.assertStructure;
+import org.junit.Test;
+
+
+public class TestQbe {
+
+       @Test
+       public void simpleQuery() throws Exception {
+               
+               class SimpleBean {
+                       private String name;
+                       private int height;
+                       private Date birthday;
+                       
+                       public String getName() {
+                               return name;
+                       }
+                       public void setName(String name) {
+                               this.name = name;
+                       }
+                       public int getHeight() {
+                               return height;
+                       }
+                       public void setHeight(int height) {
+                               this.height = height;
+                       }
+                       public Date getBirthday() {
+                               return birthday;
+                       }
+                       public void setBirthday(Date birthday) {
+                               this.birthday = birthday;
+                       }
+               }
+               
+               SimpleBean sb = new SimpleBean();
+               QueryByExampleBuilder<SimpleBean> qbe = new 
QueryByExampleBuilder<SimpleBean>();
+               Query query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(0));
+               assertStructure(query.query, "!!WHERE");
+               
+               sb.height = 178;
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.query, "WHERE", "height", "=", "?1", 
"$$");
+               
+               sb.height = 0;
+               sb.name="Simone";
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.query, "WHERE", "LOWER(x.name)", "LIKE", 
"?1", "$$");
+
+               qbe.getSettings().setContainsLike(false);
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.query, "WHERE", "LOWER(x.name)", "=", 
"?1", "$$");
+
+               qbe.getSettings().setCaseSensitive(true);
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(1));
+               assertStructure(query.query, "WHERE", "name", "=", "?1", "$$");
+               
+               sb.height = 178;
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(2));
+               assertStructure(query.query, "WHERE", "?1", "AND", "?2", "$$");
+               
+               qbe.setUseOr(true);
+               query = qbe.generateQuery(sb);
+               System.out.println(query.query);
+               assertThat(query.params.length, equalTo(2));
+               assertStructure(query.query, "WHERE", "?1", "OR", "?2", "$$");  
        
+       }
+       
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to