Author: ppoddar
Date: Mon Dec 15 16:02:12 2008
New Revision: 726879

URL: http://svn.apache.org/viewvc?rev=726879&view=rev
Log:
OPENJPA-800: Introduce OpenJPAQueryBuilder interface. Implement CONCAT() and 
other String functions.

Added:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/FrequentFlierPlan.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Transaction.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OpenJPAQueryBuilder.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/VarArgsExpression.java
Modified:
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/CreditCard.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Employee.java
    
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ArrayExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BetweenExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryExpressionPredicate.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryOperatorExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/CaseExpressionImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ConcatExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ElseExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsEmptyExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsNullExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JPQLHelper.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LikeExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LocateExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RangeExpression.java
    
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/TrimExpression.java

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/CreditCard.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/CreditCard.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/CreditCard.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/CreditCard.java
 Mon Dec 15 16:02:12 2008
@@ -21,6 +21,8 @@
 import java.util.List;
 
 import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
 import javax.persistence.OrderBy;
 import javax.persistence.Table;
 
@@ -28,8 +30,10 @@
 @Table(name="CR_CREDITCARD")
 
 public class CreditCard {
-       private String holdr;
+       @OneToOne
+       private Employee holder;
        
+       @OneToMany
        @OrderBy
-       private List<String> transactionHistory;
+       private List<Transaction> transactionHistory;
 }

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Employee.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Employee.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Employee.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Employee.java
 Mon Dec 15 16:02:12 2008
@@ -39,5 +39,8 @@
        private Employee spouse;
        @ManyToOne
        private Manager manager;
+       
+       @OneToOne
+       FrequentFlierPlan frequentFlierPlan;
 
 }

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/FrequentFlierPlan.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/FrequentFlierPlan.java?rev=726879&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/FrequentFlierPlan.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/FrequentFlierPlan.java
 Mon Dec 15 16:02:12 2008
@@ -0,0 +1,9 @@
+package org.apache.openjpa.persistence.criteria;
+
+import javax.persistence.Entity;
+
+...@entity
+public class FrequentFlierPlan {
+       private String name;
+       private int annualMiles;
+}

Modified: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestCriteria.java
 Mon Dec 15 16:02:12 2008
@@ -20,30 +20,32 @@
 package org.apache.openjpa.persistence.criteria;
 
 import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
 
-import javax.persistence.CaseExpression;
 import javax.persistence.DomainObject;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Expression;
 import javax.persistence.Query;
-import javax.persistence.QueryBuilder;
 import javax.persistence.QueryDefinition;
 import javax.persistence.SelectItem;
 
-import org.apache.openjpa.kernel.jpql.ParseException;
-import org.apache.openjpa.persistence.query.AbstractDomainObject;
+import org.apache.openjpa.persistence.query.OpenJPAQueryBuilder;
 import org.apache.openjpa.persistence.query.QueryBuilderImpl;
-import org.apache.openjpa.persistence.query.QueryDefinitionImpl;
 import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
 
 /**
- * Tests QueryDefinition and comparing the resultant string
- * with an equivalent JPQL.
+ * Tests QueryDefinition via a set of example use cases from Criteria API 
+ * Section of Java Persistence API Version 2.0 [1].
  * 
- * The examples are taken from Criteria API Section of Java Persistence API 
- * Version 2.0 [1].
+ * For each use case, a corresponding JPQL String is specified. The dynamically
+ * constructed QueryDefinition and JPQL are both executed and their results
+ * are compared for verification. As some of the use cases employ few 
+ * yet unimplemented JPQL 2.0 constructs such as KEY() or INDEX() or CASE, 
+ * when such queries fail to execute, the JPQL String is literally compared
+ * to the stringified QueryDefinition.
  * 
  * [1] <A 
href="http://jcp.org/aboutJava/communityprocess/pr/jsr317/index.html";>
  * JPA API Specification Version 2.0</A>
@@ -52,7 +54,7 @@
  *
  */
 public class TestCriteria extends SingleEMFTestCase {
-       protected QueryBuilderImpl qb; 
+       protected OpenJPAQueryBuilder qb; 
        private static EntityManagerFactory emf = null;
        protected StringComparison comparator = new StringComparison();
        
@@ -69,6 +71,7 @@
                                Department.class, 
                                Employee.class, 
                                Exempt.class, 
+                               FrequentFlierPlan.class,
                                Item.class,
                                LineItem.class,
                                Manager.class, 
@@ -77,7 +80,9 @@
                                Phone.class,
                                Photo.class,
                                Student.class, 
-                               VideoStore.class);
+                               Transaction.class,
+                               VideoStore.class,
+                               "openjpa.Log","SQL=TRACE, Query=TRACE");
                        emf = super.emf;
                } 
                qb = (QueryBuilderImpl)emf.getQueryBuilder();
