You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2009/09/11 05:22:03 UTC
svn commit: r813658 - in /openjpa/trunk:
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/
openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/
openjpa-persistence/src/main/java/org/apache/openjpa/per...
Author: ppoddar
Date: Fri Sep 11 03:22:00 2009
New Revision: 813658
URL: http://svn.apache.org/viewvc?rev=813658&view=rev
Log:
OPENJPA-1288: stop re-alias(). Added new utility to check validity of names for JPA reserved words and special symbols.
Added:
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java (with props)
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaBuilder.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java?rev=813658&r1=813657&r2=813658&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java Fri Sep 11 03:22:00 2009
@@ -1261,7 +1261,7 @@
}
}
- public void testAlias() {
+ public void testAliasInOrderByClause() {
String jpql = "SELECT AVG(a.balance) AS x FROM Account a ORDER BY x";
OpenJPACriteriaQuery<Double> c = cb.createQuery(Double.class);
@@ -1275,4 +1275,63 @@
assertEquivalence(c, jpql);
assertEquals(jpql, c.toCQL());
}
+
+ public void testRealiasNotAllowed() {
+ OpenJPACriteriaQuery<Double> c = cb.createQuery(Double.class);
+ Root<Account> account = c.from(Account.class);
+ Selection<Double> term = cb.avg(account.get(Account_.balance));
+ term.alias("firsttime");
+ try {
+ term.alias("secondtime");
+ fail("Expected to fail on re-aliasing");
+ } catch (IllegalStateException e) {
+ // good
+ }
+ }
+
+ public void testInvalidAliasNotAllowed() {
+ OpenJPACriteriaQuery<Double> c = cb.createQuery(Double.class);
+ Root<Account> account = c.from(Account.class);
+ Selection<Double> term = cb.avg(account.get(Account_.balance));
+ try {
+ term.alias("from");
+ fail("Expected to fail on reserved word as alias");
+ } catch (IllegalArgumentException e) {
+ // good
+ assertNull(term.getAlias());
+ }
+ try {
+ term.alias(" with a space");
+ fail("Expected to fail on invalid alias");
+ } catch (IllegalArgumentException e) {
+ // good
+ assertNull(term.getAlias());
+ }
+ try {
+ term.alias(" with?known_symbol");
+ fail("Expected to fail on invalid alias");
+ } catch (IllegalArgumentException e) {
+ // good
+ assertNull(term.getAlias());
+ }
+ }
+
+ public void testInvalidParameterName() {
+ try {
+ cb.parameter(Integer.class, "from");
+ fail("Expected to fail on reserved word as alias");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ cb.parameter(Integer.class, ":name");
+ fail("Expected to fail on invalid alias");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ cb.parameter(Integer.class, "?3");
+ fail("Expected to fail on invalid alias");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaBuilder.java?rev=813658&r1=813657&r2=813658&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaBuilder.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/OpenJPACriteriaBuilder.java Fri Sep 11 03:22:00 2009
@@ -4,6 +4,7 @@
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.QueryBuilder;
import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Metamodel;
/**
* OpenJPA-specific extension to JPA 2.0 Criteria Query Builder API.
@@ -57,5 +58,9 @@
* Create a mutable style to apply on query-by-example.
*/
public ComparisonStyle qbeStyle();
-
+
+ /**
+ * Gets the metamodel for the managed, persistent domain entities.
+ */
+ public Metamodel getMetamodel();
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java?rev=813658&r1=813657&r2=813658&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ParameterExpressionImpl.java Fri Sep 11 03:22:00 2009
@@ -52,6 +52,8 @@
*/
public ParameterExpressionImpl(Class<T> cls, String name) {
super(cls);
+ if (name != null)
+ assertValidName(name);
_name = name;
}
Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java?rev=813658&r1=813657&r2=813658&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SelectionImpl.java Fri Sep 11 03:22:00 2009
@@ -23,6 +23,8 @@
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Selection;
+import org.apache.openjpa.persistence.util.ReservedWords;
+
/**
* An item selected in the projection clause of Criteria query.
* Base implementation for all concrete expressions.
@@ -34,7 +36,7 @@
public abstract class SelectionImpl<X> implements Selection<X>, CriteriaExpression {
private final Class<X> _cls;
private String _alias;
- private Boolean _autoAliased;
+ private Boolean _autoAliased;
/**
* Construct with the immutable type represented by this selection term.
@@ -59,8 +61,13 @@
/**
* Sets the alias on this selection term.
+ * Alias can only be set once.
*/
public Selection<X> alias(String alias) {
+ assertValidName(alias);
+ if (isAliased())
+ throw new IllegalStateException(this + " has been aliased to [" + _alias
+ + ". Can not alias again to " + alias);
_alias = alias;
_autoAliased = false;
return this;
@@ -71,8 +78,8 @@
* by calling {@linkplain #alias(String)}.
*/
void setAutoAlias(String alias) {
- if (Boolean.FALSE.equals(_autoAliased))
- throw new IllegalStateException(this + " has been aliased. Can not set alias automatically");
+ if (isAliased())
+ throw new IllegalStateException(this + " has been aliased. Can not set alias internally");
_alias = alias;
_autoAliased = true;
}
@@ -83,6 +90,15 @@
boolean isAutoAliased() {
return _autoAliased == null ? true : _autoAliased.booleanValue();
}
+
+ /**
+ * Affirms if this expression has been assigned an alias by {@linkplain #alias(String)} method.
+ * An alias can be assigned also by internal implementation.
+ * @see #isAutoAliased()
+ */
+ boolean isAliased() {
+ return Boolean.FALSE.equals(_autoAliased);
+ }
/**
* Throws IllegalStateException because a selection term, by default, consists of single value.
@@ -98,6 +114,16 @@
return false;
}
+ void assertValidName(String name) {
+ if (name == null || name.trim().length() == 0)
+ throw new IllegalArgumentException("empty name is invalid");
+ if (ReservedWords.isKeyword(name))
+ throw new IllegalArgumentException("reserved word " + name + " is not valid");
+ Character ch = ReservedWords.hasSpecialCharacter(name);
+ if (ch != null)
+ throw new IllegalArgumentException(name + " contains reserved symbol " + ch);
+ }
+
// ------------------------------------------------------------------------------------
// Contract for CriteriaExpression implemented mostly as a no-op for easier derivation.
// ------------------------------------------------------------------------------------
Added: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java?rev=813658&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java (added)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java Fri Sep 11 03:22:00 2009
@@ -0,0 +1,85 @@
+package org.apache.openjpa.persistence.util;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/*
+ * 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.
+ */
+
+/**
+ * Utility to test validity of identifier or parameter name.
+ *
+ * @author Pinaki Poddar
+ * @since 2.0.0
+ *
+ */
+public class ReservedWords {
+ public static final Set<String> KEYWORDS = new HashSet<String>();
+ static {
+ KEYWORDS.addAll(Arrays.asList(
+ "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG",
+ "BETWEEN", "BIT_LENGTH", "BOTH", "BY",
+ "CASE", "CHAR_LENGTH", "CHARACTER_LENGTH", "CLASS", "COALESCE", "CONCAT", "COUNT",
+ "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
+ "DELETE", "DESC", "DISTINCT",
+ "ELSE", "EMPTY", "END", "ENTRY", "ESCAPE", "EXISTS",
+ "FALSE", "FETCH", "FROM",
+ "GROUP",
+ "HAVING",
+ "IN", "INDEX", "INNER", "IS",
+ "JOIN",
+ "KEY",
+ "LEADING", "LEFT", "LENGTH", "LIKE", "LOCATE", "LOWER",
+ "MAX", "MEMBER", "MIN", "MOD",
+ "NEW", "NOT", "NULL", "NULLIF",
+ "OBJECT", "OF", "OR", "ORDER", "OUTER",
+ "POSITION",
+ "SELECT", "SET", "SIZE", "SOME", "SQRT", "SUBSTRING", "SUM",
+ "THEN", "TRAILING", "TRIM", "TRUE", "TYPE",
+ "UNKNOWN[50]", "UPDATE", "UPPER",
+ "VALUE",
+ "WHEN", "WHERE"));
+ };
+
+ /**
+ * Affirms if the given string matches any of the JPA reserved words in a case-insensitive manner.
+ */
+ public static boolean isKeyword(String name) {
+ return name != null && KEYWORDS.contains(name.toUpperCase());
+ }
+
+ /**
+ * Returns the special character contained in the given name if any.
+ *
+ * @return null if no character in the given name is a special character.
+ */
+ public static Character hasSpecialCharacter(String name) {
+ if (name == null)
+ return null;
+ char[] chars = name.toCharArray();
+ if (!Character.isJavaIdentifierStart(chars[0]))
+ return chars[0];
+ for (int i = 1; i < chars.length; i++) {
+ if (!Character.isJavaIdentifierPart(chars[i]))
+ return chars[i];
+ }
+ return null;
+ }
+}
Propchange: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/util/ReservedWords.java
------------------------------------------------------------------------------
svn:eol-style = native