OPENJPA-806: Initial Criteria API implementation.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@723553 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2008-12-05 01:37:13 +00:00
parent 55b1fa6cd3
commit 4c4219fc22
99 changed files with 5710 additions and 2 deletions

View File

@ -0,0 +1,39 @@
/*
* 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.criteria;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
/**
* Used for testing Criteria API.
* The fields are sometimes not declared as there is no validation yet during
* Query construction.
*
* @author Pinaki Poddar
*
*/
@Entity
public class Address {
private String zipCode;
@OneToMany
private List<Phone> phones;
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.OneToOne;
public class Contact {
@OneToOne
private Address address;
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Contractor {
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Course {
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class CreditCard {
}

View File

@ -0,0 +1,27 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Customer {
private String firstName;
private String lastName;
}

View File

@ -0,0 +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.criteria;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
@Entity
public class Department {
private int deptNo;
private String name;
@OneToMany
private Set<Employee> employees;
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Employee {
private Address contactInfo;
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Exempt {
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Item {
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Manager {
}

View File

@ -0,0 +1,33 @@
/*
* 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.criteria;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="C_ORDER")
public class Order {
private int quantity;
@ManyToOne
private Customer customer;
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Person {
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class Phone {
private String vendor;
}

View File

@ -0,0 +1,121 @@
/*
* 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.criteria;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Compares a pair of String ignoring case-sensitivity of set of reserved words.
*
* @author Pinaki Poddar
*
*/
public class StringComparison {
private static List<String> _reserved = Arrays.asList(new String[] {
"ALL", "AND", "ANY", "AS", "ASC", "AVG",
"BETWEEN", "BIT_LENGTH", "BY",
"CASE", "CHAR_LENGTH", "CHARACTER_LENGTH", "CLASS", "COALESCE",
"COUNT","CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
"DELETE", "DESC", "DISTINCT",
"EMPTY", "ENTRY", "EXISTS",
"FALSE", "FETCH", "FROM",
"GROUP",
"HAVING",
"IN", "INDEX", "INNER", "IS",
"JOIN",
"KEY",
"LEFT", "LIKE", "LOWER",
"MAX", "MEMBER", "MIN", "MOD",
"NEW", "NOT", "NULL", "NULLIF",
"OBJECT", "OF", "OR", "ORDER", "OUTER",
"POSITION",
"SELECT", "SOME", "SUM",
"THEN", "TRIM", "TRUE", "TYPE",
"UNKNOWN", "UPDATE", "UPPER",
"VALUE",
"WHEN", "WHERE",
});
private boolean isReservedWord(String s) {
return _reserved.contains(s.toUpperCase());
}
public List<String> tokenize(String s) throws IOException {
List<String> list = new ArrayList<String>();
StreamTokenizer tok = new StreamTokenizer(new StringReader(s));
tok.resetSyntax();
tok.wordChars('a', 'z');
tok.wordChars('0', '9');
tok.wordChars('A', 'Z');
tok.wordChars('\'', '\'');
tok.wordChars('=', '=');
tok.wordChars('>', '>');
tok.wordChars('<', '<');
tok.wordChars('!', '!');
tok.wordChars('.', '.');
for (int ttype; (ttype = tok.nextToken()) != StreamTokenizer.TT_EOF;) {
if (ttype == StreamTokenizer.TT_WORD)
list.add(tok.sval);
}
return list;
}
public boolean compare(String s1, String s2) {
try {
List<String> list1 = tokenize(s1);
List<String> list2 = tokenize(s2);
if (list1.size() != list2.size()) {
System.err.println("Unequal tokens " + list1.size() + "!=" + list2.size());
return false;
}
for (int i = 0; i < list1.size(); i++) {
String a = list1.get(i);
String b = list2.get(i);
boolean match = isReservedWord(a) ? a.equalsIgnoreCase(b) : a.equals(b);
if (!match) {
System.err.println("[" + a + "] does not match [" + b + "]");
return false;
}
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static void main(String[] args) throws Exception {
StringComparison c = new StringComparison();
String s1 = "SELECT DISTINCT o FROM Order AS o JOIN o.lineItems AS l WHERE l.shipped != FALSE and l.name like 'hello'";
String s2 = "select DISTINCT o FROM Order AS o JOIN o.lineItems AS l WHERE l.shipped != FALSE and l.name like 'hello'";
boolean match = c.compare(s1, s2);
if (!match) {
System.err.println(s1);
System.err.println(c.tokenize(s1));
System.err.println(s2);
System.err.println(c.tokenize(s2));
}
}
}

View File

@ -0,0 +1,413 @@
/*
* 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.criteria;
import javax.persistence.DomainObject;
import javax.persistence.QueryBuilder;
import javax.persistence.QueryDefinition;
import javax.persistence.SelectItem;
import org.apache.openjpa.persistence.query.AbstractDomainObject;
import org.apache.openjpa.persistence.query.QueryDefinitionImpl;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
/**
* Tests by stringifying QueryDefinition and comparing the resultant string
* with an equivalent JPQL.
*
* Does not execute the query.
*
* The examples are taken from Criteria API Section of Java Persistence API
* Version 2.0 [1].
*
* [1] <A href="http://jcp.org/aboutJava/communityprocess/pr/jsr317/index.html">
* JPA API Specification Version 2.0</A>
*
* @author Pinaki Poddar
*
*/
public class TestCriteria extends SingleEMFTestCase {
protected QueryBuilder qb;
protected StringComparison comparator = new StringComparison();
public void setUp() {
super.setUp(Contractor.class, Course.class, CreditCard.class,
Department.class, Employee.class, Exempt.class, Item.class,
Manager.class, Person.class, VideoStore.class, Order.class,
Customer.class);
qb = emf.getQueryBuilder();
}
public void tearDown() {
// do nothing as you do not have a database connection
}
void compare(String s, QueryDefinition q) {
String actual = ((QueryDefinitionImpl)q).toJPQL();
if (!comparator.compare(s,actual)) {
fail("\r\nExpected: [" + s + "]\r\nActual : [" + actual + "]");
}
}
void compare(String s, DomainObject q) {
String actual = ((AbstractDomainObject)q).getOwner().toJPQL();
if (!comparator.compare(s,actual)) {
fail("\r\nExpected: [" + s + "]\r\nActual : [" + actual + "]");
}
}
public void testMultipleDomainOfSameClass() {
DomainObject o1 = qb.createQueryDefinition(Order.class);
DomainObject o2 = o1.addRoot(Order.class);
o1.select(o1)
.where(o1.get("quantity").greaterThan(o2.get("quantity"))
.and(o2.get("customer").get("lastName").equal("Smith"))
.and(o2.get("customer").get("firstName").equal("John")));
String jpql = "select o from Order o, Order o2" +
" where o.quantity > o2.quantity" +
" and o2.customer.lastName = 'Smith'" +
" and o2.customer.firstName = 'John'";
compare(jpql, o1);
}
public void testFetchJoin() {
DomainObject d = qb.createQueryDefinition(Department.class);
d.leftJoinFetch("employees");
d.where(d.get("deptNo").equal(1));
String jpql = "select d from Department d" +
" LEFT JOIN FETCH d.employees" +
" where d.deptNo = 1";
compare(jpql, d);
}
public void testMultipartNavigation() {
DomainObject e = qb.createQueryDefinition(Employee.class);
DomainObject p = e.join("contactInfo").join("phones");
e.where(e.get("contactInfo").get("address").get("zipCode")
.equal("95094")).select(p.get("vendor"));
String jpql = "select p.vendor from Employee e" +
" JOIN e.contactInfo c JOIN c.phones p" +
" where e.contactInfo.address.zipCode = '95094'";
compare(jpql, e);
}
public void testOperatorPath() {
QueryDefinition qdef = qb.createQueryDefinition();
DomainObject item = qdef.addRoot(Item.class);
DomainObject photo = item.join("photos");
qdef.select(item.get("name"), photo.value())
.where(photo.key().like("egret"));
String jpql = "select i.name, VALUE(p) from Item i join i.photos p where KEY(p) like 'egret'";
compare(jpql, qdef);
}
public void testLiteral() {
DomainObject c = qb.createQueryDefinition(Customer.class);
DomainObject o = c.join("orders");
DomainObject a = c.join("address");
o.where(a.get("state").equal("CA").and(a.get("county").equal("Santa Clara")));
o.select(o.get("quantity"), o.get("cost").times(1.08), a.get("zipCode"));
String jpql = "select o.quantity, o.cost*1.08, a.zipCode" +
" from Customer c join c.orders o join c.address a" +
" where a.state = 'CA' and a.county = 'Santa Clara'";
compare(jpql, c);
}
public void testTypeExpression() {
DomainObject e = qb.createQueryDefinition(Employee.class);
e.select(e.type())
.where(e.type().equal(Exempt.class).not());
String jpql = "select TYPE(e)" +
" from Employee e" +
" where TYPE(e) <> Exempt";
compare(jpql, e);
}
public void testIndex() {
DomainObject c = qb.createQueryDefinition(Course.class);
DomainObject w = c.join("studentWaitList");
c.where(c.get("name").equal("Calculus").and(w.index().equal(0)))
.select(w.get("name"));
String jpql = "select s.name" +
" from Course c join c.studentWaitList s" +
" where c.name = 'Calculus' and INDEX(s) = 0";
compare(jpql, c);
}
public void testSum() {
DomainObject o = qb.createQueryDefinition(Order.class);
DomainObject l = o.join("lineItems");
DomainObject c = o.join("customer");
c.where(c.get("lastName").equal("Smith").and(c.get("firstName").equal("John")))
.select(l.get("price").sum());
String jpql = "select SUM(l.price)" +
" from Order o join o.lineItems l JOIN o.customer c" +
" where c.lastName = 'Smith' and c.firstName = 'John'";
compare(jpql, c);
}
public void testSize() {
DomainObject d = qb.createQueryDefinition(Department.class);
d.where(d.get("name").equal("Sales"))
.select(d.get("employees").size());
String jpql = "select SIZE(d.employees)" +
" from Department d " +
" where d.name = 'Sales'";
compare(jpql, d);
}
public void testGeneralCase() {
DomainObject e = qb.createQueryDefinition(Employee.class);
e.where(e.get("department").get("name").equal("Engineering"));
e.select(e.get("name"),
e.generalCase()
.when(e.get("rating").equal(1))
.then(e.get("salary").times(1.1))
.when(e.get("rating").equal(2))
.then(e.get("salary").times(1.2))
.elseCase(e.get("salary").times(1.01)));
String jpql = "SELECT e.name,"
+ " CASE WHEN e.rating = 1 THEN e.salary * 1.1"
+ " WHEN e.rating = 2 THEN e.salary * 1.2"
+ " ELSE e.salary * 1.01"
+ " END"
+ " FROM Employee e"
+ " WHERE e.department.name = 'Engineering'";
compare(jpql, e);
}
public void testMemberOf() {
DomainObject p = qb.createQueryDefinition(Person.class);
p.where(p.literal("Joe").member(p.get("nicknames")));
String jpql = "select p from Person p " +
" where 'Joe' MEMBER OF p.nicknames";
compare(jpql, p);
}
public void testParamater() {
QueryDefinition qdef = qb.createQueryDefinition();
DomainObject customer = qdef.addRoot(Customer.class);
qdef.where(customer.get("status").equal(qdef.param("status")));
String jpql = "select c from Customer c " +
" where c.status = :status";
compare(jpql, qdef);
}
public void testBetween() {
DomainObject c = qb.createQueryDefinition(CreditCard.class);
DomainObject t = c.join("transactionHistory");
c.select(t).where(c.get("holder").get("name").equal("John Doe")
.and(t.index().between(0, 9)));
String jpql = "select t from CreditCard c JOIN c.transactionHistory t" +
" where c.holder.name = 'John Doe' AND INDEX(t) " +
" BETWEEN 0 AND 9";
compare(jpql, c);
}
public void testIsEmpty() {
DomainObject o = qb.createQueryDefinition(Order.class);
o.where(o.get("lineItems").isEmpty());
String jpql = "select o from Order o " +
" where o.lineItems IS EMPTY";
compare(jpql, o);
}
public void testNonCorrelatedSubQuery() {
QueryDefinition q1 = qb.createQueryDefinition();
DomainObject goodCustomer = q1.addRoot(Customer.class);
QueryDefinition q2 = qb.createQueryDefinition();
DomainObject customer = q2.addRoot(Customer.class);
q1.where(goodCustomer.get("balanceOwned")
.lessThan(q2.select(customer.get("balanceOwned").avg())));
String jpql = "select c from Customer c "
+ " where c.balanceOwned < "
+ "(select AVG(c2.balanceOwned) from Customer c2)";
compare(jpql, q1);
}
public void testNew() {
QueryDefinition q = qb.createQueryDefinition();
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")));
String jpql = "SELECT NEW org.apache.openjpa.persistence.criteria.Customer(c.id, c.status, o.count)"
+ " FROM Customer c JOIN c.orders o"
+ " WHERE o.count > 100";
compare(jpql, q);
}
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);
}
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));
String jpql = "SELECT c.status, AVG(c.filledOrderCount), COUNT(c)"
+ " FROM Customer c"
+ " GROUP BY c.status"
+ " HAVING c.status IN (1, 2)";
compare(jpql, q);
}
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));
String jpql = "SELECT c.country, COUNT(c)"
+ " FROM Customer c"
+ " GROUP BY c.country"
+ " HAVING COUNT(c) > 30";
compare(jpql, q);
}
public void testOrderBy() {
QueryDefinition q = qb.createQueryDefinition();
DomainObject customer = q.addRoot(Customer.class);
DomainObject order = customer.join("orders");
DomainObject address = customer.join("address");
q.where(address.get("state").equal("CA"))
.select(order)
.orderBy(order.get("quantity").desc(), order.get("totalcost"));
String jpql = "SELECT o"
+ " FROM Customer c JOIN c.orders o JOIN c.address a"
+ " WHERE a.state = 'CA'"
+ " ORDER BY o.quantity DESC, o.totalcost";
compare(jpql, q);
}
public void testOrderBy2() {
QueryDefinition q = qb.createQueryDefinition();
DomainObject customer = q.addRoot(Customer.class);
DomainObject order = customer.join("orders");
DomainObject address = customer.join("address");
q.where(address.get("state").equal("CA"))
.select(order.get("quantity"), address.get("zipcode"))
.orderBy(order.get("quantity"), address.get("zipcode"));
String jpql = "SELECT o.quantity, a.zipcode"
+ " FROM Customer c JOIN c.orders o JOIN c.address a"
+ " WHERE a.state = 'CA'"
+ " ORDER BY o.quantity, a.zipcode";
compare(jpql, q);
}
public void testOrderByExpression() {
DomainObject o = qb.createQueryDefinition(Order.class);
DomainObject a = o.join("customer").join("address");
SelectItem taxedCost = o.get("cost").times(1.08);
o.select(o.get("quantity"), taxedCost, a.get("zipcode"))
.where(a.get("state").equal("CA")
.and(a.get("county").equal("Santa Clara")))
.orderBy(o.get("quantity"), taxedCost, a.get("zipcode"));
String jpql = "SELECT o.quantity, o.cost*1.08, a.zipcode"
+ " FROM Order o JOIN o.customer c JOIN c.address a"
+ " WHERE a.state = 'CA' AND a.county = 'Santa Clara'"
+ " ORDER BY o.quantity, o.cost*1.08, a.zipcode";
compare(jpql, o);
}
public void testCorrelatedSubquery() {
QueryDefinition q1 = qb.createQueryDefinition();
DomainObject emp = q1.addRoot(Employee.class);
QueryDefinition q2 = qb.createQueryDefinition();
DomainObject spouseEmp = q2.addRoot(Employee.class);
q2.where(spouseEmp.equal(emp.get("spouse"))).select(spouseEmp);
q1.selectDistinct(emp).where(q2.exists());
String jpql = "SELECT DISTINCT e "
+ " FROM Employee e"
+ " WHERE EXISTS ("
+ " SELECT e2 "
+ " FROM Employee e2"
+ " WHERE e2 = e.spouse)";
compare(jpql, q1);
}
public void testCreateSubquery() {
DomainObject customer = qb.createQueryDefinition(Customer.class);
DomainObject order = qb.createSubqueryDefinition(customer.get("orders"));
customer.where(order.select(order.get("price").avg()).greaterThan(100));
String jpql = "SELECT c "
+ " FROM Customer c"
+ " WHERE (SELECT AVG(o.price) FROM c.orders o) > 100";
compare(jpql, customer);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.criteria;
import javax.persistence.Entity;
@Entity
public class VideoStore {
}

View File

@ -46,6 +46,7 @@ import org.apache.openjpa.lib.conf.ProductDerivations;
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.QueryBuilderImpl;
import org.apache.openjpa.util.OpenJPAException;
import serp.util.Strings;
@ -342,8 +343,7 @@ public class EntityManagerFactoryImpl
}
public QueryBuilder getQueryBuilder() {
throw new UnsupportedOperationException(
"JPA 2.0 - Method not yet implemented");
return new QueryBuilderImpl();
}
public Set<String> getSupportedProperties() {

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes ABS() operation on a given expression.
*
* @author Pinaki Poddar
*
*/
public class AbsExpression extends UnaryOperatorExpression {
public AbsExpression(ExpressionImpl op) {
super(op, UnaryFunctionalOperator.ABS);
}
}

View File

@ -0,0 +1,395 @@
/*
* 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.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.CaseExpression;
import javax.persistence.DomainObject;
import javax.persistence.Expression;
import javax.persistence.FetchJoinObject;
import javax.persistence.OrderByItem;
import javax.persistence.PathExpression;
import javax.persistence.Predicate;
import javax.persistence.QueryDefinition;
import javax.persistence.SelectItem;
import javax.persistence.Subquery;
/**
* Domain Object is a path expression over which query is evaluated.
* Domain object acts as a proxy for a QueryDefinition via delegation.
*
* @author Pinaki Poddar
*
*/
public abstract class AbstractDomainObject extends AbstractPath
implements DomainObject {
private final QueryDefinitionImpl _owner;
private List<JoinPath> _joins;
private List<FetchPath> _fetchJoins;
protected AbstractDomainObject(QueryDefinitionImpl owner,
AbstractPath parent, PathOperator op, Object part2) {
super(parent, op, part2);
_owner = owner;
}
/**
* Gets the QueryDefinition that created this path.
* @return
*/
public QueryDefinitionImpl getOwner() {
return _owner;
}
/**
* Gets the fetch joins associated with this path. Can be null.
*/
public List<FetchPath> getFetchJoins() {
return _fetchJoins;
}
/**
* Gets the joins associated with this path. Can be null.
*/
public List<JoinPath> getJoins() {
return _joins;
}
/**
* Adding a root adds a root domain to the owning query.
*/
public DomainObject addRoot(Class cls) {
return _owner.addRoot(cls);
}
/**
* Adding a query root adds a subquery to the owning query.
*/
public DomainObject addSubqueryRoot(PathExpression path) {
return _owner.addSubqueryRoot(path);
}
/**
* Derives a path from this path by navigating through the given field.
*/
public PathExpression get(String attr) {
return new NavigationPath(_owner, this, attr);
}
/**
* Derives a path from this path by joining the given field.
* Also the joined path becomes a domain of the owning query.
*/
public DomainObject join(String attribute) {
return join(attribute, PathOperator.INNER);
}
/**
* Derives a path from this path by outer joining the given field.
* Also the joined path becomes a domain of the owning query.
*/
public DomainObject leftJoin(String attribute) {
return join(attribute, PathOperator.OUTER);
}
protected DomainObject join(String attr, PathOperator joinType) {
JoinPath join = new JoinPath(this, joinType, attr);
if (_joins == null) {
_joins = new ArrayList<JoinPath>();
}
_joins.add(join);
return join;
}
/**
* Derives a path from this path by fetch joining the given field.
*/
public FetchJoinObject joinFetch(String attribute) {
return fetchJoin(attribute, PathOperator.FETCH_INNER);
}
/**
* Derives a path from this path by fetch joining the given field.
*/
public FetchJoinObject leftJoinFetch(String attribute) {
return fetchJoin(attribute, PathOperator.FETCH_OUTER);
}
private FetchJoinObject fetchJoin(String attr, PathOperator joinType) {
NavigationPath path = new NavigationPath(_owner, this, attr);
FetchPath join = new FetchPath(path, joinType);
if (_fetchJoins == null) {
_fetchJoins = new ArrayList<FetchPath>();
}
_fetchJoins.add(join);
return join;
}
/**
* Derives by KEY() operation on this path.
*/
public PathExpression key() {
return new KeyExpression(this);
}
/**
* Derives by ENTRY() operation on this path.
*/
public SelectItem entry() {
return new EntryExpression(this);
}
/**
* Derives by INDEX() operation on this path.
*/
public Expression index() {
return new IndexExpression(this);
}
/**
* Derives a path by VALUE() operation on this path.
*/
public PathExpression value() {
return new ValueExpression(this);
}
/**
* Derives this path as ALL(subquery) to its owning query.
*/
public Subquery all() {
return _owner.all();
}
/**
* Adds this path as ANY(subquery) to its owning query.
*/
public Subquery any() {
return _owner.any();
}
/**
* Adds this path as SOME(subquery) to its owning query.
*/
public Subquery some() {
return _owner.some();
}
/**
* Adds this path as EXISTS(subquery) to its owning query.
*/
public Predicate exists() {
return _owner.exists();
}
public Expression coalesce(Expression... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(String... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(Date... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(Calendar... exp) {
throw new UnsupportedOperationException();
}
public Expression currentDate() {
return _owner.currentDate();
}
public Expression currentTime() {
return _owner.currentTime();
}
public Expression currentTimestamp() {
return _owner.currentTimestamp();
}
public CaseExpression generalCase() {
return _owner.generalCase();
}
public QueryDefinition groupBy(PathExpression... pathExprs) {
return _owner.groupBy(pathExprs);
}
public QueryDefinition groupBy(List<PathExpression> pathExprList) {
return _owner.groupBy(pathExprList);
}
public QueryDefinition having(Predicate predicate) {
return _owner.having(predicate);
}
public Expression literal(String s) {
return _owner.literal(s);
}
public Expression literal(Number n) {
return _owner.literal(n);
}
public Expression literal(boolean b) {
return _owner.literal(b);
}
public Expression literal(Calendar c) {
return _owner.literal(c);
}
public Expression literal(Date d) {
return _owner.literal(d);
}
public Expression literal(char c) {
return _owner.literal(c);
}
public Expression literal(Class cls) {
return _owner.literal(cls);
}
public Expression literal(Enum<?> e) {
return _owner.literal(e);
}
public SelectItem newInstance(Class cls, SelectItem... args) {
return _owner.newInstance(cls, args);
}
public Expression nullLiteral() {
return _owner.nullLiteral();
}
public Expression nullif(Expression exp1, Expression exp2) {
return _owner.nullif(exp1, exp2);
}
public Expression nullif(Number arg1, Number arg2) {
return _owner.nullif(arg1, arg2);
}
public Expression nullif(String arg1, String arg2) {
return _owner.nullif(arg1, arg2);
}
public Expression nullif(Date arg1, Date arg2) {
return _owner.nullif(arg1, arg2);
}
public Expression nullif(Calendar arg1, Calendar arg2) {
return _owner.nullif(arg1, arg2);
}
public Expression nullif(Class arg1, Class arg2) {
return _owner.nullif(arg1, arg2);
}
public Expression nullif(Enum<?> arg1, Enum<?> arg2) {
return _owner.nullif(arg1, arg2);
}
public QueryDefinition orderBy(OrderByItem... orderByItems) {
return _owner.orderBy(orderByItems);
}
public QueryDefinition orderBy(List<OrderByItem> orderByItemList) {
return _owner.orderBy(orderByItemList);
}
public Expression param(String name) {
return _owner.param(name);
}
public Predicate predicate(boolean b) {
return _owner.predicate(b);
}
public QueryDefinition select(SelectItem... selectItems) {
return _owner.select(selectItems);
}
public QueryDefinition select(List<SelectItem> selectItemList) {
return _owner.select(selectItemList);
}
public QueryDefinition selectDistinct(SelectItem... selectItems) {
return _owner.selectDistinct(selectItems);
}
public QueryDefinition selectDistinct(List<SelectItem> selectItemList) {
return _owner.selectDistinct(selectItemList);
}
public CaseExpression simpleCase(Expression caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(Number caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(String caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(Date caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(Calendar caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(Class caseOperand) {
return _owner.simpleCase(caseOperand);
}
public CaseExpression simpleCase(Enum<?> caseOperand) {
return _owner.simpleCase(caseOperand);
}
public QueryDefinition where(Predicate predicate) {
return _owner.where(predicate);
}
// -----------------------------------------------------------------------
// contract for conversion to JPQL.
// -----------------------------------------------------------------------
/**
* Sets alias for this domain and all its joins.
*/
public void setAlias(AliasContext ctx) {
ctx.getAlias(this);
if (_joins != null)
for (JoinPath join : _joins)
join.setAlias(ctx);
}
abstract public String asJoinable(AliasContext ctx);
}

View File

@ -0,0 +1,124 @@
/*
* 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.Aggregate;
import javax.persistence.Expression;
import javax.persistence.OrderByItem;
import javax.persistence.PathExpression;
import javax.persistence.Predicate;
/**
* An abstract path is formed by two parts : the first part is a parent path.
* The second part can be an attribute or an operation (e.g. KEY() or VALUE())
* or a join type operation. Based on the exact nature of the second part,
* concrete derivation of this class combines the two constituent parts to
* arrive at complete path name.
* For example, a navigation path adds the two part with a navigation '.'
* operator, while a OperatorPath will combine the parts as KEY(parent).
*
* The constituent parts are immutable and supplied at construction. Hence
* concrete implementations know what exact type they are dealing with, but
* this receiver maintains it state as more generic type to accommodate
* concrete types to cast/interpret these state variables.
*
* @author Pinaki Poddar
*
*/
abstract class AbstractPath extends ExpressionImpl implements
PathExpression {
protected final AbstractPath _parent;
protected final Object _part2;
protected final PathOperator _operator;
protected AbstractPath(AbstractPath parent, PathOperator op, Object part2) {
_parent = parent;
_part2 = part2;
_operator = op;
}
// ------------------------------------------------------------------------
// Path related functions.
// ------------------------------------------------------------------------
/**
* Gets the parent from which this receiver has been derived. Can be null
* for a root path.
*/
public AbstractPath getParent() {
return _parent;
}
/**
* Gets operator that derived this receiver from its parent.
*/
public PathOperator getOperator() {
return _operator;
}
/**
* Gets the last segment of this path.
* Concrete implementation should return a covariant type.
*/
public Object getLastSegment() {
return _part2;
}
// -----------------------------------------------------------------------
// Implementation of PathExpression
// -----------------------------------------------------------------------
public Aggregate avg() {
return new AverageExpression(this);
}
public Aggregate count() {
return new CountExpression(this);
}
public Predicate isEmpty() {
return new IsEmptyExpression(this);
}
public Aggregate max() {
return new MaxExpression(this);
}
public Aggregate min() {
return new MinExpression(this);
}
public Expression size() {
return new SizeExpression(this);
}
public Aggregate sum() {
return new SumExpression(this);
}
public Expression type() {
return new TypeExpression(this);
}
public OrderByItem asc() {
return new OrderableItem(this, Boolean.TRUE);
}
public OrderByItem desc() {
return new OrderableItem(this, Boolean.FALSE);
}
}

View File

@ -0,0 +1,60 @@
/*
* 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.HashMap;
import java.util.Map;
import javax.persistence.Expression;
class AliasContext {
private Map<ExpressionImpl, String> _aliases =
new HashMap<ExpressionImpl, String>();
/**
* Sets alias for the given Expression or gets the alias if the given
* path has already been assigned an alias.
* The given expression must provide a hint on what should be the
* alias name. If the alias name is assigned by this context, then a
* different alias is generated.
* @param path
* @return the alias name
*/
public String getAlias(ExpressionImpl path) {
String alias = _aliases.get(path);
if (alias != null)
return alias;
alias = path.getAliasHint().substring(0,1).toLowerCase();
int i = 2;
while (_aliases.containsValue(alias)) {
alias = alias + i;
i++;
}
_aliases.put(path, alias);
return alias;
}
/**
* Affirms if the given Expression has been assigned an alias by this
* context.
*/
public boolean hasAlias(Expression path) {
return _aliases.containsKey(path);
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.DomainObject;
import javax.persistence.QueryDefinition;
import javax.persistence.Subquery;
/**
* Denotes All(SubQuery) Expression.
*
* @author Pinaki Poddar
*
*/
class AllExpression extends QueryExpression implements Subquery {
public AllExpression(QueryDefinitionImpl sub) {
super(sub, UnaryFunctionalOperator.ALL);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Predicate;
import static org.apache.openjpa.persistence.query.ConditionalOperator.*;
/**
* Denotes (e1 AND e2) predicate.
*
* @author Pinaki Poddar
*
*/
public class AndPredicate extends LogicalPredicate {
public AndPredicate(Predicate p1, Predicate p2) {
super(p1, AND, OR, p2);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.QueryDefinition;
import javax.persistence.Subquery;
/**
* Denotes ANY(SUbquery) Expression.
*
* @author Pinaki Poddar
*
*/
class AnyExpression extends UnaryOperatorExpression implements Subquery {
public AnyExpression(QueryDefinitionImpl sub) {
super(sub, UnaryFunctionalOperator.ANY);
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes AVG() on a given Expression.
*
* @author Pinaki Poddar
*
*/
public class AverageExpression extends UnaryOperatorExpression {
public AverageExpression(ExpressionImpl op) {
super(op, UnaryFunctionalOperator.AVG);
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.Expression;
/**
* Denotes e1 BETWEEN(e2 AND e3) Expression.
*
* @author Pinaki Poddar
*
*/
public class BetweenExpression extends BinaryExpressionPredicate {
public BetweenExpression(Expression arg1, RangeExpression arg2) {
super(arg1, BinaryConditionalOperator.BETWEEN,
BinaryConditionalOperator.BETWEEN_NOT, arg2);
}
// public String toJPQL(AliasContext ctx) {
// return super.toJPQL(ctx) + " AND " + ((ExpressionImpl)arg3).toJPQL(ctx);
// }
}

View File

@ -0,0 +1,55 @@
/*
* 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;
/**
* Enumeration of conditional operator that operates on ordered pair of
* expression to generate a predicate.
*
* @see BinaryExpressionPredicate
*
* @author Pinaki Poddar
*
*/
public enum BinaryConditionalOperator {
BETWEEN("BETWEEN"),
BETWEEN_NOT("NOT BETWEEN"),
EQUAL("="),
EQUAL_NOT("<>"),
GREATER(">"),
GREATEREQUAL(">="),
IN("IN"),
IN_NOT("NOT IN"),
LESS("<"),
LESSEQUAL("<="),
LIKE("LIKE"),
LIKE_NOT("NOT LIKE"),
MEMBER("MEMBER OF"),
MEMBER_NOT("NOT MEMBER OF");
private final String _symbol;
BinaryConditionalOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.Expression;
import javax.persistence.Predicate;
/**
* Binary predicate combines two expressions with an operator.
*
* @author Pinaki Poddar
*
*/
class BinaryExpressionPredicate implements Predicate, Visitable {
protected final Expression _e1;
protected final Expression _e2;
protected final BinaryConditionalOperator _op;
private final BinaryConditionalOperator _nop;
BinaryExpressionPredicate(Expression e1, BinaryConditionalOperator op,
BinaryConditionalOperator nop, Expression e2) {
_e1 = e1;
_e2 = e2;
_op = op;
_nop = nop;
}
public final Expression getOperand() {
return _e1;
}
public final Expression getOperand2() {
return _e2;
}
public final BinaryConditionalOperator getOperator() {
return _op;
}
public Predicate and(Predicate predicate) {
return new AndPredicate(this, predicate);
}
public Predicate or(Predicate predicate) {
return new OrPredicate(this, predicate);
}
public Predicate not() {
if ( _nop == null)
throw new UnsupportedOperationException(this.toString());
return new BinaryExpressionPredicate(_e1, _nop, _op, _e2);
}
public String asExpression(AliasContext ctx) {
return ((Visitable)_e1).asExpression(ctx)
+ " " + _op + " "
+ ((Visitable)_e2).asExpression(ctx);
}
}

View File

@ -0,0 +1,50 @@
/*
* 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;
/**
* Enumeration of functional operator that operates on ordered pair of
* expression to generate another expression.
*
* @see BinaryOperatorExpression
*
* @author Pinaki Poddar
*
*/
public enum BinaryFunctionalOperator {
DIVIDE("/"),
LOCATE("LOCATE"),
MINUS("-"),
MOD("MOD"),
PLUS("+"),
RANGE(","),
SUBSTR("SUBSTR"),
TIMES("*"),
TRIM("TRIM");
private final String _symbol;
BinaryFunctionalOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.Expression;
/**
* An expression resulting from a binary operation on two expressions.
*
* @author Pinaki Poddar
*
*/
public class BinaryOperatorExpression extends ExpressionImpl {
protected final Expression _e1;
protected final Expression _e2;
protected final BinaryFunctionalOperator _op;
public BinaryOperatorExpression(Expression e1, BinaryFunctionalOperator op,
Expression e2) {
_e1 = e1;
_e2 = e2;
_op = op;
}
public Expression getOperand1() {
return _e1;
}
public Expression getOperand2() {
return _e2;
}
public BinaryFunctionalOperator getOperator() {
return _op;
}
public String asExpression(AliasContext ctx) {
return ((Visitable)_e1).asExpression(ctx) + _op
+ ((Visitable)_e2).asExpression(ctx);
}
public String asProjection(AliasContext ctx) {
return ((Selectable)_e1).asProjection(ctx) + _op
+ ((Selectable)_e2).asProjection(ctx);
}
}

View File

@ -0,0 +1,197 @@
/*
* 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.Calendar;
import java.util.Date;
import java.util.LinkedList;
import javax.persistence.CaseExpression;
import javax.persistence.Expression;
import javax.persistence.Predicate;
public class CaseExpressionImpl implements CaseExpression {
private LinkedList<WhenClause> _whens = new LinkedList<WhenClause>();
private final Object _caseOperand;
public CaseExpressionImpl() {
this(null);
}
public CaseExpressionImpl(Object caseOperand) {
_caseOperand = caseOperand;
}
public Expression elseCase(Expression arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(String arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(Number arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(Date arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(Calendar arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(Class arg) {
return new ElseExpression(this, arg);
}
public Expression elseCase(Enum<?> arg) {
return new ElseExpression(this, arg);
}
public CaseExpression then(Expression then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(Number then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(String then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(Date then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(Calendar then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(Class then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression then(Enum<?> then) {
assertThenState();
_whens.getLast().setThen(then);
return this;
}
public CaseExpression when(Predicate when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Expression when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Number when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(String when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Date when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Calendar when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Class when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
public CaseExpression when(Enum<?> when) {
assertWhenState();
WhenClause clause = new WhenClause(when);
_whens.add(clause);
return this;
}
void assertWhenState() {
boolean ok = _whens.isEmpty() || _whens.getLast().hasThen();
if (!ok)
throw new IllegalStateException("when() can not be called now");
}
void assertThenState() {
boolean ok = !_whens.isEmpty() && !_whens.getLast().hasThen();
if (!ok)
throw new IllegalStateException("then() can not be called now");
}
public String toJPQL(AliasContext ctx) {
StringBuffer tmp = new StringBuffer("CASE ");
if (_caseOperand != null) {
tmp.append(toJPQL(ctx, _caseOperand));
}
for (WhenClause when : _whens) {
tmp.append(when.toJPQL(ctx));
}
return tmp.toString();
}
String toJPQL(AliasContext ctx, Object o) {
if (o instanceof Visitable) {
return ((Visitable)o).asExpression(ctx);
}
return o.toString();
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Enumerates conditional operator that operates on two predicates to generate
* another predicate.
*
* @author Pinaki Poddar
*
*/
public enum ConditionalOperator {
AND,
OR;
}

View File

@ -0,0 +1,60 @@
/*
* 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;
/**
* Denotes a Value based expression such as Number, String or Date.
*
* @author Pinaki Poddar
*
*/
class ConstantExpression extends ExpressionImpl {
private final Object _value;
public ConstantExpression(Object value) {
_value = value;
}
public Object getValue() {
return _value;
}
@Override
public String asExpression(AliasContext ctx) {
if (_value.getClass().isArray()) {
return Arrays.asList((Object[])_value).toString();
}
return quoted(_value);
}
@Override
public String asProjection(AliasContext ctx) {
return asExpression(ctx);
}
String quoted(Object o) {
if (o instanceof String)
return "'" + o + "'";
if (o instanceof Class)
return ((Class)o).getSimpleName();
return o.toString();
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes COUNT(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class CountExpression extends UnaryOperatorExpression {
public CountExpression(Expression op) {
super(op, UnaryFunctionalOperator.COUNT);
}
}

View File

@ -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.sql.Time;
import java.util.Date;
/**
* Denotes CURRENT_TIME(), CURRENT_DATE() and CURRENT_TIMESTAMP() expressions.
*
* @author Pinaki Poddar
*
*/
public class CurrentTimeExpression extends ExpressionImpl {
private static enum Now {
CURRENT_DATE,
CURRENT_TIME,
CURRENT_TIMESTAMP
}
private final Class _type;
public CurrentTimeExpression(Class operand) {
_type = operand;
}
@Override
public String asExpression(AliasContext ctx) {
Now now = (_type == Date.class
? Now.CURRENT_DATE
: (_type == Time.class
? Now.CURRENT_TIME : Now.CURRENT_TIMESTAMP));
return now.toString();
}
@Override
public String asProjection(AliasContext ctx) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.Expression;
/**
* Denotes DISTINCT(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class DistinctExpression extends UnaryOperatorExpression {
public DistinctExpression(Expression expr) {
super(expr, UnaryFunctionalOperator.DISTINCT);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes e1/e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class DividedByExpression extends BinaryOperatorExpression {
public DividedByExpression(Expression op1, Expression op2) {
super(op1, BinaryFunctionalOperator.DIVIDE, op2);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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;
/**
* Else clause in a Case Statement.
*
* @author Pinaki Poddar
*
*/
public class ElseExpression extends ExpressionImpl {
private final CaseExpressionImpl _caseClause;
private final Object _elseClause;
public ElseExpression(CaseExpressionImpl owner, Object op) {
_caseClause = owner;
_elseClause = op;
}
@Override
public String asExpression(AliasContext ctx) {
return _caseClause.toJPQL(ctx)
+ " ELSE " + toJPQL(ctx, _elseClause)
+ " END ";
}
@Override
public String asProjection(AliasContext ctx) {
return _caseClause.toJPQL(ctx)
+ " ELSE " + toJPQL(ctx, _elseClause)
+ " END ";
}
String toJPQL(AliasContext ctx, Object o) {
if (o instanceof Visitable) {
return ((Visitable)o).asExpression(ctx);
}
return o.toString();
}
String asProjection(AliasContext ctx, Object o) {
if (o instanceof Selectable) {
return ((Selectable)o).asProjection(ctx);
}
return o.toString();
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes ENTRY(e) on a path.
*
* @author Pinaki Poddar
*
*/
public class EntryExpression extends OperatorPath {
public EntryExpression(AbstractDomainObject expr) {
super(expr, PathOperator.ENTRY);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes e1 = e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class EqualExpression extends BinaryExpressionPredicate {
public EqualExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.EQUAL, BinaryConditionalOperator.EQUAL_NOT, op2);
}
}

View File

@ -0,0 +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;
/**
* Denotes EXISTS(SubQuery) Expression.
*
* @author Pinaki Poddar
*
*/
public class ExistsExpression extends UnaryExpressionPredicate {
public ExistsExpression(QueryDefinitionImpl op) {
super(op, UnaryConditionalOperator.EXISTS, UnaryConditionalOperator.EXISTS_NOT);
}
}

View File

@ -0,0 +1,477 @@
/*
* 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.Calendar;
import java.util.Date;
import javax.persistence.Expression;
import javax.persistence.OrderByItem;
import javax.persistence.PathExpression;
import javax.persistence.Predicate;
import javax.persistence.PredicateOperand;
import javax.persistence.Subquery;
import javax.persistence.TrimSpec;
/**
* An abstract expression acts as a factory for concrete unary or binary
* expressions such as ABS() or PLUS().
*
* @author Pinaki Poddar
*
*/
abstract class ExpressionImpl implements Expression, Selectable, Visitable {
public Expression abs() {
return new AbsExpression(this);
}
public Expression concat(String... str) {
throw new UnsupportedOperationException();
}
public Expression concat(Expression... str) {
throw new UnsupportedOperationException();
}
public Expression dividedBy(Number num) {
return new DividedByExpression(this, new ConstantExpression(num));
}
public Expression dividedBy(Expression expr) {
return new DividedByExpression(this, expr);
}
public Predicate in(String... strings) {
return new InExpression(this, new ConstantExpression(strings));
}
public Predicate in(Number... nums) {
return new InExpression(this,
new ConstantExpression(nums));
}
public Predicate in(Enum<?>... enums) {
return new InExpression(this,
new ConstantExpression(enums));
}
public Predicate in(Class... classes) {
return new InExpression(this,
new ConstantExpression(classes));
}
public Predicate in(Expression... params) {
return new InExpression(this,
new ConstantExpression(params));
}
public Predicate in(Subquery subquery) {
return new InExpression(this, (Expression)subquery);
}
public Predicate isNull() {
return new IsNullExpression(this);
}
public Expression length() {
return new LengthExpression(this);
}
public Expression locate(String str) {
return locate(str, 0);
}
public Expression locate(Expression expr) {
return new LocateExpression(this, expr, 1);
}
public Expression locate(String str, int position) {
return new LocateExpression(this, new ConstantExpression(str), position);
}
public Expression locate(String str, Expression position) {
return new LocateExpression(this, new ConstantExpression(str), position);
}
public Expression locate(Expression str, int position) {
return new LocateExpression(this, str, position);
}
public Expression locate(Expression str, Expression position) {
return new LocateExpression(this, str, position);
}
public Expression lower() {
return new LowerExpression(this);
}
public Predicate member(PathExpression arg) {
return new MemberOfExpression(this, arg);
}
public Expression minus() {
return new UnaryMinusExpression(this);
}
public Expression minus(Number num) {
return new MinusExpression(this, new ConstantExpression(num));
}
public Expression minus(Expression expr) {
return new MinusExpression(this, expr);
}
public Expression mod(int num) {
return new ModExpression(this, new ConstantExpression(num));
}
public Expression mod(Expression expr) {
return new MinusExpression(this, expr);
}
public Expression plus(Number num) {
return new PlusExpression(this, new ConstantExpression(num));
}
public Expression plus(Expression expr) {
return new PlusExpression(this, expr);
}
public Expression sqrt() {
return new SquareRootExpression(this);
}
public Expression substring(int start) {
return new SubStringExpression(this, start);
}
public Expression substring(Expression start) {
return new SubStringExpression(this, start);
}
public Expression substring(int start, int len) {
return new SubStringExpression(this, start, len);
}
public Expression substring(int start, Expression len) {
return new SubStringExpression(this, new ConstantExpression(start), len);
}
public Expression substring(Expression start, int len) {
return new SubStringExpression(this, start, new ConstantExpression(len));
}
public Expression substring(Expression start, Expression len) {
return new SubStringExpression(this, start, len);
}
public Expression times(Number num) {
return new TimesExpression(this, new ConstantExpression(num));
}
public Expression times(Expression expr) {
return new TimesExpression(this, expr);
}
public Expression trim() {
return new TrimExpression(this, null, null);
}
public Expression trim(TrimSpec spec) {
return new TrimExpression(this, null, spec);
}
public Expression trim(char c) {
return new TrimExpression(this, c, null);
}
public Expression trim(char c, TrimSpec spec) {
return new TrimExpression(this, c, spec);
}
public Expression trim(Expression expr) {
return new TrimExpression(this, expr, null);
}
public Expression trim(Expression expr, TrimSpec spec) {
return new TrimExpression(this, expr, spec);
}
public Expression upper() {
return new ToUpperExpression(this);
}
public OrderByItem asc() {
throw new UnsupportedOperationException(this.toString());
}
public OrderByItem desc() {
throw new UnsupportedOperationException(this.toString());
}
public Predicate between(PredicateOperand arg1, PredicateOperand arg2) {
return new BetweenExpression(this, new RangeExpression(
(Expression)arg1, (Expression)arg2));
}
public Predicate between(PredicateOperand arg1, Number arg2) {
return new BetweenExpression(this, new RangeExpression(
(Expression)arg1, new ConstantExpression(arg2)));
}
public Predicate between(Number arg1, PredicateOperand arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), (Expression)arg2));
}
public Predicate between(Number arg1, Number arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), new ConstantExpression(arg2)));
}
public Predicate between(PredicateOperand arg1, String arg2) {
return new BetweenExpression(this, new RangeExpression((Expression)arg1,
new ConstantExpression(arg2)));
}
public Predicate between(String arg1, PredicateOperand arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), (Expression)arg2));
}
public Predicate between(String arg1, String arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), new ConstantExpression(arg2)));
}
public Predicate between(PredicateOperand arg1, Date arg2) {
return new BetweenExpression(this, new RangeExpression(
(Expression)arg1, new ConstantExpression(arg2)));
}
public Predicate between(Date arg1, PredicateOperand arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), (Expression)arg2));
}
public Predicate between(Date arg1, Date arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), new ConstantExpression(arg2)));
}
public Predicate between(PredicateOperand arg1, Calendar arg2) {
return new BetweenExpression(this, new RangeExpression(
(Expression)arg1, new ConstantExpression(arg2)));
}
public Predicate between(Calendar arg1, PredicateOperand arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), (Expression)arg2));
}
public Predicate between(Calendar arg1, Calendar arg2) {
return new BetweenExpression(this, new RangeExpression(
new ConstantExpression(arg1), new ConstantExpression(arg2)));
}
public Predicate equal(PredicateOperand arg) {
return new EqualExpression(this, (Expression)arg);
}
public Predicate equal(Class cls) {
return new EqualExpression(this, new ConstantExpression(cls));
}
public Predicate equal(Number arg) {
return new EqualExpression(this, new ConstantExpression(arg));
}
public Predicate equal(String arg) {
return new EqualExpression(this, new ConstantExpression(arg));
}
public Predicate equal(boolean arg) {
return new EqualExpression(this, new ConstantExpression(arg));
}
public Predicate equal(Date arg) {
return new EqualExpression(this, new ConstantExpression(arg));
}
public Predicate equal(Calendar arg) {
return new EqualExpression(this, new ConstantExpression(arg));
}
public Predicate equal(Enum<?> e) {
return new EqualExpression(this, new ConstantExpression(e));
}
public Predicate greaterEqual(PredicateOperand arg) {
return new GreaterEqualExpression(this, new ConstantExpression(arg));
}
public Predicate greaterEqual(Number arg) {
return new GreaterEqualExpression(this, new ConstantExpression(arg));
}
public Predicate greaterEqual(String arg) {
return new GreaterEqualExpression(this, new ConstantExpression(arg));
}
public Predicate greaterEqual(Date arg) {
return new GreaterEqualExpression(this, new ConstantExpression(arg));
}
public Predicate greaterEqual(Calendar arg) {
return new GreaterEqualExpression(this, new ConstantExpression(arg));
}
public Predicate greaterThan(PredicateOperand arg) {
return new GreaterThanExpression(this, (Expression)arg);
}
public Predicate greaterThan(Number arg) {
return new GreaterThanExpression(this, new ConstantExpression(arg));
}
public Predicate greaterThan(String arg) {
return new GreaterThanExpression(this, new ConstantExpression(arg));
}
public Predicate greaterThan(Date arg) {
return new GreaterThanExpression(this, new ConstantExpression(arg));
}
public Predicate greaterThan(Calendar arg) {
return new GreaterThanExpression(this, new ConstantExpression(arg));
}
public Predicate lessEqual(PredicateOperand arg) {
return new LessEqualExpression(this, new ConstantExpression(arg));
}
public Predicate lessEqual(Number arg) {
return new LessEqualExpression(this, new ConstantExpression(arg));
}
public Predicate lessEqual(String arg) {
return new LessEqualExpression(this, new ConstantExpression(arg));
}
public Predicate lessEqual(Date arg) {
return new LessEqualExpression(this, new ConstantExpression(arg));
}
public Predicate lessEqual(Calendar arg) {
return new LessEqualExpression(this, new ConstantExpression(arg));
}
public Predicate lessThan(PredicateOperand arg) {
return new LessThanExpression(this, (Expression)arg);
}
public Predicate lessThan(Number arg) {
return new LessThanExpression(this, new ConstantExpression(arg));
}
public Predicate lessThan(String arg) {
return new LessThanExpression(this, new ConstantExpression(arg));
}
public Predicate lessThan(Date arg) {
return new LessThanExpression(this, new ConstantExpression(arg));
}
public Predicate lessThan(Calendar arg) {
return new LessThanExpression(this, new ConstantExpression(arg));
}
public Predicate like(PredicateOperand pattern) {
return new LikeExpression(this, (Expression)pattern, null);
}
public Predicate like(PredicateOperand pattern, PredicateOperand escChar) {
return new LikeExpression(this, (Expression)pattern, escChar);
}
public Predicate like(PredicateOperand pattern, char escapeChar) {
return new LikeExpression(this, (Expression)pattern, escapeChar);
}
public Predicate like(String pattern) {
return new LikeExpression(this, new ConstantExpression(pattern), null);
}
public Predicate like(String pattern, PredicateOperand escapeChar) {
return new LikeExpression(this, new ConstantExpression(pattern),
escapeChar);
}
public Predicate like(String pattern, char escChar) {
return new LikeExpression(this, new ConstantExpression(pattern),
escChar);
}
public Predicate notEqual(PredicateOperand arg) {
return new NotEqualExpression(this, (Expression)arg);
}
public Predicate notEqual(Class cls) {
return new NotEqualExpression(this, new ConstantExpression(cls));
}
public Predicate notEqual(Number arg) {
return new NotEqualExpression(this, new ConstantExpression(arg));
}
public Predicate notEqual(String arg) {
return new NotEqualExpression(this, new ConstantExpression(arg));
}
public Predicate notEqual(boolean arg) {
return new NotEqualExpression(this, new ConstantExpression(arg));
}
public Predicate notEqual(Date arg) {
return new NotEqualExpression(this, new ConstantExpression(arg));
}
public Predicate notEqual(Calendar arg) {
return new NotEqualExpression(this, new ConstantExpression(arg));
}
public Predicate notEqual(Enum<?> e) {
return new NotEqualExpression(this, new ConstantExpression(e));
}
//
// Visitable/Selectable implementation
//
public void setAlias(AliasContext ctx) {
ctx.getAlias(this);
}
public String getAliasHint() {
return "o";
}
public abstract String asExpression(AliasContext ctx);
public abstract String asProjection(AliasContext ctx);
}

View File

@ -0,0 +1,42 @@
/*
* 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.FetchJoinObject;
/**
* Denotes a path used in fetch join. Simply wraps a Navigation Path.
*
* @author Pinaki Poddar
*
*/
public class FetchPath implements FetchJoinObject, Visitable {
private NavigationPath _path;
private PathOperator _joinType;
FetchPath(NavigationPath path, PathOperator joinType) {
_path = path;
_joinType = joinType;
}
public String asExpression(AliasContext ctx) {
return _joinType + " " + _path.asExpression(ctx);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes e1 >= e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class GreaterEqualExpression extends BinaryExpressionPredicate {
public GreaterEqualExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.GREATEREQUAL, BinaryConditionalOperator.LESS, op2);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes e1 > e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class GreaterThanExpression extends BinaryExpressionPredicate {
public GreaterThanExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.GREATER, BinaryConditionalOperator.LESSEQUAL, op2);
}
}

View File

@ -0,0 +1,15 @@
package org.apache.openjpa.persistence.query;
import javax.persistence.Expression;
/**
* Denotes e1 IN (e2) Expression.
*
* @author Pinaki Poddar
*
*/
public class InExpression extends BinaryExpressionPredicate {
public InExpression(Expression op, Expression op2) {
super(op, BinaryConditionalOperator.IN, BinaryConditionalOperator.IN_NOT, op2);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes INDEX(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class IndexExpression extends UnaryOperatorExpression {
public IndexExpression(Expression op) {
super(op, UnaryFunctionalOperator.INDEX);
}
}

View File

@ -0,0 +1,16 @@
package org.apache.openjpa.persistence.query;
import javax.persistence.Expression;
public class IsEmptyExpression extends UnaryExpressionPredicate {
public IsEmptyExpression(Expression op) {
super(op, UnaryConditionalOperator.ISEMPTY,
UnaryConditionalOperator.ISEMPTY_NOT);
}
@Override
public String asExpression(AliasContext ctx) {
return ((Visitable)_e).asExpression(ctx) + " " + _op;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.Expression;
/**
* Denotes e IS NULL Expression.
*
* @author Pinaki Poddar
*
*/
public class IsNullExpression extends UnaryExpressionPredicate {
public IsNullExpression(Expression op) {
super(op, UnaryConditionalOperator.ISNULL,
UnaryConditionalOperator.ISNULL_NOT);
}
@Override
public String asExpression(AliasContext ctx) {
return ((Visitable)_e).asExpression(ctx) + " " + _op;
}
}

View File

@ -0,0 +1,33 @@
/*
* 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;
/**
* Utility for converting elements to JPQL string fragments.
*
* @author Pinaki Poddar
*
*/
public class JPQLHelper {
static String toJPQL(AliasContext ctx, Object o) {
if (o instanceof Visitable)
return ((Visitable)o).asExpression(ctx);
return o.toString();
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.DomainObject;
import static org.apache.openjpa.persistence.query.PathOperator.NAVIGATION;
/**
* Path resulting by joining from a parent path via an attribute.
*
* @author Pinaki Poddar
*
*/
public class JoinPath extends AbstractDomainObject implements DomainObject {
public JoinPath(AbstractDomainObject parent, PathOperator join, String attr) {
super(parent.getOwner(), parent, join, attr);
}
@Override
public String getAliasHint() {
return getLastSegment();
}
@Override
public String getLastSegment() {
return super.getLastSegment().toString();
}
@Override
public AbstractDomainObject getParent() {
return (AbstractDomainObject)super.getParent();
}
// @Override
public String asJoinable(AliasContext ctx) {
StringBuffer tmp = new StringBuffer(getOperator().toString());
tmp.append(getParent().asProjection(ctx))
.append(NAVIGATION)
.append(getLastSegment())
.append(" ")
.append(ctx.getAlias(this));
if (getJoins() != null)
for (JoinPath join : getJoins())
tmp.append(join.asJoinable(ctx));
return tmp.toString();
}
@Override
public String asExpression(AliasContext ctx) {
if (ctx.hasAlias(this))
return ctx.getAlias(this);
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();
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes KEY(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class KeyExpression extends OperatorPath {
public KeyExpression(AbstractDomainObject expr) {
super(expr, PathOperator.KEY);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes LENGTH(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class LengthExpression extends UnaryOperatorExpression {
public LengthExpression(Expression op) {
super(op, UnaryFunctionalOperator.LENGTH);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes e1 <= e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class LessEqualExpression extends BinaryExpressionPredicate {
public LessEqualExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.LESSEQUAL,
BinaryConditionalOperator.GREATER, op2);
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.Expression;
/**
* Denotes e1 < e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class LessThanExpression extends BinaryExpressionPredicate {
public LessThanExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.LESS,
BinaryConditionalOperator.GREATEREQUAL, op2);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.Expression;
/**
* Denotes e1 LIKE e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class LikeExpression extends BinaryExpressionPredicate {
public LikeExpression(Expression op1, Expression op2, Object echar) {
super(escape(op1, echar), BinaryConditionalOperator.LIKE,
BinaryConditionalOperator.LIKE_NOT, escape(op2, echar));
}
static Expression escape(Expression o, Object echar) {
if (echar != null && o instanceof ConstantExpression
&& ((ConstantExpression)o).getValue() instanceof String) {
String escapeChar = echar.toString();
return new ConstantExpression(escapeChar + o.toString() + escapeChar);
}
return o;
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes a Literal Expression.
*
* @author Pinaki Poddar
*
*/
public class LiteralExpression extends ConstantExpression {
public LiteralExpression(Object literal) {
super(literal);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes LOCATE(e)
*
* @author Pinaki Poddar
*
*/
public class LocateExpression extends BinaryOperatorExpression {
public LocateExpression(Expression op, Expression op2, Object pos) {
super(op, BinaryFunctionalOperator.LOCATE, op2);
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.Predicate;
/**
* Logical Predicate combines two predicates with a logical operator.
*
* @author Pinaki Poddar
*
*/
public class LogicalPredicate implements Predicate, Visitable {
private final Predicate _p1;
private final Predicate _p2;
private final ConditionalOperator _op;
private final ConditionalOperator _nop;
public LogicalPredicate(Predicate p1, ConditionalOperator op,
ConditionalOperator nop, Predicate p2) {
_p1 = p1;
_p2 = p2;
_op = op;
_nop = nop;
}
public Predicate and(Predicate predicate) {
return new AndPredicate(this, predicate);
}
public Predicate or(Predicate predicate) {
return new OrPredicate(this, predicate);
}
public Predicate not() {
return new LogicalPredicate(_p1.not(), _nop, _op, _p2.not());
}
public String asExpression(AliasContext ctx) {
return ((Visitable)_p1).asExpression(ctx) + " " + _op + " "
+ ((Visitable)_p2).asExpression(ctx);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes LOWER(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class LowerExpression extends UnaryOperatorExpression {
public LowerExpression(Expression op) {
super(op, UnaryFunctionalOperator.LOWER);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes MAX(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class MaxExpression extends UnaryOperatorExpression {
public MaxExpression(Expression op) {
super(op, UnaryFunctionalOperator.MAX);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.Expression;
/**
* Denotes e1 MEMBER OF e2 Expression.
*
* @author Pinaki Poddar
*
*/
public class MemberOfExpression extends BinaryExpressionPredicate {
public MemberOfExpression(Expression op, Expression op2) {
super(op, BinaryConditionalOperator.MEMBER,
BinaryConditionalOperator.MEMBER_NOT, op2);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes MIN(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class MinExpression extends UnaryOperatorExpression {
public MinExpression(Expression op) {
super(op, UnaryFunctionalOperator.MIN);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes (e1 - e2) Expression.
*
* @author Pinaki Poddar
*
*/
public class MinusExpression extends BinaryOperatorExpression {
public MinusExpression(Expression op, Expression op2) {
super(op, BinaryFunctionalOperator.MINUS, op2);
}
}

View File

@ -0,0 +1,37 @@
/*
* 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;
/**
* Denotes MOD(e1, e2) Expression.
*
* @author Pinaki Poddar
*
*/
class ModExpression extends BinaryOperatorExpression {
public ModExpression(ExpressionImpl op, ExpressionImpl op2) {
super(op, BinaryFunctionalOperator.MOD, op2);
}
@Override
public String asExpression(AliasContext ctx) {
return _op + "(" + ((Visitable)_e1).asExpression(ctx)
+ "," + ((Visitable)_e2).asExpression(ctx);
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.PathExpression;
import static org.apache.openjpa.persistence.query.PathOperator.NAVIGATION;
/**
* Represents a path resulted by navigation.
*
* @author Pinaki Poddar
*
*/
class NavigationPath extends AbstractDomainObject implements PathExpression {
protected NavigationPath(QueryDefinitionImpl owner, AbstractPath parent,
String attr) {
super(owner, parent, NAVIGATION, attr);
}
@Override
public String getLastSegment() {
return (String)super.getLastSegment();
}
@Override
public String asProjection(AliasContext ctx) {
AbstractPath parent = getParent();
if (ctx.hasAlias(parent))
return ctx.getAlias(parent) + NAVIGATION + getLastSegment();
return getParent().asProjection(ctx) + NAVIGATION + getLastSegment();
}
@Override
public String asExpression(AliasContext ctx) {
return getParent().asExpression(ctx) + NAVIGATION + getLastSegment();
}
/**
* A navigation path is joinable only when it represents domain of a
* subquery.
* @see QueryDefinitionImpl#addSubqueryRoot(PathExpression)
*/
@Override
public String asJoinable(AliasContext ctx) {
return asProjection(ctx) + " " + ctx.getAlias(this);
}
}

View File

@ -0,0 +1,70 @@
/*
* 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.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.OrderByItem;
import javax.persistence.SelectItem;
/**
* Denotes NEW fully.qualified.class.name(arg1, arg2,...)
*
* @author Pinaki Poddar
*
*/
public class NewInstance implements Selectable {
private final Class _cls;
private List<SelectItem> _args;
NewInstance(Class cls, SelectItem...args) {
_cls = cls;
if (args != null) {
_args = Arrays.asList(args);
}
}
public OrderByItem asc() {
throw new UnsupportedOperationException();
}
public OrderByItem desc() {
throw new UnsupportedOperationException();
}
public String asProjection(AliasContext ctx) {
StringBuffer tmp = new StringBuffer("NEW ").append(_cls.getName())
.append("(");
if (_args == null || _args.isEmpty())
return tmp.append(")").toString();
int i = 0;
int N = _args.size();
for (SelectItem arg : _args) {
i++;
tmp.append(((Selectable)arg).asProjection(ctx))
.append(i == N ? ")" : ",");
}
return tmp.toString();
}
public void setAlias(AliasContext ctx) {
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.Expression;
/**
* Denotes (e1 != e2) Expression.
*
* @author Pinaki Poddar
*
*/
public class NotEqualExpression extends BinaryExpressionPredicate {
public NotEqualExpression(Expression op1, Expression op2) {
super(op1, BinaryConditionalOperator.EQUAL_NOT,
BinaryConditionalOperator.EQUAL, op2);
}
}

View File

@ -0,0 +1,58 @@
/*
* 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 org.apache.openjpa.util.InternalException;
/**
* A path resulting from KEY() or VALUE() operation on an existing path.
*
* @author Pinaki Poddar
*
*/
public class OperatorPath extends AbstractDomainObject {
public OperatorPath(AbstractDomainObject operand, PathOperator operator) {
super(operand.getOwner(), operand, operator, null);
}
@Override
public Class getLastSegment() {
throw new InternalException();
}
@Override
public String getAliasHint() {
return getParent().getAliasHint();
}
@Override
public String asProjection(AliasContext ctx) {
return getOperator() + "(" + getParent().asProjection(ctx) + ")";
}
@Override
public String asExpression(AliasContext ctx) {
return getOperator() + "(" + getParent().asExpression(ctx) + ")";
}
@Override
public String asJoinable(AliasContext ctx) {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.Predicate;
import static org.apache.openjpa.persistence.query.ConditionalOperator.*;
/**
* Denotes (e1 OR e2) predicate.
*
* @author Pinaki Poddar
*
*/
public class OrPredicate extends LogicalPredicate {
public OrPredicate(Predicate p1, Predicate p2) {
super(p1, OR, AND, p2);
}
}

View File

@ -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.OrderByItem;
/**
* Denotes an item of ORDER BY clause.
*
* @author Pinaki Poddar
*
*/
public class OrderableItem implements OrderByItem {
private final Boolean _asc;
private final ExpressionImpl path;
OrderableItem(ExpressionImpl path) {
this(path, null);
}
OrderableItem(ExpressionImpl path, Boolean asc) {
super();
this._asc = asc;
this.path = path;
}
public String toJPQL(AliasContext ctx) {
return path.asExpression(ctx) + " "
+ (_asc == null ? "" : (_asc ? " ASC " : "DESC"));
}
}

View File

@ -0,0 +1,36 @@
/*
* 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;
/**
* Denotes a parameter in a query.
*
* @author Pinaki Poddar
*
*/
public class ParameterExpression extends ConstantExpression {
public ParameterExpression(String name) {
super(name);
}
@Override
public String asExpression(AliasContext ctx) {
return ":" + getValue();
}
}

View File

@ -0,0 +1,48 @@
/*
* 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;
/**
* Operator that combines two components to form a path.
*
* @author Pinaki Poddar
*
*/
public enum PathOperator {
NONE(" "),
INNER(" JOIN "),
OUTER(" LEFT JOIN "),
FETCH_INNER(" JOIN FETCH "),
FETCH_OUTER(" LEFT JOIN FETCH "),
NAVIGATION("."),
KEY("KEY"),
ROOT(""),
VALUE("VALUE"),
ENTRY("ENTRY");
private final String _symbol;
PathOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes (e1 + e2) Expression.
*
* @author Pinaki Poddar
*
*/
public class PlusExpression extends BinaryOperatorExpression {
public PlusExpression(Expression op, Expression op2) {
super(op, BinaryFunctionalOperator.PLUS, op2);
}
}

View File

@ -0,0 +1,55 @@
/*
* 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.DomainObject;
import javax.persistence.PathExpression;
import javax.persistence.QueryBuilder;
import javax.persistence.QueryDefinition;
/**
* The factory for QueryDefinition.
*
*
* @author Pinaki Poddar
*
*/
public class QueryBuilderImpl implements QueryBuilder {
/**
* Creates a QueryDefinition without a domain root.
*/
public QueryDefinition createQueryDefinition() {
return new QueryDefinitionImpl(this);
}
/**
* Creates a QueryDefinition with given class as domain root.
*/
public DomainObject createQueryDefinition(Class root) {
return new QueryDefinitionImpl(this).addRoot(root);
}
/**
* Creates a QueryDefinition that can be used as a subquery to some
* other query.
*/
public DomainObject createSubqueryDefinition(PathExpression path) {
return new QueryDefinitionImpl(this).addSubqueryRoot(path);
}
}

View File

@ -0,0 +1,425 @@
/*
* 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.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.CaseExpression;
import javax.persistence.DomainObject;
import javax.persistence.Expression;
import javax.persistence.OrderByItem;
import javax.persistence.PathExpression;
import javax.persistence.Predicate;
import javax.persistence.QueryDefinition;
import javax.persistence.SelectItem;
import javax.persistence.Subquery;
import org.apache.openjpa.lib.util.Localizer;
/**
* Implements QueryDefinition.
*
* @author Pinaki Poddar
*
*/
public class QueryDefinitionImpl extends ExpressionImpl
implements QueryDefinition, Expression {
private final QueryBuilderImpl _builder;
private List<AbstractDomainObject> _domains;
private List<PathExpression> _groupBys;
private List<Subquery> _subqueries;
private List<OrderableItem> _orderBys;
private List<Selectable> _projections;
private boolean _distinct;
private Predicate _where;
private Predicate _having;
protected static Localizer _loc =
Localizer.forPackage(QueryDefinitionImpl.class);
protected QueryDefinitionImpl(QueryBuilderImpl builder) {
_builder = builder;
}
/**
* Root domain object has no parent, no path but a non-null Class.
*/
public DomainObject addRoot(Class cls) {
RootPath root = new RootPath(this, cls);
addDomain(root);
return root;
}
public DomainObject addSubqueryRoot(PathExpression path) {
if (_domains != null && _domains.contains(path))
throw new IllegalArgumentException(_loc.get("query-subroot-clash",
path).toString());
AbstractPath impl = (AbstractPath)path;
if (_subqueries == null)
_subqueries = new ArrayList<Subquery>();
AbstractDomainObject newRoot = new NavigationPath(this, impl.getParent(),
impl.getLastSegment().toString());
addDomain(newRoot);
return newRoot;
}
protected void addDomain(AbstractDomainObject path) {
if (_domains == null)
_domains = new ArrayList<AbstractDomainObject>();
_domains.add(path);
}
public Subquery all() {
return new AllExpression(this);
}
public Subquery any() {
return new AnyExpression(this);
}
public Expression coalesce(Expression... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(String... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(Date... exp) {
throw new UnsupportedOperationException();
}
public Expression coalesce(Calendar... exp) {
throw new UnsupportedOperationException();
}
public Expression currentDate() {
return new CurrentTimeExpression(Date.class);
}
public Expression currentTime() {
return new CurrentTimeExpression(Time.class);
}
public Expression currentTimestamp() {
return new CurrentTimeExpression(Timestamp.class);
}
public Predicate exists() {
return new ExistsExpression(this);
}
public CaseExpression generalCase() {
return new CaseExpressionImpl();
}
public QueryDefinition groupBy(PathExpression... pathExprs) {
if (_groupBys == null) {
_groupBys = new ArrayList<PathExpression>();
}
for (PathExpression e : pathExprs)
_groupBys.add(e);
return this;
}
public QueryDefinition groupBy(List<PathExpression> pathExprList) {
if (_groupBys == null) {
_groupBys = new ArrayList<PathExpression>();
}
for (PathExpression e : pathExprList)
_groupBys.add(e);
return this;
}
public QueryDefinition having(Predicate predicate) {
_having = predicate;
return this;
}
public Expression literal(String s) {
return new LiteralExpression(s);
}
public Expression literal(Number n) {
return new LiteralExpression(n);
}
public Expression literal(boolean b) {
return new LiteralExpression(b);
}
public Expression literal(Calendar c) {
return new LiteralExpression(c);
}
public Expression literal(Date d) {
return new LiteralExpression(d);
}
public Expression literal(char c) {
return new LiteralExpression(c);
}
public Expression literal(Class cls) {
return new LiteralExpression(cls);
}
public Expression literal(Enum<?> e) {
return new LiteralExpression(e);
}
public Expression nullLiteral() {
return new LiteralExpression(null);
}
public SelectItem newInstance(Class cls, SelectItem... args) {
return new NewInstance(cls, args);
}
public Expression nullif(Expression exp1, Expression exp2) {
throw new UnsupportedOperationException();
}
public Expression nullif(Number arg1, Number arg2) {
throw new UnsupportedOperationException();
}
public Expression nullif(String arg1, String arg2) {
throw new UnsupportedOperationException();
}
public Expression nullif(Date arg1, Date arg2) {
throw new UnsupportedOperationException();
}
public Expression nullif(Calendar arg1, Calendar arg2) {
throw new UnsupportedOperationException();
}
public Expression nullif(Class arg1, Class arg2) {
throw new UnsupportedOperationException();
}
public Expression nullif(Enum<?> arg1, Enum<?> arg2) {
throw new UnsupportedOperationException();
}
public QueryDefinition orderBy(OrderByItem... orderByItems) {
if (_orderBys == null)
_orderBys = new ArrayList<OrderableItem>();
for (OrderByItem i : orderByItems) {
if (i instanceof OrderableItem)
_orderBys.add((OrderableItem)i);
else
_orderBys.add(new OrderableItem((ExpressionImpl)i, null));
}
return this;
}
public QueryDefinition orderBy(List<OrderByItem> orderByItemList) {
if (_orderBys == null)
_orderBys = new ArrayList<OrderableItem>();
for (OrderByItem i : orderByItemList) {
if (i instanceof OrderableItem)
_orderBys.add((OrderableItem)i);
else
_orderBys.add(new OrderableItem((ExpressionImpl)i, null));
}
return this;
}
public Expression param(String name) {
return new ParameterExpression(name);
}
public Predicate predicate(boolean b) {
return null;
}
public QueryDefinition select(SelectItem... items) {
return select(items == null ? null : Arrays.asList(items), false);
}
public QueryDefinition select(List<SelectItem> items) {
return select(items, false);
}
public QueryDefinition selectDistinct(SelectItem... items) {
return select(items == null ? null : Arrays.asList(items), true);
}
public QueryDefinition selectDistinct(List<SelectItem> items) {
return select(items, false);
}
private QueryDefinition select(List<SelectItem> items, boolean isDistinct) {
if (_projections == null) {
_projections = new ArrayList<Selectable>();
} else {
_projections.clear();
}
_distinct = isDistinct;
for (SelectItem item : items)
_projections.add((Selectable)item);
return this;
}
public CaseExpression simpleCase(Expression caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(Number caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(String caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(Date caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(Calendar caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(Class caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public CaseExpression simpleCase(Enum<?> caseOperand) {
return new CaseExpressionImpl(caseOperand);
}
public Subquery some() {
return new SomeExpression(this);
}
public QueryDefinition where(Predicate predicate) {
_where = predicate;
return this;
}
private List<Selectable> getProjections() {
if (_projections == null) {
List<Selectable> defaultProjection = new ArrayList<Selectable>();
defaultProjection.add(_domains.get(0));
return defaultProjection;
}
return _projections;
}
public String toJPQL() {
return asExpression(new AliasContext());
}
/**
*
*/
@Override
public String asExpression(AliasContext ctx) {
StringBuffer buffer = new StringBuffer();
registerDomains(ctx);
buffer.append("SELECT ");
if (_distinct)
buffer.append("DISTINCT ");
List<Selectable> projs = getProjections();
for (int i=0; i < projs.size(); i++) {
projs.get(i).setAlias(ctx);
buffer.append(projs.get(i).asProjection(ctx));
if (i != projs.size()-1)
buffer.append(",");
}
buffer.append(" FROM ");
for (int i=0; _domains != null && i < _domains.size(); i++) {
buffer.append(_domains.get(i).asJoinable(ctx));
List<JoinPath> joins = _domains.get(i).getJoins();
if (joins != null) {
for (int j = 0; j < joins.size(); j++) {
buffer.append(joins.get(j).asJoinable(ctx));
}
}
List<FetchPath> fetchJoins = _domains.get(i).getFetchJoins();
if (fetchJoins != null) {
for (int j = 0; j < fetchJoins.size(); j++) {
buffer.append(fetchJoins.get(j).asExpression(ctx));
}
}
if (i != _domains.size()-1)
buffer.append(",");
}
if (_where != null) {
buffer.append(" WHERE ").append(((Visitable)_where).asExpression(ctx));
}
if (_groupBys != null) {
buffer.append(" GROUP BY ");
for (int i = 0; i<_groupBys.size(); i++) {
buffer.append(((ExpressionImpl)_groupBys.get(i)).asExpression(ctx));
if (i != _groupBys.size()-1)
buffer.append(",");
}
}
if (_having != null) {
buffer.append(" HAVING ").append(((Visitable)_having).asExpression(ctx));
}
if (_orderBys != null) {
buffer.append(" ORDER BY ");
for (int i = 0; i<_orderBys.size(); i++) {
buffer.append(((OrderableItem)_orderBys.get(i)).toJPQL(ctx));
if (i != _orderBys.size()-1)
buffer.append(",");
}
}
return buffer.toString();
}
public String asProjection(AliasContext ctx) {
return asExpression(ctx);
}
/**
* Registers each domain with an alias.
* @param ctx
*/
private void registerDomains(AliasContext ctx) {
if (_domains != null) {
for (AbstractDomainObject domain : _domains) {
domain.setAlias(ctx);
}
}
if (_subqueries != null) {
for (Subquery sub : _subqueries) {
if (sub instanceof QueryDefinitionImpl)
((QueryDefinitionImpl)sub).registerDomains(ctx);
else
((AbstractDomainObject)sub).setAlias(ctx);
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.Subquery;
/**
* An expression resulting from operation on a query itself. Can be used as a
* subquery clause in a parent query.
*
* @author Pinaki Poddar
*
*/
abstract class QueryExpression extends UnaryOperatorExpression
implements Subquery {
public QueryExpression(QueryDefinitionImpl q, UnaryFunctionalOperator op) {
super(q, op);
}
@Override
public String asExpression(AliasContext ctx) {
return "(" + super.asExpression(ctx) + ")";
}
}

View File

@ -0,0 +1,39 @@
/*
* 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.Expression;
/**
* Denotes a range used by MEMBER OF operation.
*
* @author Pinaki Poddar
*
*/
public class RangeExpression extends BinaryOperatorExpression {
public RangeExpression(Expression e1, Expression e2) {
super(e1, BinaryFunctionalOperator.RANGE, e2);
}
@Override
public String asExpression(AliasContext ctx) {
return "(" + ((Visitable)_e1).asExpression(ctx)
+ " AND " + ((Visitable)_e2).asExpression(ctx) + ")";
}
}

View File

@ -0,0 +1,41 @@
package org.apache.openjpa.persistence.query;
import javax.persistence.DomainObject;
/**
* Denotes root domain instance representing a persistent type.
*
* @author Pinaki Poddar
*
*/
public class RootPath extends AbstractDomainObject implements DomainObject {
public RootPath(QueryDefinitionImpl owner, Class cls) {
super(owner, null, PathOperator.ROOT, cls);
}
@Override
public Class getLastSegment() {
return (Class)super.getLastSegment();
}
@Override
public String getAliasHint() {
return getLastSegment().getSimpleName();
}
@Override
public String asExpression(AliasContext ctx) {
return ctx.getAlias(this);
}
@Override
public String asJoinable(AliasContext ctx) {
return getLastSegment().getSimpleName() + " " + ctx.getAlias(this);
}
@Override
public String asProjection(AliasContext ctx) {
return ctx.getAlias(this);
}
}

View File

@ -0,0 +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 javax.persistence.SelectItem;
/**
* An item that can be selected in a query.
*
* @author Pinaki Poddar
*
*/
public interface Selectable extends SelectItem {
String asProjection(AliasContext ctx);
void setAlias(AliasContext ctx);
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes SIZE(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class SizeExpression extends UnaryOperatorExpression {
public SizeExpression(Expression op) {
super(op, UnaryFunctionalOperator.SIZE);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Subquery;
/**
* Denotes SOME(Subquery) Expression.
*
* @author Pinaki Poddar
*
*/
class SomeExpression extends UnaryOperatorExpression implements Subquery {
public SomeExpression(QueryDefinitionImpl sub) {
super(sub, UnaryFunctionalOperator.SOME);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes SQRT(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class SquareRootExpression extends UnaryOperatorExpression {
public SquareRootExpression(Expression op) {
super(op, UnaryFunctionalOperator.SQRT);
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.Expression;
/**
* Denotes SUBSTR(a,i1,i2) Expression.
*
* @author Pinaki Poddar
*
*/
public class SubStringExpression extends BinaryOperatorExpression {
public SubStringExpression(Expression op, Expression op2) {
this(op, op2, new ConstantExpression(0));
}
public SubStringExpression(Expression op, int start) {
this(op, start, 0);
}
public SubStringExpression(Expression op, int start, int len) {
this(op, new ConstantExpression(start), new ConstantExpression(len));
}
public SubStringExpression(Expression op, Expression op2, Expression pos) {
super(op, BinaryFunctionalOperator.SUBSTR, op2);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes SUM(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class SumExpression extends UnaryOperatorExpression {
public SumExpression(Expression op) {
super(op, UnaryFunctionalOperator.SUM);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes (e1*e2) Expression.
*
* @author Pinaki Poddar
*
*/
public class TimesExpression extends BinaryOperatorExpression {
public TimesExpression(Expression op1, Expression op2) {
super(op1, BinaryFunctionalOperator.TIMES, op2);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes UPPER(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class ToUpperExpression extends UnaryOperatorExpression {
public ToUpperExpression(Expression op) {
super(op, UnaryFunctionalOperator.UPPER);
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.Expression;
import javax.persistence.TrimSpec;
/**
* Denotes TRIM(e1,x) Expression.
*
* @author Pinaki Poddar
*
*/
public class TrimExpression extends BinaryOperatorExpression {
TrimSpec _spec;
public TrimExpression(Expression op1, char ch, TrimSpec spec) {
super(op1, BinaryFunctionalOperator.TRIM, new ConstantExpression(ch));
_spec = spec;
}
public TrimExpression(Expression op, Expression op1, TrimSpec spec) {
super(op, BinaryFunctionalOperator.TRIM, op1);
_spec = spec;
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.Expression;
/**
* Denotes TYPE(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class TypeExpression extends UnaryOperatorExpression {
public TypeExpression(Expression op) {
super(op, UnaryFunctionalOperator.TYPE);
}
}

View File

@ -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.openjpa.persistence.query;
/**
* Enumeration of operator that operates on a single expression to generate
* a predicate.
*
* @see UnaryOperatorExpression
*
* @author Pinaki Poddar
*
*/
public enum UnaryConditionalOperator {
EXISTS("EXISTS"),
EXISTS_NOT("NOT EXISTS"),
ISEMPTY("IS EMPTY"),
ISEMPTY_NOT("IS NOT EMPTY"),
ISNULL("IS NULL"),
ISNULL_NOT("IS NOT NULL"),
SOME("SOME");
private final String _symbol;
UnaryConditionalOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.Expression;
import javax.persistence.Predicate;
/**
* Unary Predicate results from an operator on an Expression.
*
* @author Pinaki Poddar
*
*/
class UnaryExpressionPredicate implements Predicate, Visitable {
protected final Expression _e;
protected final UnaryConditionalOperator _op;
private final UnaryConditionalOperator _nop;
public UnaryExpressionPredicate(Expression e, UnaryConditionalOperator op,
UnaryConditionalOperator nop) {
this._e = e;
this._op = op;
this._nop = nop;
}
public Expression getOperand() {
return _e;
}
public UnaryConditionalOperator getOperator() {
return _op;
}
public Predicate and(Predicate predicate) {
return new AndPredicate(this, predicate);
}
public Predicate or(Predicate predicate) {
return new OrPredicate(this, predicate);
}
public Predicate not() {
if (_nop == null)
throw new UnsupportedOperationException(this.toString());
return new UnaryExpressionPredicate(_e, _nop, _op);
}
public String asExpression(AliasContext ctx) {
return _op + "(" + ((ExpressionImpl)_e).asExpression(ctx) + ")";
}
}

View File

@ -0,0 +1,61 @@
/*
* 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;
/**
* Enumeration of operator that operates on a single expression to generate
* another expression.
*
* @see UnaryOperatorExpression
*
* @author Pinaki Poddar
*
*/
public enum UnaryFunctionalOperator {
ABS("ABS"),
ALL("ALL"),
ANY("ANY"),
AVG("AVG"),
COUNT("COUNT"),
DISTINCT("DISTINCT"),
EXISTS("EXISTS"),
INDEX("INDEX"),
LENGTH("LENGTH"),
LOCATE("LOCATE"),
LOWER("TOLOWER"),
MAX("MAX"),
MIN("MIN"),
MINUS("-"),
SIZE("SIZE"),
SOME("SOME"),
SQRT("SQRT"),
SUM("SUM"),
TYPE("TYPE"),
UPPER("TOUPPER");
private final String _symbol;
UnaryFunctionalOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.Expression;
/**
* Denotes (-e) Expression.
*
* @author Pinaki Poddar
*
*/
public class UnaryMinusExpression extends UnaryOperatorExpression {
public UnaryMinusExpression(Expression expr) {
super(expr, UnaryFunctionalOperator.MINUS);
}
}

View File

@ -0,0 +1,65 @@
/*
* 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;
/**
* Enumeration of Operator that operate on a single expression.
*
* @author Pinaki Poddar
*
*/
public enum UnaryOperator {
ABS("ABS"),
ALL("ALL"),
ANY("ANY"),
AVG("AVG"),
COUNT("COUNT"),
DISTINCT("DISTINCT"),
EXISTS("EXISTS"),
INDEX("INDEX"),
ISEMPTY("IS EMPTY"),
ISEMPTY_NOT("IS NOT EMPTY"),
ISNULL("IS NULL"),
ISNULL_NOT("IS NOT NULL"),
LENGTH("LENGTH"),
LOCATE("LOCATE"),
LOWER("TOLOWER"),
MAX("MAX"),
MIN("MIN"),
MINUS("-"),
SIZE("SIZE"),
SOME("SOME"),
SQRT("SQRT"),
SUBSTRING("SUBSTR"),
SUM("SUM"),
TIMES("*"),
TRIM("TRIM"),
TYPE("TYPE"),
UPPER("TOUPPER");
private final String _symbol;
UnaryOperator(String symbol) {
_symbol = symbol;
}
public String toString() {
return _symbol;
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.Aggregate;
import javax.persistence.Expression;
class UnaryOperatorExpression extends ExpressionImpl implements Aggregate {
protected final Expression _e;
protected final UnaryFunctionalOperator _op;
public UnaryOperatorExpression(Expression e, UnaryFunctionalOperator op) {
_e = e;
_op = op;
}
public Expression getOperand() {
return _e;
}
public UnaryFunctionalOperator getOperator() {
return _op;
}
public Expression distinct() {
return new DistinctExpression(this);
}
public String asExpression(AliasContext ctx) {
return _op + "(" + ((Visitable)_e).asExpression(ctx) + ")";
}
public String asProjection(AliasContext ctx) {
return _op + "(" + ((Selectable)_e).asProjection(ctx) + ")";
}
}

View File

@ -0,0 +1,31 @@
/*
* 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;
/**
* Denotes VALUE(e) Expression.
*
* @author Pinaki Poddar
*
*/
public class ValueExpression extends OperatorPath {
public ValueExpression(AbstractDomainObject expr) {
super(expr, PathOperator.VALUE);
}
}

View File

@ -0,0 +1,33 @@
/*
* 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;
/**
* An element of query that is convertible to a JPQL String given a aliasing
* scheme. QueryDefinition visits each of its element and translates them.
*
* @author Pinaki Poddar
*
*/
public interface Visitable {
/**
* Get a JPQL fragment as used in a WHERE clause.
*/
String asExpression(AliasContext ctx);
}

View File

@ -0,0 +1,55 @@
/*
* 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;
/**
* Denotes WHEN ... THEN ... clause of a Case Statement.
*
* @author Pinaki Poddar
*
*/
public class WhenClause {
private final Object when;
private Object then;
WhenClause(Object op) {
when = op;
}
Object getThen() {
return then;
}
void setThen(Object then) {
if (hasThen())
throw new IllegalStateException("then() is already set");
this.then = then;
}
boolean hasThen() {
return then != null;
}
public String toJPQL(AliasContext ctx) {
StringBuffer tmp = new StringBuffer();
tmp.append(" WHEN ").append(JPQLHelper.toJPQL(ctx, when))
.append(" THEN ").append(JPQLHelper.toJPQL(ctx, then));
return tmp.toString();
}
}