@@ -139,7 +144,7 @@
                String jpql = "select i.name, VALUE(p)"
                                + " from Item i join i.photos p"
                                + " where KEY(p) like 'egret'";
-               compare(jpql, qdef, "VALUE(p) not supported");
+               compare(jpql, qdef);
        }
        
        public void testLiteral() {
@@ -163,7 +168,7 @@
                String jpql = "select TYPE(e)" +
                              " from Employee e" +
                              " where TYPE(e) <> Exempt";
-               compare(jpql, e, "Type() not supported");
+               compare(jpql, e);
        }
 
        public void testIndex() {
@@ -175,7 +180,7 @@
                String jpql = "select s.name" +
                              " from Course c join c.studentWaitList s" +
                              " where c.name = 'Calculus' and INDEX(s) = 0";
-               compare(jpql, c, "Index() not supported");
+               compare(jpql, c);
        }
        
        public void testSum() {
@@ -254,7 +259,7 @@
                              " where c.holder.name = 'John Doe' AND INDEX(t) " 
+
                              " BETWEEN 0 AND 9";
                
-               compare(jpql, c, "Index() not supported");
+               compare(jpql, c);
        }
        
        public void testIsEmpty() {
@@ -288,10 +293,9 @@
                DomainObject customer = q.addRoot(Customer.class);
                DomainObject order = customer.join("orders");
                q.where(order.get("count").greaterThan(100))
-               .select(q.newInstance(Customer.class,
-               customer.get("id"),
-               customer.get("status"),
-               order.get("count")));
+                .select(q.newInstance(Customer.class, customer.get("id"),
+                                                      customer.get("status"),
+                                                      order.get("count")));
                
                
                String jpql = "SELECT NEW 
org.apache.openjpa.persistence.criteria.Customer" 
@@ -302,30 +306,27 @@
        }
        
        public void testKeyValueOperatorPath() {
-       QueryDefinition q = qb.createQueryDefinition();
-       DomainObject v = q.addRoot(VideoStore.class);
-       DomainObject i = v.join("videoInventory");
-       q.where(v.get("location").get("zipCode").equal("94301")
-       .and(i.value().greaterThan(0)));
-       q.select(v.get("location").get("street"),
-       i.key().get("title"),
-       i.value());
-       
-       String jpql = "SELECT v.location.street, KEY(v2).title, VALUE(v2)" 
-                               + " FROM VideoStore v JOIN v.videoInventory v2"
-                               + " WHERE v.location.zipCode = '94301' AND 
VALUE(v2) > 0";
-       
-       compare(jpql, q, "KEY() and/or VALUE() not supported");
+               QueryDefinition q = qb.createQueryDefinition();
+               DomainObject v = q.addRoot(VideoStore.class);
+               DomainObject i = v.join("videoInventory");
+               q.where(v.get("location").get("zipCode").equal("94301")
+                .and(i.value().greaterThan(0)));
+               q.select(v.get("location").get("street"), i.key().get("title"), 
i.value());
+               
+               String jpql = "SELECT v.location.street, KEY(v2).title, 
VALUE(v2)" 
+                                       + " FROM VideoStore v JOIN 
v.videoInventory v2"
+                                       + " WHERE v.location.zipCode = '94301' 
AND VALUE(v2) > 0";
+               
+               compare(jpql, q);
        }
        
        public void testGroupByHaving() {
                QueryDefinition q = qb.createQueryDefinition();
                DomainObject customer = q.addRoot(Customer.class);
-               q.select(customer.get("status"),
-               customer.get("filledOrderCount").avg(),
-               customer.count())
-               .groupBy(customer.get("status"))
-               .having(customer.get("status").in(1, 2));
+               q.select(customer.get("status"), 
customer.get("filledOrderCount").avg(),
+                        customer.count())
+                .groupBy(customer.get("status"))
+                .having(customer.get("status").in(1, 2));
                
                String jpql = "SELECT c.status, AVG(c.filledOrderCount), 
COUNT(c)"
                                        + " FROM Customer c"
@@ -338,10 +339,9 @@
        public void testGroupByHaving2() {
                QueryDefinition q = qb.createQueryDefinition();
                DomainObject customer = q.addRoot(Customer.class);
-               q.select(customer.get("country"),
-               customer.count())
-               .groupBy(customer.get("country"))
-               .having(customer.count().greaterThan(30));
+               q.select(customer.get("country"), customer.count())
+                .groupBy(customer.get("country"))
+                .having(customer.count().greaterThan(30));
                
                String jpql = "SELECT c.country, COUNT(c)" 
                                        + " FROM Customer c"
@@ -437,7 +437,7 @@
                        + " FROM Employee e"
                        + " WHERE TYPE(e) IN (Exempt, Contractor)";
                
-               compare(jpql, q, "Type() not supported");
+               compare(jpql, q);
        }
        
        public void testStringList() {
@@ -456,16 +456,16 @@
                Expression c = 
                
e.generalCase().when(f.get("annualMiles").greaterThan(50000)).then("Platinum")
                               
.when(f.get("annualMiles").greaterThan(25000)).then("Gold")
-                              .elseCase("");
+                              .elseCase("XYZ");
                e.select(e.get("name"), f.get("name"), 
e.concat(c,e.literal("Frequent Flyer")));
                
                String jpql = "SELECT e.name, f.name, CONCAT(" 
                        + " CASE WHEN f.annualMiles > 50000 THEN 'Platinum'" 
                        + " WHEN f.annualMiles > 25000 THEN 'Gold'" 
-                       + " ELSE '' END, 'Frequent Flyer')" 
+                       + " ELSE 'XYZ' END, 'Frequent Flyer')" 
                        + " FROM Employee e JOIN e.frequentFlierPlan f";
                        
-               compare(jpql, e, "Case not supported");
+               compare(jpql, e);
        }
        
        public void testCorrelatedSubquerySpecialCase1() {
@@ -478,7 +478,7 @@
                                + " where 10000 < ALL "
                                + " (select a.balance from o.customer c join 
o.customer.accounts a)";
                
-               compare(jpql, o, "SubQuery generates invalid SQL on Derby");
+               compare(jpql, o);
        }
        
        public void testCorrelatedSubquerySpecialCase2() {
@@ -492,7 +492,7 @@
                                + " where 10000 < ALL "
                                + " (select a.balance from c.accounts a)";
                
-               compare(jpql, o, "SubQuery generates invalid SQL on Derby");
+               compare(jpql, o);
        }
        
        public void testRecursiveDefinitionIsNotAllowed() {
@@ -516,7 +516,7 @@
         * QueryDefinition. 
         */
        void compare(String jpql, QueryDefinition q) {
-               compare(jpql, q, null, (Object[])null);
+               compare(jpql, q, (Object[])null);
        }
        
        /**
@@ -524,15 +524,8 @@
         * If skip is null then execute both queries against the database, 
otherwise
         * compare them literally. 
         */
-       void compare(String jpql, QueryDefinition q, String skip, Object...p) {
-               boolean execute = (skip == null);
-               if (execute) {
-                       executeActually(jpql, q, p);
-               } else {
-                       System.err.println("***WARN: " + this.getName()  
-                               + ": skips executing ["+ jpql + "] because " + 
skip);
-                       compareLiterally(jpql, q);
-               }
+       void compare(String jpql, QueryDefinition q, Object...p) {
+               executeActually(jpql, q, p);
        }
        
        /**
@@ -582,11 +575,12 @@
                                        + "JPQL [" + jpql + "]\r\n"
                                        + "error : " + jpqlError.getMessage());
                } else {
-                       fail("Both JPQL and QueryDefinition failed to 
execute.\r\n"
-                         + "JPQL " + jpql + "\r\n"
-                         + "error :" + jpqlError.getMessage() + "\r\n"
-                         + "Criteria " + qb.toJPQL(q) + "\r\n"
-                         + "error : " + criteriaError.getMessage());
+                       System.err.println("WARN: Both JPQL and QueryDefinition 
are invalid"
+                                         + "\r\nJPQL " + jpql + "\r\n"
+                                         + "error :" + jpqlError.getMessage() 
+ "\r\n"
+                                         + "Criteria " + qb.toJPQL(q) + "\r\n"
+                                         + "error : " + 
criteriaError.getMessage());
+                       compareLiterally(jpql, q);
                }
        }
        
    void setParameters(Query q, Object...p) {

Added: 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Transaction.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Transaction.java?rev=726879&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Transaction.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/Transaction.java
 Mon Dec 15 16:02:12 2008
@@ -0,0 +1,10 @@
+package org.apache.openjpa.persistence.criteria;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+...@entity
+...@table(name="CR_TRANSACTION")
+public class Transaction {
+
+}

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
 Mon Dec 15 16:02:12 2008
@@ -46,6 +46,7 @@
 import org.apache.openjpa.lib.conf.Value;
 import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.persistence.query.OpenJPAQueryBuilder;
 import org.apache.openjpa.persistence.query.QueryBuilderImpl;
 import org.apache.openjpa.util.OpenJPAException;
 import serp.util.Strings;
@@ -342,7 +343,7 @@
             "JPA 2.0 - Method not yet implemented");
     }
 
-    public QueryBuilder getQueryBuilder() {
+    public OpenJPAQueryBuilder getQueryBuilder() {
        return new QueryBuilderImpl(this);
     }
 

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
 Mon Dec 15 16:02:12 2008
@@ -67,6 +67,7 @@
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.QueryMetaData;
 import org.apache.openjpa.meta.SequenceMetaData;
+import org.apache.openjpa.persistence.query.OpenJPAQueryBuilder;
 import org.apache.openjpa.persistence.query.QueryBuilderImpl;
 import org.apache.openjpa.util.Exceptions;
 import org.apache.openjpa.util.ImplHelper;
@@ -1414,7 +1415,7 @@
             "JPA 2.0 - Method not yet implemented");
     }
 
-    public QueryBuilderImpl getQueryBuilder() {
+    public OpenJPAQueryBuilder getQueryBuilder() {
         return new QueryBuilderImpl(_emf);
     }
 

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/AbstractVisitable.java
 Mon Dec 15 16:02:12 2008
@@ -26,7 +26,12 @@
  *
  */
 abstract class AbstractVisitable implements Visitable {
-
+       public static final String SPACE = " ";
+       public static final String OPEN_BRACE = "(";
+       public static final String CLOSE_BRACE = ")";
+       public static final String COMMA = ",";
+       public static final String EMPTY = "";
+       
        public String asExpression(AliasContext ctx) {
                throw new 
UnsupportedOperationException(this.getClass().getName());
        }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ArrayExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ArrayExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ArrayExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ArrayExpression.java
 Mon Dec 15 16:02:12 2008
@@ -1,7 +1,32 @@
+/*
+ * 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.openjpa.persistence.query;
 
-import java.util.Arrays;
 
+/**
+ * A single expression that holds an array of values. Used as the second 
operand 
+ * in e1 IN(e2) expression, for example. Different than 
+ * {...@link VarArgsExpression} which represents multiple expressions.  
+ * 
+ * @author Pinaki Poddar
+ *
+ */
 public class ArrayExpression extends ExpressionImpl {
        private final Object[] _values;
        
@@ -11,12 +36,14 @@
 
        @Override
        public String asExpression(AliasContext ctx) {
-               StringBuffer tmp = new StringBuffer("(");
+               StringBuffer tmp = new StringBuffer(OPEN_BRACE);
                for (int i = 0; i < _values.length; i++) {
-                       tmp.append(JPQLHelper.toJPQL(ctx, _values[i]))
-                          .append(i == _values.length-1 ? "" : ", ");
+                       Object v = _values[i];
+                       tmp.append((v instanceof Visitable ? 
+                               ((Visitable)v).asExpression(ctx) : 
JPQLHelper.toJPQL(ctx, v)))
+                          .append(i == _values.length-1 ? EMPTY : COMMA + 
SPACE);
                }
-               tmp.append(")");
+               tmp.append(CLOSE_BRACE);
                return tmp.toString();
        }
 
@@ -24,5 +51,4 @@
        public String asProjection(AliasContext ctx) {
                return asExpression(ctx);
        }
-
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BetweenExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BetweenExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BetweenExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BetweenExpression.java
 Mon Dec 15 16:02:12 2008
@@ -32,8 +32,4 @@
                super(arg1, BinaryConditionalOperator.BETWEEN, 
                        BinaryConditionalOperator.BETWEEN_NOT, arg2);
        }
-       
-//     public String toJPQL(AliasContext ctx) {
-//             return super.toJPQL(ctx) + " AND " + 
((ExpressionImpl)arg3).toJPQL(ctx);
-//     }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryExpressionPredicate.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryExpressionPredicate.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryExpressionPredicate.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryExpressionPredicate.java
 Mon Dec 15 16:02:12 2008
@@ -33,6 +33,7 @@
        protected final Expression _e2;
        protected final BinaryConditionalOperator   _op;
        private final BinaryConditionalOperator   _nop;
+       private static final StringBuffer SPACE = new StringBuffer(" ");
        
        BinaryExpressionPredicate(Expression e1, BinaryConditionalOperator op, 
                BinaryConditionalOperator nop, Expression e2) {
@@ -70,7 +71,7 @@
 
        public String asExpression(AliasContext ctx) {
                return ((Visitable)_e1).asExpression(ctx) 
-                    + " " + _op + " "
+                    + SPACE + _op + SPACE
                     + ((Visitable)_e2).asExpression(ctx);
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryOperatorExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryOperatorExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryOperatorExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/BinaryOperatorExpression.java
 Mon Dec 15 16:02:12 2008
@@ -51,13 +51,15 @@
        }
        
        public String asExpression(AliasContext ctx) {
-               return ((Visitable)_e1).asExpression(ctx) + _op 
-                    + ((Visitable)_e2).asExpression(ctx);
+               return ((Visitable)_e1).asExpression(ctx)
+                       + _op 
+                   + ((Visitable)_e2).asExpression(ctx);
        }
        
        public String asProjection(AliasContext ctx) {
-               return ((Visitable)_e1).asProjection(ctx) + _op 
-                    + ((Visitable)_e2).asProjection(ctx) 
+               return ((Visitable)_e1).asProjection(ctx)
+                        + _op 
+                    + (((Visitable)_e2).asProjection(ctx))
                     + (ctx.hasAlias(this) ? " as " + ctx.getAlias(this) : "");
 
        }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/CaseExpressionImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/CaseExpressionImpl.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/CaseExpressionImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/CaseExpressionImpl.java
 Mon Dec 15 16:02:12 2008
@@ -26,7 +26,7 @@
 import javax.persistence.Expression;
 import javax.persistence.Predicate;
 
-public class CaseExpressionImpl implements CaseExpression {
+public class CaseExpressionImpl implements CaseExpression, Visitable {
        private LinkedList<WhenClause> _whens = new LinkedList<WhenClause>();
        private final Object _caseOperand;
        
@@ -43,27 +43,27 @@
        }
 
        public Expression elseCase(String arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public Expression elseCase(Number arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public Expression elseCase(Date arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public Expression elseCase(Calendar arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public Expression elseCase(Class arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public Expression elseCase(Enum<?> arg) {
-               return new ElseExpression(this, arg);
+               return new ElseExpression(this, new ConstantExpression(arg));
        }
 
        public CaseExpression then(Expression then) {
@@ -176,7 +176,7 @@
                        throw new IllegalStateException("then() can not be 
called now");
        }
        
-       public String toJPQL(AliasContext ctx) {
+       public String asExpression(AliasContext ctx) {
                StringBuffer tmp = new StringBuffer("CASE ");
                if (_caseOperand != null) {
                        tmp.append(toJPQL(ctx, _caseOperand));
@@ -187,6 +187,19 @@
                return tmp.toString();
        }
        
+       public String asProjection(AliasContext ctx) {
+               return asExpression(ctx);
+       }
+       
+       public String asJoinable(AliasContext ctx) {
+               throw new UnsupportedOperationException();
+       }
+       
+       public String getAliasHint(AliasContext ctx) {
+               throw new UnsupportedOperationException();
+       }
+       
+       
 
        String toJPQL(AliasContext ctx, Object o) {
                if (o instanceof Visitable) {

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ConcatExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ConcatExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ConcatExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ConcatExpression.java
 Mon Dec 15 16:02:12 2008
@@ -26,7 +26,7 @@
  *
  */
 public class ConcatExpression extends UnaryOperatorExpression {
-       public ConcatExpression(ArrayExpression op) {
+       public ConcatExpression(VarArgsExpression op) {
                super(op, UnaryFunctionalOperator.CONCAT);
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ElseExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ElseExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ElseExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ElseExpression.java
 Mon Dec 15 16:02:12 2008
@@ -18,6 +18,8 @@
  */
 package org.apache.openjpa.persistence.query;
 
+import javax.persistence.Expression;
+
 /**
  * Else clause in a Case Statement.
  * 
@@ -26,24 +28,24 @@
  */
 public class ElseExpression extends ExpressionImpl {
        private final CaseExpressionImpl _caseClause;
-       private final Object _elseClause;
+       private final Expression _elseClause;
        
-       public ElseExpression(CaseExpressionImpl owner, Object op) {
+       public ElseExpression(CaseExpressionImpl owner, Expression op) {
                _caseClause = owner;
                _elseClause = op;
        }
        
        @Override
        public String asExpression(AliasContext ctx) {
-               return _caseClause.toJPQL(ctx) 
-                   + " ELSE " + JPQLHelper.toJPQL(ctx, _elseClause) 
-                   + " END ";
+               return ((Visitable)_caseClause).asExpression(ctx) 
+                   + " ELSE " + ((Visitable)_elseClause).asExpression(ctx) 
+                   + " END";
        }
        
        @Override
        public String asProjection(AliasContext ctx) {
-               return _caseClause.toJPQL(ctx) 
-                    + " ELSE " + JPQLHelper.toJPQL(ctx, _elseClause) 
-                    + " END ";
+               return ((Visitable)_caseClause).asProjection(ctx) 
+           + " ELSE " + ((Visitable)_elseClause).asProjection(ctx) 
+           + " END";
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/ExpressionImpl.java
 Mon Dec 15 16:02:12 2008
@@ -45,11 +45,14 @@
        }
 
        public Expression concat(String... str) {
-               return new ConcatExpression(new ArrayExpression(str));
+               ConstantExpression[] exprs = new ConstantExpression[str.length];
+               for (int i = 0; i < str.length; i++)
+                       exprs[i] = new ConstantExpression(str[i]);
+               return new ConcatExpression(new VarArgsExpression(exprs));
        }
 
-       public Expression concat(Expression... str) {
-               return new ConcatExpression(new ArrayExpression(str));
+       public Expression concat(Expression... exprs) {
+               return new ConcatExpression(new VarArgsExpression(exprs));
        }
 
        public Expression dividedBy(Number num) {

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/FetchPath.java
 Mon Dec 15 16:02:12 2008
@@ -36,13 +36,11 @@
        
        @Override
        public String asJoinable(AliasContext ctx) {
-               StringBuffer tmp = new StringBuffer(getOperator().toString());
-               tmp.append(getParent().asProjection(ctx))
-                  .append(NAVIGATION)
-                  .append(getLastSegment())
-                  .append(" ");
-               
-               return tmp.toString();
+               return getOperator() 
+                    + getParent().asProjection(ctx) 
+                    + NAVIGATION 
+                    + getLastSegment() 
+                    + SPACE;
        }
 
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsEmptyExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsEmptyExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsEmptyExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsEmptyExpression.java
 Mon Dec 15 16:02:12 2008
@@ -11,6 +11,6 @@
        
        @Override
        public String asExpression(AliasContext ctx) {
-               return ((Visitable)_e).asExpression(ctx) + " " + _op;
+               return ((Visitable)_e).asExpression(ctx) + SPACE + _op;
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsNullExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsNullExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsNullExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/IsNullExpression.java
 Mon Dec 15 16:02:12 2008
@@ -34,6 +34,6 @@
 
        @Override
        public String asExpression(AliasContext ctx) {
-               return ((Visitable)_e).asExpression(ctx) + " " + _op;
+               return ((Visitable)_e).asExpression(ctx) + SPACE + _op;
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JPQLHelper.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JPQLHelper.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JPQLHelper.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JPQLHelper.java
 Mon Dec 15 16:02:12 2008
@@ -25,7 +25,7 @@
  *
  */
 public class JPQLHelper {
-       private static final String SINGLE_QUOTE = "'";
+       private static final StringBuffer SINGLE_QUOTE = new StringBuffer("'");
        
        static String toJPQL(AliasContext ctx, Object o) {
                if (o == null)

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/JoinPath.java
 Mon Dec 15 16:02:12 2008
@@ -61,14 +61,18 @@
        public String asExpression(AliasContext ctx) {
                if (ctx.hasAlias(this))
                        return ctx.getAlias(this);
-               return getParent().asExpression(ctx) + NAVIGATION + 
getLastSegment();
+               return getParent().asExpression(ctx)
+                      + NAVIGATION
+                      + getLastSegment();
        }
        
        @Override
        public String asProjection(AliasContext ctx) {
                if (ctx.hasAlias(this))
                        return ctx.getAlias(this);
-               return getParent().asProjection(ctx) + NAVIGATION + 
getLastSegment();
+               return getParent().asProjection(ctx)
+                      + NAVIGATION
+                      + getLastSegment();
        }
        
        public String toString() {

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LikeExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LikeExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LikeExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LikeExpression.java
 Mon Dec 15 16:02:12 2008
@@ -48,7 +48,7 @@
        @Override
        public String asExpression(AliasContext ctx) {
                return super.asExpression(ctx) 
-                   + (_escaped ? "ESCAPE " + JPQLHelper.toJPQL(ctx, _echar) : 
"");
+                   + (_escaped ? "ESCAPE " + JPQLHelper.toJPQL(ctx, _echar) : 
EMPTY);
        }
 
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LocateExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LocateExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LocateExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/LocateExpression.java
 Mon Dec 15 16:02:12 2008
@@ -53,10 +53,14 @@
        }
        
        public String asExpression(AliasContext ctx) {
-               return _op + "(" + ((Visitable)_e1).asExpression(ctx) + "," 
-                   + ((Visitable)_e2).asExpression(ctx) 
-                   + (_start == null ? "" : "," + 
((Visitable)_start).asExpression(ctx))
-                   + ")";
+               String start = _start == null ? EMPTY : COMMA + 
((Visitable)_start).asExpression(ctx);
+               return new StringBuffer(_op.toString())
+                   .append(OPEN_BRACE)
+                   .append(((Visitable)_e1).asExpression(ctx))
+                   .append(COMMA) 
+                   .append(((Visitable)_e2).asExpression(ctx)) 
+                   .append(start)
+                   .append(CLOSE_BRACE).toString();
        }
 
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/NavigationPath.java
 Mon Dec 15 16:02:12 2008
@@ -62,11 +62,11 @@
         */
        @Override
        public String asJoinable(AliasContext ctx) {
-               return asProjection(ctx) + " " + ctx.getAlias(this);
+               return asProjection(ctx) + SPACE + ctx.getAlias(this);
        }
        
        public String toString() {
-               return getParent().toString()+"."+getLastSegment();
+               return getParent().toString()+ NAVIGATION +getLastSegment();
        }
 
 }

Added: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OpenJPAQueryBuilder.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OpenJPAQueryBuilder.java?rev=726879&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OpenJPAQueryBuilder.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/OpenJPAQueryBuilder.java
 Mon Dec 15 16:02:12 2008
@@ -0,0 +1,47 @@
+/*
+ * 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.openjpa.persistence.query;
+
+import javax.persistence.Query;
+import javax.persistence.QueryBuilder;
+import javax.persistence.QueryDefinition;
+
+/**
+ * An extension of standard JPA Specification interface to add equivalence of 
+ * QueryDefinition and Query and JPQL String.
+ *  
+ * @author Pinaki Poddar
+ *
+ */
+public interface OpenJPAQueryBuilder extends QueryBuilder {
+       /**
+        * Create a QueryDefinition from the given JPQL String.
+        */
+       public QueryDefinition createQueryDefinition(String jpql);
+       
+       /**
+        * Create a QueryDefinition from the given OpenJPA Query instance.
+        */
+       public QueryDefinition createQueryDefinition(Query jpql);
+       
+       /**
+        * Gets equivalent JPQL String for the given QueryDefinition.
+        */
+       public String toJPQL(QueryDefinition qdef);
+}

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/QueryBuilderImpl.java
 Mon Dec 15 16:02:12 2008
@@ -20,7 +20,7 @@
 
 import javax.persistence.DomainObject;
 import javax.persistence.PathExpression;
-import javax.persistence.QueryBuilder;
+import javax.persistence.Query;
 import javax.persistence.QueryDefinition;
 
 import org.apache.openjpa.meta.MetaDataRepository;
@@ -33,7 +33,7 @@
  * @author Pinaki Poddar
  *
  */
-public class QueryBuilderImpl implements QueryBuilder {
+public class QueryBuilderImpl implements OpenJPAQueryBuilder {
        private final OpenJPAEntityManagerFactorySPI _emf;
        
        public QueryBuilderImpl(OpenJPAEntityManagerFactorySPI emf) {
@@ -63,10 +63,19 @@
        }
        
        public String toJPQL(QueryDefinition query) {
-               MetaDataRepository repos = 
null;//_emf.getConfiguration().getMetaDataRepositoryInstance()
+               MetaDataRepository repos = _emf.getConfiguration()
+                       .getMetaDataRepositoryInstance();
                AliasContext ctx = new AliasContext(repos);
                if (query instanceof AbstractDomainObject)
                        return 
((AbstractDomainObject)query).getOwner().asExpression(ctx);
                return ((QueryDefinitionImpl)query).asExpression(ctx);
        }
+       
+       public QueryDefinition createQueryDefinition(String jpql) {
+               throw new UnsupportedOperationException();
+       }
+       
+       public QueryDefinition createQueryDefinition(Query jpql) {
+               throw new UnsupportedOperationException();              
+       }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RangeExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RangeExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RangeExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/RangeExpression.java
 Mon Dec 15 16:02:12 2008
@@ -21,7 +21,7 @@
 import javax.persistence.Expression;
 
 /**
- * Denotes a range used by MEMBER OF operation.
+ * Denotes a range used by e1 BETWEEN x AND y operation.
  * 
  * @author Pinaki Poddar
  *
@@ -33,7 +33,7 @@
        
        @Override
        public String asExpression(AliasContext ctx) {
-               return "(" + ((Visitable)_e1).asExpression(ctx) 
-                    + " AND " + ((Visitable)_e2).asExpression(ctx) + ")";
+               return ((Visitable)_e1).asExpression(ctx) 
+                    + " AND " + ((Visitable)_e2).asExpression(ctx);
        }
 }

Modified: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/TrimExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/TrimExpression.java?rev=726879&r1=726878&r2=726879&view=diff
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/TrimExpression.java
 (original)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/TrimExpression.java
 Mon Dec 15 16:02:12 2008
@@ -29,27 +29,35 @@
  */
 public class TrimExpression extends UnaryOperatorExpression {
        private final Expression _trimChar;
-       private final TrimSpec _spec;
-       private static final String BLANK = "' '";
+       private final TrimSpec _trimSpec;
+       private static final String DEFAULT_TRIM_CHAR = "' '";
+       private static final String DEFAULT_TRIM_SPEC = EMPTY;
        
        public TrimExpression(Expression op, char ch, TrimSpec spec) {
                super(op, UnaryFunctionalOperator.TRIM);
                _trimChar = new ConstantExpression(ch);
-               _spec     = spec;
+               _trimSpec     = spec;
        }
        
        public TrimExpression(Expression op, Expression ch, TrimSpec spec) {
                super(op, UnaryFunctionalOperator.TRIM);
                _trimChar = ch;
-               _spec = spec;
+               _trimSpec = spec;
        }
        
        public String asExpression(AliasContext ctx) {
-               String trim = _trimChar == null ? BLANK 
+               String trimChar = _trimChar == null ? DEFAULT_TRIM_CHAR 
                        : ((Visitable)_trimChar).asExpression(ctx);
-               String spec = _spec == null ? "" : _spec.toString();
-               return _op + "(" + spec + " " + trim + " FROM " 
-                       + ((Visitable)_e).asExpression(ctx) + ")";
+               String trimSpec = _trimSpec == null ? DEFAULT_TRIM_SPEC : 
+                       _trimSpec.toString();
+               return _op.toString()
+                      + OPEN_BRACE
+                      + trimSpec
+                          + SPACE
+                          + trimChar
+                          + " FROM "
+                          + ((Visitable)_e).asExpression(ctx)
+                          + CLOSE_BRACE;
        }
 
 }

Added: 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/VarArgsExpression.java
URL: 
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/VarArgsExpression.java?rev=726879&view=auto
==============================================================================
--- 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/VarArgsExpression.java
 (added)
+++ 
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/query/VarArgsExpression.java
 Mon Dec 15 16:02:12 2008
@@ -0,0 +1,56 @@
+/*
+ * 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.openjpa.persistence.query;
+
+import java.util.Arrays;
+
+import javax.persistence.Expression;
+
+/**
+ * A expression that holds an array of Expressions. Used as operand for 
+ * CONCAT(e1,e2,e3,...), for example. Different than {...@link 
ArrayExpression} 
+ * which represents a single expression with array of values. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class VarArgsExpression extends ExpressionImpl {
+       private final Expression[] _values;
+       
+       public VarArgsExpression(Expression[] values) {
+               _values = values;
+       }
+
+       @Override
+       public String asExpression(AliasContext ctx) {
+               StringBuffer tmp = new StringBuffer();
+               for (int i = 0; i < _values.length; i++) {
+                       Visitable v = (Visitable)_values[i];
+                       tmp.append(v.asExpression(ctx))
+                          .append(i == _values.length-1 ? "" : ", ");
+               }
+               return tmp.toString();
+       }
+
+       @Override
+       public String asProjection(AliasContext ctx) {
+               return asExpression(ctx);
+       }
+
+}


Reply via email to