cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r927626 - in /cxf/trunk/rt/frontend/jaxrs/src: main/java/org/apache/cxf/jaxrs/ext/search/ test/java/org/apache/cxf/jaxrs/ext/search/
Date Thu, 25 Mar 2010 22:49:26 GMT
Author: sergeyb
Date: Thu Mar 25 22:49:26 2010
New Revision: 927626

URL: http://svn.apache.org/viewvc?rev=927626&view=rev
Log:
JAXRS : ensuring search conditions can 'recreate' original queries and introducing toSQL utility
method 

Added:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
  (with props)
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
  (with props)
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
  (with props)
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
  (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AndSearchCondition.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/OrSearchCondition.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchConditionTest.java

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java?rev=927626&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
(added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
Thu Mar 25 22:49:26 2010
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.search;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class AbstractComplexCondition<T> implements SearchCondition<T>
{
+
+    protected List<SearchCondition<T>> conditions;
+    private ConditionType cType;
+    
+    protected AbstractComplexCondition(ConditionType cType) {
+        this.cType = cType;
+    }
+    
+    protected AbstractComplexCondition(List<SearchCondition<T>> conditions, ConditionType
cType) {
+        this.conditions = conditions;
+        this.cType = cType;
+    }
+    
+    public void setConditions(List<SearchCondition<T>> conditions) {
+        this.conditions = conditions;
+    }
+    
+    public List<T> findAll(Collection<T> pojos) {
+        List<T> result = new ArrayList<T>();
+        for (T pojo : pojos) {
+            if (isMet(pojo)) {
+                result.add(pojo);
+            }
+        }
+        return result;
+    }
+
+    public T getCondition() {
+        return null;
+    }
+
+    public ConditionType getConditionType() {
+        return cType;
+    }
+
+    public List<SearchCondition<T>> getSearchConditions() {
+        return Collections.unmodifiableList(conditions);
+    }
+
+    public PrimitiveStatement getStatement() {
+        return null;
+    }
+
+    public String toSQL(String table, String... columns) {
+        StringBuilder sb = new StringBuilder();
+        
+        if (table != null) {
+            SearchUtils.startSqlQuery(sb, table, columns);
+        }
+        
+        boolean first = true;
+        for (SearchCondition<T> sc : conditions) {
+            if (!first) {
+                sb.append(" " + cType.toString() + " ");
+            } else {
+                first = false;
+            }
+            
+            sb.append("(").append(sc.toSQL(null)).append(")");
+        }
+        return sb.toString();
+    }
+
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AbstractComplexCondition.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AndSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AndSearchCondition.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AndSearchCondition.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/AndSearchCondition.java
Thu Mar 25 22:49:26 2010
@@ -18,29 +18,21 @@
  */
 package org.apache.cxf.jaxrs.ext.search;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Composite 'and' search condition   
  */
-public class AndSearchCondition<T> implements SearchCondition<T> {
+public class AndSearchCondition<T> extends AbstractComplexCondition<T> {
 
-    private List<SearchCondition<T>> conditions;
-    
     public AndSearchCondition() {
-        
+        super(ConditionType.AND);
     }
     
     public AndSearchCondition(List<SearchCondition<T>> conditions) {
-        this.conditions = conditions;    
+        super(conditions, ConditionType.AND);    
     }
     
-    public void setConditions(List<SearchCondition<T>> conditions) {
-        this.conditions = conditions;
-    }
     
     public boolean isMet(T pojo) {
         for (SearchCondition<T> sc : conditions) {
@@ -50,26 +42,5 @@ public class AndSearchCondition<T> imple
         }
         return true;
     }
-
-    public T getCondition() {
-        return null;
-    }
-
-    public ConditionType getConditionType() {
-        return ConditionType.AND;
-    }
-
-    public List<SearchCondition<T>> getConditions() {
-        return Collections.unmodifiableList(conditions);
-    }
-
-    public List<T> findAll(Collection<T> pojos) {
-        List<T> result = new ArrayList<T>();
-        for (T pojo : pojos) {
-            if (isMet(pojo)) {
-                result.add(pojo);
-            }
-        }
-        return result;
-    }
+    
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/OrSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/OrSearchCondition.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/OrSearchCondition.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/OrSearchCondition.java
Thu Mar 25 22:49:26 2010
@@ -18,29 +18,21 @@
  */
 package org.apache.cxf.jaxrs.ext.search;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Composite 'or' search condition   
  */
-public class OrSearchCondition<T> implements SearchCondition<T> {
+public class OrSearchCondition<T> extends AbstractComplexCondition<T> {
 
-    private List<SearchCondition<T>> conditions;
-    
     public OrSearchCondition() {
-        
+        super(ConditionType.OR);
     }
     
     public OrSearchCondition(List<SearchCondition<T>> conditions) {
-        this.conditions = conditions;    
+        super(conditions, ConditionType.OR);    
     }
     
-    public void setConditions(List<SearchCondition<T>> conditions) {
-        this.conditions = conditions;
-    }
     
     public boolean isMet(T pojo) {
         for (SearchCondition<T> sc : conditions) {
@@ -51,26 +43,4 @@ public class OrSearchCondition<T> implem
         return false;
     }
 
-    public T getCondition() {
-        return null;
-    }
-
-    public ConditionType getConditionType() {
-        return ConditionType.OR;
-    }
-
-    public List<SearchCondition<T>> getConditions() {
-        return Collections.unmodifiableList(conditions);
-    }
-
-    public List<T> findAll(Collection<T> pojos) {
-        List<T> result = new ArrayList<T>();
-        for (T pojo : pojos) {
-            if (isMet(pojo)) {
-                result.add(pojo);
-            }
-        }
-        return result;
-    }
-
 }

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java?rev=927626&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
(added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
Thu Mar 25 22:49:26 2010
@@ -0,0 +1,180 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.search;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class PrimitiveSearchCondition<T> implements SearchCondition<T> {
+    
+    private String propertyName;
+    private Object propertyValue;
+    private T condition;
+    private ConditionType cType;
+    private Beanspector<T> beanspector;
+    
+    public PrimitiveSearchCondition(String propertyName, 
+                                    Object propertyValue,
+                                    ConditionType ct,
+                                    T condition) {
+        this.propertyName = propertyName;
+        this.propertyValue = propertyValue;
+        this.condition = condition;
+        this.cType = ct;
+        if (propertyName != null) {
+            this.beanspector = new Beanspector<T>(condition);
+        }
+    }
+    
+    public List<T> findAll(Collection<T> pojos) {
+        List<T> result = new ArrayList<T>();
+        for (T pojo : pojos) {
+            if (isMet(pojo)) {
+                result.add(pojo);
+            }
+        }
+        return result;
+    }
+
+    public T getCondition() {
+        return condition;
+    }
+
+    public ConditionType getConditionType() {
+        return cType;
+    }
+
+    public List<SearchCondition<T>> getSearchConditions() {
+        return null;
+    }
+
+    public PrimitiveStatement getStatement() {
+        return new PrimitiveStatement(propertyName, propertyValue, cType);
+    }
+
+    public boolean isMet(T pojo) {
+        if (isPrimitive(pojo)) {
+            return compare(pojo, cType, propertyValue);
+        } else {
+            Object lValue = getValue(propertyName, pojo);
+            return lValue == null ? false : compare(lValue, cType, propertyValue);
+        }
+    }
+
+    private Object getValue(String getter, T pojo) {
+        try {
+            return beanspector.swap(pojo).getValue(getter);
+        } catch (Throwable e) {
+            return null;
+        }
+    }
+    
+    public String toSQL(String table, String... columns) {
+        StringBuilder sb = new StringBuilder();
+        
+        if (table != null) {
+            SearchUtils.startSqlQuery(sb, table, columns);
+        }
+        
+        String rvalStr = propertyValue.toString();
+        rvalStr = rvalStr.replaceAll("\\*", "%");
+        
+        
+        sb.append(propertyName).append(" ").append(
+            SearchUtils.conditionTypeToSqlOperator(cType, rvalStr)).append(" ")
+            .append("'").append(rvalStr).append("'");
+        return sb.toString();
+    }
+
+    private boolean isPrimitive(T pojo) {
+        return pojo.getClass().getName().startsWith("java.lang");
+    }
+
+    @SuppressWarnings("unchecked")
+    private boolean compare(Object lval, ConditionType cond, Object rval) {
+        boolean compares = true;
+        if (cond == ConditionType.EQUALS || cond == ConditionType.NOT_EQUALS) {
+            if (rval == null) {
+                compares = true;
+            } else if (lval == null) {
+                compares = false;
+            } else {
+                if (lval instanceof String) {
+                    compares = textCompare((String)lval, (String)rval);
+                } else {
+                    compares = lval.equals(rval);
+                }
+                if (cond == ConditionType.NOT_EQUALS) {
+                    compares = !compares;
+                }
+            }
+        } else {
+            if (lval instanceof Comparable && rval instanceof Comparable) {
+                Comparable lcomp = (Comparable)lval;
+                Comparable rcomp = (Comparable)rval;
+                int comp = lcomp.compareTo(rcomp);
+                switch (cond) {
+                case GREATER_THAN:
+                    compares = comp > 0;
+                    break;
+                case GREATER_OR_EQUALS:
+                    compares = comp >= 0;
+                    break;
+                case LESS_THAN:
+                    compares = comp < 0;
+                    break;
+                case LESS_OR_EQUALS:
+                    compares = comp <= 0;
+                    break;
+                default:
+                    String msg = String.format("Condition type %s is not supported", cond.name());
+                    throw new RuntimeException(msg);
+                }
+            }
+        }
+        return compares;
+    }
+
+    private boolean textCompare(String lval, String rval) {
+        // check wild cards
+        boolean starts = false;
+        boolean ends = false;
+        if (rval.charAt(0) == '*') {
+            starts = true;
+            rval = rval.substring(1);
+        }
+        if (rval.charAt(rval.length() - 1) == '*') {
+            ends = true;
+            rval = rval.substring(0, rval.length() - 1);
+        }
+        if (starts || ends) {
+            // wild card tests
+            if (starts && !ends) {
+                return lval.endsWith(rval);
+            } else if (ends && !starts) {
+                return lval.startsWith(rval);
+            } else {
+                return lval.contains(rval);
+            }
+        } else {
+            return lval.equals(rval);
+        }
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveSearchCondition.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java?rev=927626&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
(added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
Thu Mar 25 22:49:26 2010
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.search;
+
+/**
+ * Encapsulates a basic search statement such as a = b, i < 5, etc
+ */
+
+public class PrimitiveStatement {
+
+    private String propery;
+    private Object value;
+    private ConditionType condition;
+    
+    public PrimitiveStatement(String property, Object value, ConditionType condition) {
+        this.propery = property;
+        this.value = value;
+        this.condition = condition;
+    }
+    
+    public String getPropery() {
+        return propery;
+    }
+    
+    public Object getValue() {
+        return value;
+    }
+    public ConditionType getCondition() {
+        return condition;
+    }
+
+    
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/PrimitiveStatement.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchCondition.java
Thu Mar 25 22:49:26 2010
@@ -55,17 +55,27 @@ public interface SearchCondition<T> {
      * thus making it simpler to implement isMet(T). In some cases, the code which is given
      * SearchCondition may find it more efficient to directly deal with the captured state
      * for a more efficient lookup of matching data/records as opposed to calling
-     * SearchCondition.isMet for every instance of T it knows about. 
+     * SearchCondition.isMet for every instance of T it knows about.
+     * 
      *  
      * @return T the captured search criteria, can be null 
      */
     T getCondition();
+
+    
+    /**
+     * Primitive statement such a > b, i < 5, etc
+     * this condition may represent  
+     *  
+     * @return primitive search statement, can be null 
+     */
+    PrimitiveStatement getStatement();
     
     /**
      * List of conditions this SearchCondition may represent  
      * @return list of conditions, can be null
      */
-    List<SearchCondition<T>> getConditions();
+    List<SearchCondition<T>> getSearchConditions();
     
     /**
      * Type of condition this SearchCondition represents
@@ -73,4 +83,12 @@ public interface SearchCondition<T> {
      */
     ConditionType getConditionType();
     
+    /**
+     * Utility method for converting this condition into an SQL expression
+     * @param table table name
+     * @param columns column names, a wildcard as in 'SELECT * from table' will be used
+     *                if names are not provided 
+     * @return SQL expression
+     */    
+    String toSQL(String table, String... columns);
 }

Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java?rev=927626&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
(added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
Thu Mar 25 22:49:26 2010
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.search;
+
+public final class SearchUtils {
+    
+    private SearchUtils() {
+        
+    }
+    
+    public static void startSqlQuery(StringBuilder sb, String table, String... columns) {
+        sb.append("SELECT ");
+        if (columns.length > 0) {
+            for (int i = 0; i < columns.length; i++) {
+                sb.append(columns[i]);
+                if (i + 1 < columns.length) {
+                    sb.append(",");
+                }
+            }
+        } else {
+            sb.append("*");
+        }
+        sb.append(" FROM ").append(table).append(" WHERE ");
+    }
+    
+    public static String conditionTypeToSqlOperator(ConditionType ct, String value) {
+        // TODO : if we have the same column involved, ex a >= 123 and a <=244 then

+        // we may try to use IN or BETWEEN, depending on the values
+        String op;
+        switch (ct) {
+        case EQUALS:
+            op = value.contains("%") ? "LIKE" : "=";
+            break;
+        case NOT_EQUALS:
+            op = value.contains("%") ? "NOT LIKE" : "<>";
+            break;
+        case GREATER_THAN:
+            op = ">";
+            break;
+        case GREATER_OR_EQUALS:
+            op = ">=";
+            break;
+        case LESS_THAN:
+            op = "<";
+            break;
+        case LESS_OR_EQUALS:
+            op = "<=";
+            break;
+        default:
+            String msg = String.format("Condition type %s is not supported", ct.name());
+            throw new RuntimeException(msg);
+        }
+        return op;
+    }
+}

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SearchUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchCondition.java
Thu Mar 25 22:49:26 2010
@@ -20,6 +20,7 @@ package org.apache.cxf.jaxrs.ext.search;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -31,6 +32,7 @@ import java.util.Set;
  * {@link #isMet(Object)} description.
  * 
  * @param <T> type of search condition.
+ * 
  */
 public class SimpleSearchCondition<T> implements SearchCondition<T> {
 
@@ -43,12 +45,11 @@ public class SimpleSearchCondition<T> im
         supportedTypes.add(ConditionType.LESS_THAN);
         supportedTypes.add(ConditionType.LESS_OR_EQUALS);
     }
-    private ConditionType cType;
+    private ConditionType joiningType = ConditionType.AND;
     private T condition;
-    private Map<String, ConditionType> getters2operators;
-    private Map<String, Object> getters2values;
-    private Beanspector<T> beanspector;
-
+    
+    private List<SearchCondition<T>> scts;
+    
     /**
      * Creates search condition with same operator (equality, inequality) applied in all
comparison; see
      * {@link #isMet(Object)} for details of comparison.
@@ -66,9 +67,9 @@ public class SimpleSearchCondition<T> im
         if (!supportedTypes.contains(cType)) {
             throw new IllegalArgumentException("unsupported condition type: " + cType.name());
         }
-        this.cType = cType;
-        this.getters2operators = null;
         this.condition = condition;
+        scts = createConditions(null, cType);
+                
     }
 
     /**
@@ -91,14 +92,13 @@ public class SimpleSearchCondition<T> im
                                                + "not supported for primitive type "
                                                + condition.getClass().getName());
         }
+        this.condition = condition;
         for (ConditionType ct : getters2operators.values()) {
             if (!supportedTypes.contains(ct)) {
                 throw new IllegalArgumentException("unsupported condition type: " + ct.name());
             }
         }
-        this.cType = null;
-        this.getters2operators = getters2operators;
-        this.condition = condition;
+        scts = createConditions(getters2operators, null);
     }
 
     public T getCondition() {
@@ -111,13 +111,49 @@ public class SimpleSearchCondition<T> im
      * When constructor with map is used it returns null.
      */
     public ConditionType getConditionType() {
-        return cType;
+        if (scts.size() > 1) {
+            return joiningType;
+        } else {
+            return scts.get(0).getStatement().getCondition();
+        }
     }
 
-    public List<SearchCondition<T>> getConditions() {
-        return null;
+    public List<SearchCondition<T>> getSearchConditions() {
+        if (scts.size() > 1) {
+            return Collections.unmodifiableList(scts);
+        } else {
+            return null;
+        }
     }
 
+    private List<SearchCondition<T>> createConditions(Map<String, ConditionType>
getters2operators, 
+                                                      ConditionType sharedType) {
+        if (isPrimitive(condition)) {
+            return Collections.singletonList(
+                (SearchCondition<T>)new PrimitiveSearchCondition<T>(null, condition,
sharedType, condition));
+        } else {
+            List<SearchCondition<T>> list = new ArrayList<SearchCondition<T>>();
+            Map<String, Object> get2val = getGettersAndValues();
+            
+            for (String getter : get2val.keySet()) {
+                ConditionType ct = getters2operators == null ? sharedType : getters2operators.get(getter);
+                if (ct == null) {
+                    continue;
+                }
+                Object rval = get2val.get(getter);
+                if (rval == null) {
+                    continue;
+                }
+                list.add(new PrimitiveSearchCondition<T>(getter, rval, ct, condition));
+                
+            }
+            if (list.isEmpty()) {
+                throw new IllegalStateException("This search condition is empty and can not
be used");
+            }
+            return list;
+        }
+    }
+    
     /**
      * Compares given object against template condition object.
      * <p>
@@ -182,28 +218,12 @@ public class SimpleSearchCondition<T> im
      * @throws IllegalAccessException when security manager disallows reflective call of
getters.
      */
     public boolean isMet(T pojo) {
-        if (isPrimitive(pojo)) {
-            return compare(pojo, cType, condition);
-        } else {
-            boolean matches = false;
-            Map<String, Object> get2val = getGettersAndValues();
-            for (String getter : get2val.keySet()) {
-                ConditionType ct = cType;
-                if (ct == null) {
-                    ct = getters2operators.get(getter);
-                    if (ct == null) {
-                        continue;
-                    }
-                }
-                Object lval = getValue(getter, pojo);
-                Object rval = get2val.get(getter);
-                matches = compare(lval, ct, rval);
-                if (!matches) {
-                    break;
-                }
+        for (SearchCondition<T> sc : scts) {
+            if (!sc.isMet(pojo)) {
+                return false;
             }
-            return matches;
         }
+        return true;
     }
 
     /**
@@ -214,20 +234,19 @@ public class SimpleSearchCondition<T> im
      * @return template (condition) object getters mapped to their non-null values
      */
     private Map<String, Object> getGettersAndValues() {
-        if (getters2values == null) {
-            getters2values = new HashMap<String, Object>();
-            beanspector = new Beanspector<T>(condition);
-            for (String getter : beanspector.getGettersNames()) {
-                Object value = getValue(getter, condition);
-                getters2values.put(getter, value);
-            }
-            //we do not need compare class objects
-            getters2values.keySet().remove("class");
+        
+        Map<String, Object> getters2values = new HashMap<String, Object>();
+        Beanspector<T> beanspector = new Beanspector<T>(condition);
+        for (String getter : beanspector.getGettersNames()) {
+            Object value = getValue(beanspector, getter, condition);
+            getters2values.put(getter, value);
         }
+        //we do not need compare class objects
+        getters2values.keySet().remove("class");
         return getters2values;
     }
 
-    private Object getValue(String getter, T pojo) {
+    private Object getValue(Beanspector<T> beanspector, String getter, T pojo) {
         try {
             return beanspector.swap(pojo).getValue(getter);
         } catch (Throwable e) {
@@ -239,76 +258,6 @@ public class SimpleSearchCondition<T> im
         return pojo.getClass().getName().startsWith("java.lang");
     }
 
-    @SuppressWarnings("unchecked")
-    private boolean compare(Object lval, ConditionType cond, Object rval) {
-        boolean compares = true;
-        if (cond == ConditionType.EQUALS || cond == ConditionType.NOT_EQUALS) {
-            if (rval == null) {
-                compares = true;
-            } else if (lval == null) {
-                compares = false;
-            } else {
-                if (lval instanceof String) {
-                    compares = textCompare((String)lval, (String)rval);
-                } else {
-                    compares = lval.equals(rval);
-                }
-                if (cond == ConditionType.NOT_EQUALS) {
-                    compares = !compares;
-                }
-            }
-        } else {
-            if (lval instanceof Comparable && rval instanceof Comparable) {
-                Comparable lcomp = (Comparable)lval;
-                Comparable rcomp = (Comparable)rval;
-                int comp = lcomp.compareTo(rcomp);
-                switch (cond) {
-                case GREATER_THAN:
-                    compares = comp > 0;
-                    break;
-                case GREATER_OR_EQUALS:
-                    compares = comp >= 0;
-                    break;
-                case LESS_THAN:
-                    compares = comp < 0;
-                    break;
-                case LESS_OR_EQUALS:
-                    compares = comp <= 0;
-                    break;
-                default:
-                    String msg = String.format("Condition type %s is not supported", cond.name());
-                    throw new RuntimeException(msg);
-                }
-            }
-        }
-        return compares;
-    }
-
-    private boolean textCompare(String lval, String rval) {
-        // check wild cards
-        boolean starts = false;
-        boolean ends = false;
-        if (rval.charAt(0) == '*') {
-            starts = true;
-            rval = rval.substring(1);
-        }
-        if (rval.charAt(rval.length() - 1) == '*') {
-            ends = true;
-            rval = rval.substring(0, rval.length() - 1);
-        }
-        if (starts || ends) {
-            // wild card tests
-            if (starts && !ends) {
-                return lval.endsWith(rval);
-            } else if (ends && !starts) {
-                return lval.startsWith(rval);
-            } else {
-                return lval.contains(rval);
-            }
-        } else {
-            return lval.equals(rval);
-        }
-    }
 
     public List<T> findAll(Collection<T> pojos) {
         List<T> result = new ArrayList<T>();
@@ -320,4 +269,40 @@ public class SimpleSearchCondition<T> im
         return result;
     }
 
+    public String toSQL(String table, String... columns) {
+        if (isPrimitive(condition)) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        
+        if (table != null) {
+            SearchUtils.startSqlQuery(sb, table, columns);
+        }
+        
+        boolean first = true;
+        for (SearchCondition<T> sc : scts) {
+            PrimitiveStatement ps = sc.getStatement();
+            if (ps.getPropery() == null) {
+                continue;
+            }
+            if (!first) {
+                sb.append(" " + joiningType.toString() + " ");
+            } else {
+                first = false;
+            }
+            
+            sb.append(sc.toSQL(null));
+        }
+        return sb.toString();
+    }
+    
+    public PrimitiveStatement getStatement() {
+        if (scts.size() == 1) {
+            return scts.get(0).getStatement();
+        } else {
+            return null;
+        }
+    }
+    
+    
 }

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/FiqlParserTest.java
Thu Mar 25 22:49:26 2010
@@ -25,13 +25,12 @@ import java.util.Date;
 
 import javax.xml.datatype.DatatypeFactory;
 
+import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
-public class FiqlParserTest {
+public class FiqlParserTest extends Assert {
     private FiqlParser<Condition> parser = new FiqlParser<Condition>(Condition.class);
 
     @Test(expected = FiqlParseException.class)
@@ -155,6 +154,14 @@ public class FiqlParserTest {
         assertFalse(filter.isMet(new Condition("ami", 8, null)));
         assertFalse(filter.isMet(new Condition("am", 20, null)));
     }
+    
+    @Test
+    public void testSQL1() throws FiqlParseException {
+        SearchCondition<Condition> filter = parser.parse("name==ami*;level=gt=10");
+        String sql = filter.toSQL("table");
+        assertTrue("SELECT * FROM table WHERE name LIKE 'ami%' AND level > '10'".equals(sql)
+                   || "SELECT * FROM table WHERE level > '10' AND name LIKE 'ami%'".equals(sql));
+    }
 
     @Test
     public void testParseComplex2() throws FiqlParseException {
@@ -165,6 +172,14 @@ public class FiqlParserTest {
     }
 
     @Test
+    public void testSQL2() throws FiqlParseException {
+        SearchCondition<Condition> filter = parser.parse("name==ami*,level=gt=10");
+        String sql = filter.toSQL("table");
+        assertTrue("SELECT * FROM table WHERE (name LIKE 'ami%') OR (level > '10')".equals(sql)
+                   || "SELECT * FROM table WHERE (level > '10') OR (name LIKE 'ami%')".equals(sql));
+    }
+    
+    @Test
     public void testParseComplex3() throws FiqlParseException {
         SearchCondition<Condition> filter = parser.parse("name==foo*;(name!=*bar,level=gt=10)");
         assertTrue(filter.isMet(new Condition("fooooo", 0, null)));
@@ -174,6 +189,16 @@ public class FiqlParserTest {
     }
 
     @Test
+    public void testSQL3() throws FiqlParseException {
+        SearchCondition<Condition> filter = parser.parse("name==foo*;(name!=*bar,level=gt=10)");
+        String sql = filter.toSQL("table");
+        assertTrue(("SELECT * FROM table WHERE (name LIKE 'foo%') AND ((name NOT LIKE '%bar')
"
+                   + "OR (level > '10'))").equals(sql)
+                   || ("SELECT * FROM table WHERE (name LIKE 'foo%') AND "
+                   + "((level > '10') OR (name NOT LIKE '%bar'))").equals(sql));
+    }
+    
+    @Test
     public void testParseComplex4() throws FiqlParseException {
         SearchCondition<Condition> filter = parser.parse("name==foo*;name!=*bar,level=gt=10");
         assertTrue(filter.isMet(new Condition("zonk", 20, null)));
@@ -181,7 +206,7 @@ public class FiqlParserTest {
         assertTrue(filter.isMet(new Condition("foobar", 20, null)));
         assertFalse(filter.isMet(new Condition("fooxxxbar", 0, null)));
     }
-
+    
     @Ignore
     static class Condition {
         private String name;

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchConditionTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchConditionTest.java?rev=927626&r1=927625&r2=927626&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchConditionTest.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/search/SimpleSearchConditionTest.java
Thu Mar 25 22:49:26 2010
@@ -155,7 +155,7 @@ public class SimpleSearchConditionTest {
 
     @Test
     public void testGetConditions() {
-        assertEquals(cGt.getConditions(), null);
+        assertEquals(cGt.getSearchConditions(), null);
     }
 
     @Test



Mime
View raw message