Hibernate SVN: r11010 - in branches/Hibernate_3_0_5_JBAS-3961/Hibernate3: lib src/org/hibernate/transaction
by hibernate-commits@lists.jboss.org
Author: amit.bhayani(a)jboss.com
Date: 2006-12-24 11:24:10 -0500 (Sun, 24 Dec 2006)
New Revision: 11010
Added:
branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/cglib-2.1.3.jar
Removed:
branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/cglib-2.1.jar
Modified:
branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/version.properties
branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java
Log:
Changes to fix JBAS-3961. Patch creation
Added: branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/cglib-2.1.3.jar
===================================================================
(Binary files differ)
Property changes on: branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/cglib-2.1.3.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/cglib-2.1.jar
===================================================================
(Binary files differ)
Modified: branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/version.properties
===================================================================
--- branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/version.properties 2006-12-22 18:50:40 UTC (rev 11009)
+++ branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/lib/version.properties 2006-12-24 16:24:10 UTC (rev 11010)
@@ -47,8 +47,8 @@
versioncheck.name=version checker
versioncheck.when=buildtime
-cglib.lib=cglib-2.1.jar
-cglib.version=2.1.0
+cglib.lib=cglib-2.1.3.jar
+cglib.version=2.1.3
cglib.name=CGLIB bytecode generator
cglib.when=runtime, required
Modified: branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java
===================================================================
--- branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java 2006-12-22 18:50:40 UTC (rev 11009)
+++ branches/Hibernate_3_0_5_JBAS-3961/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java 2006-12-24 16:24:10 UTC (rev 11010)
@@ -133,10 +133,10 @@
if (!commitFailed) {
- beforeTransactionCompletion();
+ /*beforeTransactionCompletion();
if ( callback ) {
jdbcContext.beforeTransactionCompletion( this );
- }
+ }*/
try {
rollbackAndResetAutoCommit();
18 years
Hibernate SVN: r11009 - branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-12-22 13:50:40 -0500 (Fri, 22 Dec 2006)
New Revision: 11009
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
Log:
it translation
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-22 08:58:13 UTC (rev 11008)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-22 18:50:40 UTC (rev 11009)
@@ -11,6 +11,6 @@
validator.size=le dimensioni devono essere tra {min} e {max}
validator.email=not a well-formed email address
validator.notEmpty=non pu� essere nullo o vuoto
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
-validator.ean=invalid EAN
+validator.digits=Valore numerico fuori dai limiti (atteso <{integerDigits} cifre>.<{fractionalDigits} cifre>)
+validator.ean=EAN invalido
validator.creditCard=invalid credit card number
\ No newline at end of file
18 years
Hibernate SVN: r11008 - branches
by hibernate-commits@lists.jboss.org
Author: amit.bhayani(a)jboss.com
Date: 2006-12-22 03:58:13 -0500 (Fri, 22 Dec 2006)
New Revision: 11008
Added:
branches/Hibernate_3_0_5_JBAS-3961/
Log:
Creating Patch. Fix for JBAS-3961
Copied: branches/Hibernate_3_0_5_JBAS-3961 (from rev 11007, tags/v305)
18 years
Hibernate SVN: r11007 - branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-12-21 14:57:13 -0500 (Thu, 21 Dec 2006)
New Revision: 11007
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
Log:
translation
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-20 22:16:31 UTC (rev 11006)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-21 19:57:13 UTC (rev 11007)
@@ -11,6 +11,6 @@
validator.size=antallet skal v�re mellem {min} og {max}
validator.email=not a well-formed email address
validator.notEmpty=m� ikke v�re null eller tom
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
-validator.ean=invalid EAN
-validator.creditCard=invalid credit card number
\ No newline at end of file
+validator.digits=V�rdien er ikke inden for det forventede (<{integerDigits} heltal>.<{fractionalDigits} decimaler>)
+validator.ean=Ukorrekt EAN
+validator.creditCard=Ukorrekt kreditkort nummer
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-20 22:16:31 UTC (rev 11006)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-21 19:57:13 UTC (rev 11007)
@@ -13,4 +13,4 @@
validator.notEmpty=kann nicht null oder leer sein
validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
validator.ean=invalid EAN
-validator.creditCard=invalid credit card number
\ No newline at end of file
+validator.creditCard=Ung�ltige Kreditkartennummer
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-20 22:16:31 UTC (rev 11006)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-21 19:57:13 UTC (rev 11007)
@@ -11,6 +11,6 @@
validator.size=tamanho deve estar entre {min} e {max}
validator.email=n�o � um email v�lido
validator.notEmpty=n�o pode ser nulo ou vazio
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
-validator.ean=invalid EAN
-validator.creditCard=invalid credit card number
\ No newline at end of file
+validator.digits=Valor num�rico fora do padr�o (esperado <{integerDigits}> d�gitos,<{fractionalDigits} d�gitos)
+validator.ean=EAN inv�lido
+validator.creditCard=N�mero inv�lido de cart�o de cr�dito
\ No newline at end of file
18 years
Hibernate SVN: r11006 - branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-12-20 17:16:31 -0500 (Wed, 20 Dec 2006)
New Revision: 11006
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
Log:
translation
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-20 22:08:59 UTC (rev 11005)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-20 22:16:31 UTC (rev 11006)
@@ -11,6 +11,6 @@
validator.size=size must be between {min} and {max}
validator.email=not a well-formed email address
validator.notEmpty=may not be null or empty
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
-validator.creditCard=invalid credit card number
-validator.ean=invalid EAN
\ No newline at end of file
+validator.digits=Numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.creditCard=Invalid credit card number
+validator.ean=Invalid EAN
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-20 22:08:59 UTC (rev 11005)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-20 22:16:31 UTC (rev 11006)
@@ -11,6 +11,6 @@
validator.size=le nombre d'�l�ments doit �tre entre {min} et {max}
validator.email=Address email mal form�e
validator.notEmpty=ne peut pas �tre nul ou vide
-validator.digits=valeur num�rique hors limite (<{integerDigits} chiffres>.<{fractionalDigits} chiffres> attendus)
-validator.ean=invalid EAN
-validator.creditCard=invalid credit card number
\ No newline at end of file
+validator.digits=Valeur num�rique hors limite (<{integerDigits} chiffres>.<{fractionalDigits} chiffres> attendus)
+validator.ean=EAN invalide
+validator.creditCard=Num�ro de carte de cr�dit invalide
\ No newline at end of file
18 years
Hibernate SVN: r11005 - in branches/Branch_3_2/HibernateExt/metadata/src: java/org/hibernate/validator java/org/hibernate/validator/resources test/org/hibernate/validator/test/validator
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-12-20 17:08:59 -0500 (Wed, 20 Dec 2006)
New Revision: 11005
Added:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/AbstractLuhnValidator.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumber.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumberValidator.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EAN.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EANValidator.java
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/CreditCard.java
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/LuhnTest.java
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties
Log:
ANN-508 @CreditCardNumber
ANN-510 @EAN
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/AbstractLuhnValidator.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/AbstractLuhnValidator.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/AbstractLuhnValidator.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,40 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Implement the Luhn algorithm (with Luhn key on the last digit)
+ * @author Emmanuel Bernard
+ */
+public abstract class AbstractLuhnValidator {
+ abstract int multiplicator();
+
+ public boolean isValid(Object value) {
+ if (value == null) return true;
+ if ( ! ( value instanceof String) ) return false;
+ String creditCard = (String) value;
+ char[] chars = creditCard.toCharArray();
+
+ List<Integer> ints = new ArrayList<Integer>();
+ for (char c : chars) {
+ if ( Character.isDigit( c ) ) ints.add( c - '0' );
+ }
+ int length = ints.size();
+ int sum = 0;
+ boolean even = false;
+ for ( int index = length - 1 ; index >= 0 ; index-- ) {
+ int digit = ints.get(index);
+ if (even) {
+ digit *= multiplicator();
+ }
+ if (digit > 9) {
+ digit = digit / 10 + digit % 10;
+ }
+ sum+= digit;
+ even = !even;
+ }
+ return sum % 10 == 0;
+ }
+}
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumber.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumber.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumber.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,23 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The annotated element has to represent a valid
+ * credit card number. This is the Luhn algorithm implementation
+ * which aims to check for user mistake, not credit card validity!
+ *
+ * @author Emmanuel Bernard
+ */
+@Documented
+@ValidatorClass( CreditCardNumberValidator.class)
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+@Retention( RetentionPolicy.RUNTIME )
+public @interface CreditCardNumber {
+ String message() default "{validator.creditCard}";
+}
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumberValidator.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumberValidator.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/CreditCardNumberValidator.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,19 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.io.Serializable;
+
+/**
+ * Check a credit card number through the Luhn algorithm
+ *
+ * @author Emmanuel Bernard
+ */
+public class CreditCardNumberValidator extends AbstractLuhnValidator implements Validator<CreditCardNumber>, Serializable {
+
+ public void initialize(CreditCardNumber parameters) {
+ }
+
+ int multiplicator() {
+ return 2;
+ }
+}
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EAN.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EAN.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EAN.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,23 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The annotated element has to represent an EAN-13 or UPC-A
+ *
+ * which aims to check for user mistake, not actual number validity!
+ *
+ * @author Emmanuel Bernard
+ */
+@Documented
+@ValidatorClass( EANValidator.class)
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+@Retention( RetentionPolicy.RUNTIME )
+public @interface EAN {
+ String message() default "{validator.ean}";
+}
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EANValidator.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EANValidator.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/EANValidator.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,41 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Validate EAN13 and UPC-A
+ *
+ * @author Emmanuel Bernard
+ */
+public class EANValidator implements Validator<EAN> {
+
+ public void initialize(EAN parameters) {
+ }
+
+
+ public boolean isValid(Object value) {
+ if (value == null) return true;
+ if ( ! ( value instanceof String) ) return false;
+ String creditCard = (String) value;
+ char[] chars = creditCard.toCharArray();
+
+ List<Integer> ints = new ArrayList<Integer>();
+ for (char c : chars) {
+ if ( Character.isDigit( c ) ) ints.add( c - '0' );
+ }
+ int length = ints.size();
+ int sum = 0;
+ boolean even = false;
+ for ( int index = length - 1 ; index >= 0 ; index-- ) {
+ int digit = ints.get(index);
+ if (even) {
+ digit *= 3;
+ }
+ sum+= digit;
+ even = !even;
+ }
+ return sum % 10 == 0;
+ }
+}
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=size must be between {min} and {max}
validator.email=not a well-formed email address
validator.notEmpty=may not be null or empty
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.creditCard=invalid credit card number
+validator.ean=invalid EAN
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=antallet skal v�re mellem {min} og {max}
validator.email=not a well-formed email address
validator.notEmpty=m� ikke v�re null eller tom
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=muss zwischen {min} und {max} gross sein
validator.email=not a well-formed email address
validator.notEmpty=kann nicht null oder leer sein
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=el tama�o debe ser entre {min} y {max}
validator.email=no es una direcci�n de correo electr�nico bien formada
validator.notEmpty=no debe ser nulo o vac�o
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=le nombre d'�l�ments doit �tre entre {min} et {max}
validator.email=Address email mal form�e
validator.notEmpty=ne peut pas �tre nul ou vide
-validator.digits=valeur num�rique hors limite (<{integerDigits} chiffres>.<{fractionalDigits} chiffres> attendus)
\ No newline at end of file
+validator.digits=valeur num�rique hors limite (<{integerDigits} chiffres>.<{fractionalDigits} chiffres> attendus)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -12,3 +12,5 @@
validator.email=not a well-formed email address
validator.notEmpty=non pu� essere nullo o vuoto
validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=moet tussen {min} en {max} groot zijn
validator.email=moet een geldig e-mail adres zijn
validator.notEmpty=mag niet null of leeg zijn
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=tamanho deve estar entre {min} e {max}
validator.email=n�o � um email v�lido
validator.notEmpty=n�o pode ser nulo ou vazio
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=storlek m�ste vara mellan {min} och {max}
validator.email=ogiltig e-mail adress
validator.notEmpty=f�r inte vara tomt
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=\u5927\u5c0f\u5fc5\u987b\u4ecb\u4e8e {min} \u4e0e {max} \u4e4b\u95f4
validator.email=not a well-formed email address
validator.notEmpty=may not be null or empty
-validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties 2006-12-20 22:08:59 UTC (rev 11005)
@@ -11,4 +11,6 @@
validator.size=\u5927\u5c0f\u5fc5\u9808\u4ecb\u65bc{min} \u8207 {max} \u4e4b\u9593
validator.email=not a well-formed email address
validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
-validator.notEmpty=may not be null or empty
\ No newline at end of file
+validator.notEmpty=may not be null or empty
+validator.ean=invalid EAN
+validator.creditCard=invalid credit card number
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/CreditCard.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/CreditCard.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/CreditCard.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,14 @@
+//$Id: $
+package org.hibernate.validator.test.validator;
+
+import org.hibernate.validator.EAN;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class CreditCard {
+ @org.hibernate.validator.CreditCardNumber
+ public String number;
+ @EAN
+ public String ean;
+}
Added: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/LuhnTest.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/LuhnTest.java 2006-12-19 22:22:21 UTC (rev 11004)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/LuhnTest.java 2006-12-20 22:08:59 UTC (rev 11005)
@@ -0,0 +1,28 @@
+//$Id: $
+package org.hibernate.validator.test.validator;
+
+import junit.framework.TestCase;
+import org.hibernate.validator.ClassValidator;
+import org.hibernate.validator.InvalidValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class LuhnTest extends TestCase {
+ public void testCreditCard() {
+ CreditCard card = new CreditCard();
+ card.number = "1234567890123456";
+ ClassValidator<CreditCard> classValidator = new ClassValidator<CreditCard>( CreditCard.class );
+ InvalidValue[] invalidValues = classValidator.getInvalidValues( card );
+ assertEquals( 1, invalidValues.length );
+ card.number = "541234567890125"; //right CC (luhn compliant)
+ invalidValues = classValidator.getInvalidValues( card );
+ assertEquals( 0, invalidValues.length );
+ card.ean = "9782266156066"; //right EAN
+ invalidValues = classValidator.getInvalidValues( card );
+ assertEquals( 0, invalidValues.length );
+ card.ean = "9782266156067"; //wrong EAN
+ invalidValues = classValidator.getInvalidValues( card );
+ assertEquals( 1, invalidValues.length );
+ }
+}
18 years
Hibernate SVN: r11004 - in branches/HQL_ANTLR_2/Hibernate3: g2 src/org/hibernate/hql/ast src/org/hibernate/hql/ast/common src/org/hibernate/hql/ast/resolve src/org/hibernate/hql/ast/resolve/path src/org/hibernate/hql/ast/tree test/org/hibernate/test/hql/redesign
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-12-19 17:22:21 -0500 (Tue, 19 Dec 2006)
New Revision: 11004
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java
Removed:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
Modified:
branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
Log:
added initial basic select clause processing
Modified: branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 22:22:21 UTC (rev 11004)
@@ -44,10 +44,13 @@
PROPERTY_REF;
ENTITY_PERSISTER_REF;
COLLECTION_PERSISTER_REF;
+ PERSISTER_REF_REF;
BOGUS;
NAMED_PARAM;
ORDINAL_PARAM;
+
+ SELECT_CLAUSE;
}
@@ -125,7 +128,13 @@
protected void popWithFragmentPropertyPathContext() {
}
+ protected void pushSelectClausePropertyPathContext() {
+ }
+ protected void popSelectClausePropertyPathContext() {
+ }
+
+
// persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
@@ -158,17 +167,32 @@
return param;
}
+ protected void injectSelectAlias( AST selectExpression, AST alias) {
+ }
+
+ protected void registerSelectExpression(AST selectExpression) {
+ }
+
+ protected AST handleSelectedPropertyRef(AST propertyRef) {
+ return propertyRef;
+ }
}
-// The main statement rule.
+///////////////////////////////////////////////////////////////////////////////
+// The main statement rule
+
statement
: selectStatement | updateStatement | deleteStatement | insertStatement
;
-// --- HQL statements ---
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// The statement sub-rules
+
selectStatement
- : query
+ : query ( ( m:MINUS | u:UNION ) (a:ALL)? query )*
;
updateStatement
@@ -183,6 +207,8 @@
: #(INSERT { pushStatement( #insertStatement ); } intoClause query { popStatement(); })
;
+///////////////////////////////////////////////////////////////////////////////
+
query
: #(QUERY { pushStatement( #query ); }
// The first phase places the FROM first to make processing the SELECT simpler.
@@ -195,14 +221,50 @@
)
;
-// TODO : for now, just copy over the entire subtree
selectClause
- : #(SELECT (subtree)* )
+ : #( SELECT { pushSelectClausePropertyPathContext(); } ( d:DISTINCT )? x:selectExprList ) {
+ #selectClause = #([SELECT_CLAUSE,"{select clause}"], #d, #x);
+ popSelectClausePropertyPathContext();
+ }
;
-// -- Language sub-elements --
+selectExprList
+ : ( selectExprValue )+
+ ;
+selectExprValue
+ : ( selectExpr | aliasedSelectExpr ) {
+ registerSelectExpression( #selectExprValue );
+ }
+ ;
+aliasedSelectExpr
+ : #( AS se:selectExpr i:identifier! ) {
+ injectSelectAlias( #se, #i );
+ #aliasedSelectExpr = #se;
+ }
+ ;
+
+// TODO : the old grammar had both literal and constant available as select expressions, but that is probably not valid; it is certainly not valid for non-subqueries
+selectExpr
+ : (persisterReferenceAliasCheck) => persisterRefRef
+ | pr:propertyRef { #selectExpr = handleSelectedPropertyRef( #pr ); }
+ | arithmeticExpr
+ | count
+ | literal
+ | constant
+ ;
+
+persisterRefRef!
+ : alias:IDENT {
+ #persisterRefRef = #( [ PERSISTER_REF_REF, alias.getText() ] );
+ }
+ ;
+
+count
+ : #(COUNT ( DISTINCT | ALL )? ( propertyRef | literal | ROW_STAR ) )
+ ;
+
fromClause
: #( f:FROM rootFromElement ( explicitJoin | rootFromElement )* )
;
@@ -443,10 +505,6 @@
| #( INDICES propertyRef )
;
-count
- : #(COUNT ( DISTINCT | ALL )? ( aggregateExpr | ROW_STAR ) )
- ;
-
aggregateExpr
: expr
| collectionFunction
@@ -490,12 +548,16 @@
;
constant
- : literal
- | NULL
+ : NULL
| TRUE
| FALSE
+ | javaConstant
;
+javaConstant
+ : JAVA_CONSTANT
+ ;
+
literal
: NUM_INT
| NUM_LONG
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java (from rev 11003, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java)
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -0,0 +1,62 @@
+package org.hibernate.hql.ast.common;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * Represents a canonical join type.
+ * <p/>
+ * Note that currently HQL really only supports inner and left outer joins
+ * (though cross joins can also be achieved). This is because joins in HQL
+ * are always defined in relation to a mapped association. However, when we
+ * start allowing users to specify ad-hoc joins this may need to change to
+ * allow the full spectrum of join types. Thus the others are provided here
+ * currently just for completeness and for future expansion.
+ *
+ * @author Steve Ebersole
+ */
+public class JoinType implements Serializable {
+ /**
+ * Represents an inner join.
+ */
+ public static final JoinType INNER = new JoinType( "inner" );
+ /**
+ * Represents a left outer join.
+ */
+ public static final JoinType LEFT = new JoinType( "left outer" );
+ /**
+ * Represents a right outer join.
+ */
+ public static final JoinType RIGHT = new JoinType( "right outer" );
+ /**
+ * Represents a cross join (aka a cartesian product).
+ */
+ public static final JoinType CROSS = new JoinType( "cross" );
+ /**
+ * Represents a full join.
+ */
+ public static final JoinType FULL = new JoinType( "full" );
+
+ private static final HashMap INSTANCES = new HashMap();
+ static {
+ INSTANCES.put( INNER.name, INNER );
+ INSTANCES.put( LEFT.name, LEFT );
+ INSTANCES.put( RIGHT.name, RIGHT );
+ INSTANCES.put( CROSS.name, CROSS );
+ INSTANCES.put( FULL.name, FULL );
+ }
+
+ private final String name;
+
+ private JoinType(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ private Object readResolve() {
+ return INSTANCES.get( name );
+ }
+}
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java (from rev 11003, branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java)
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -0,0 +1,18 @@
+package org.hibernate.hql.ast.common;
+
+import org.hibernate.hql.ast.PhaseContext;
+
+/**
+ * Injection service contract for nodes which require access to the current
+ * phase context during their lifetime.
+ *
+ * @author Steve Ebersole
+ */
+public interface PhaseContextAwareNode {
+ /**
+ * Inject a reference to the current {@link PhaseContext}.
+ *
+ * @param context The current {@link PhaseContext}
+ */
+ public void injectPhaseContext(PhaseContext context);
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -12,8 +12,13 @@
import org.hibernate.hql.ast.resolve.path.FromClausePathResolutionStrategy;
import org.hibernate.hql.ast.resolve.path.OnFragmentPathResolutionStrategy;
import org.hibernate.hql.ast.resolve.path.WithFragmentPathResolutionStrategy;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.CollectionType;
import antlr.collections.AST;
@@ -218,6 +223,15 @@
return getPersisterReferenceBuilder().buildJoinNode( lhs, ( PersisterReference ) rhs, joinType, null, false );
}
+ protected void injectSelectAlias(AST selectExpression, AST alias) {
+ ( ( SelectExpression ) selectExpression ).injectSelectAlias( alias.getText() );
+ }
+
+ protected void registerSelectExpression(AST selectExpression) {
+ log.debug( "registering select expression [" + selectExpression + "]" );
+ super.registerSelectExpression( selectExpression );
+ }
+
protected void applyWithFragment(AST withFragment) {
log.debug( printer.showAsString( withFragment, "WITH fragment" ) );
WithFragmentPathResolutionStrategy strategy = ( WithFragmentPathResolutionStrategy ) pathResolutionStrategyStack.getCurrent();
@@ -251,4 +265,34 @@
}
return buffer.toString();
}
+
+ protected AST handleSelectedPropertyRef(AST propertyRef) {
+ if ( propertyRef.getType() == PROPERTY_REF ) {
+ PropertyReference ref = ( PropertyReference ) propertyRef;
+ Type propType = ref.getPropertyType();
+ String propName = ref.getPropertyName();
+ if ( propType.isAssociationType() ) {
+ // force the join (unless already joined) and mutate into a PERSISTER_REF_REF node...
+ PersisterReference origin = ref.getOrigination();
+ JoinNode join = origin.locateReusableJoinByProperty( propName );
+ if ( join == null ) {
+ final PersisterReference rhs;
+ if ( propType.isEntityType() ) {
+ final String entityName = ( ( EntityType ) propType ).getAssociatedEntityName( sessionFactory );
+ rhs = persisterReferenceBuilder.buildEntityPersisterReference( entityName, null, false );
+ }
+ else if ( propType.isCollectionType() ) {
+ final String role = ( ( CollectionType ) propType ).getRole();
+ rhs = persisterReferenceBuilder.buildCollectionPersisterReference( role, null, false );
+ }
+ else {
+ throw new HibernateException( "unexpected type [" + propType + "]" );
+ }
+ join = persisterReferenceBuilder.buildJoinNode( origin, rhs, JoinType.INNER, propName, false );
+ }
+ return astFactory.create( PERSISTER_REF_REF, join.getRhs().getAlias() );
+ }
+ }
+ return propertyRef;
+ }
}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -4,7 +4,7 @@
import antlr.Token;
import org.hibernate.hql.ast.HqlASTFactory;
-import org.hibernate.hql.ast.tree.PhaseContextAwareNode;
+import org.hibernate.hql.ast.common.PhaseContextAwareNode;
import org.hibernate.hql.antlr.ResolveTokenTypes;
/**
@@ -39,6 +39,8 @@
return JoinNode.class;
case PROPERTY_REF:
return PropertyReference.class;
+ case PERSISTER_REF_REF:
+ return PersisterReferenceAliasReferenceNode.class;
}
return super.getASTNodeType( tokenType );
}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -4,6 +4,7 @@
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.tree.DisplayableNode;
+import org.hibernate.hql.ast.common.JoinType;
/**
* Represents an HQL join. The coneptualization here is strictly that of
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -1,62 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-/**
- * Represents a canonical join type.
- * <p/>
- * Note that currently HQL really only supports inner and left outer joins
- * (though cross joins can also be achieved). This is because joins in HQL
- * are always defined in relation to a mapped association. However, when we
- * start allowing users to specify ad-hoc joins this may need to change to
- * allow the full spectrum of join types. Thus the others are provided here
- * currently just for completeness and for future expansion.
- *
- * @author Steve Ebersole
- */
-public class JoinType implements Serializable {
- /**
- * Represents an inner join.
- */
- public static final JoinType INNER = new JoinType( "inner" );
- /**
- * Represents a left outer join.
- */
- public static final JoinType LEFT = new JoinType( "left outer" );
- /**
- * Represents a right outer join.
- */
- public static final JoinType RIGHT = new JoinType( "right outer" );
- /**
- * Represents a cross join (aka a cartesian product).
- */
- public static final JoinType CROSS = new JoinType( "cross" );
- /**
- * Represents a full join.
- */
- public static final JoinType FULL = new JoinType( "full" );
-
- private static final HashMap INSTANCES = new HashMap();
- static {
- INSTANCES.put( INNER.name, INNER );
- INSTANCES.put( LEFT.name, LEFT );
- INSTANCES.put( RIGHT.name, RIGHT );
- INSTANCES.put( CROSS.name, CROSS );
- INSTANCES.put( FULL.name, FULL );
- }
-
- private final String name;
-
- private JoinType(String name) {
- this.name = name;
- }
-
- public String toString() {
- return name;
- }
-
- private Object readResolve() {
- return INSTANCES.get( name );
- }
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -0,0 +1,43 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.HibernateException;
+
+/**
+ * Represents a reference to a {@link PersisterReference}'s alias in another part of
+ * the HQL query...
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceAliasReferenceNode extends Node implements SelectExpression, PersisterReferenceContextAwareNode {
+ private PersisterReferenceContext persisterReferenceContext;
+ private String selectAlias;
+
+ private PersisterReference persisterReference;
+
+ public String getSelectAlias() {
+ return selectAlias;
+ }
+
+ public void injectSelectAlias(String selectAlias) {
+ this.selectAlias = selectAlias;
+ }
+
+ public PersisterReference getPersisterReference() {
+ if ( persisterReference == null ) {
+ if ( persisterReferenceContext == null ) {
+ throw new HibernateException( "PersisterReferenceContext not yet injected" );
+ }
+ persisterReference = persisterReferenceContext.locatePersisterReferenceByAlias( getPersisterReferenceAlias() );
+ }
+ return persisterReference;
+ }
+
+ public String getPersisterReferenceAlias() {
+ return getText();
+ }
+
+ public void injectPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext) {
+ this.persisterReferenceContext = persisterReferenceContext;
+ }
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -5,6 +5,7 @@
import org.hibernate.MappingException;
import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.persister.entity.EntityPersister;
/**
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -15,21 +15,23 @@
*
* @author Steve Ebersole
*/
-public class PropertyReference extends Node implements PersisterReferenceContextAwareNode, DisplayableNode {
+public class PropertyReference extends Node implements PersisterReferenceContextAwareNode, DisplayableNode, SelectExpression {
private PersisterReferenceContext persisterContext;
+ private String alias;
+
// caches
- private String alias;
+ private String originationAlias;
private String propertyName;
private Type propertyType;
private PersisterReference origin;
public String getOriginationAlias() {
- if ( alias == null ) {
- alias = getFirstChild().getText();
+ if ( originationAlias == null ) {
+ originationAlias = getFirstChild().getText();
}
- return alias;
+ return originationAlias;
}
public String getPropertyName() {
@@ -63,4 +65,12 @@
public String getDisplayText() {
return " {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
}
+
+ public void injectSelectAlias(String alias) {
+ this.alias = alias;
+ }
+
+ public String getSelectAlias() {
+ return alias;
+ }
}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -0,0 +1,11 @@
+package org.hibernate.hql.ast.resolve;
+
+/**
+ * Represents an atomic value in a select-clause value list.
+ *
+ * @author Steve Ebersole
+ */
+public interface SelectExpression {
+ public String getSelectAlias();
+ public void injectSelectAlias(String alias);
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -7,7 +7,7 @@
import org.hibernate.hql.ast.resolve.PersisterReference;
import org.hibernate.hql.ast.resolve.PropertyReference;
import org.hibernate.hql.ast.resolve.JoinNode;
-import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.hql.ast.resolve.CollectionPersisterReference;
import org.hibernate.hql.CollectionProperties;
import org.hibernate.type.ComponentType;
@@ -114,7 +114,7 @@
}
- private class SimpleReferencePathPart extends PropertyPathPartAdapter {
+ protected class SimpleReferencePathPart extends PropertyPathPartAdapter {
public PropertyPathPart resolveIntermediatePathPart(String propertyName) {
throw new HibernateException( "cannot dereference simple value as part of path expression" );
}
@@ -124,7 +124,7 @@
}
}
- private class ComponentReferencePathPart extends PropertyPathPartAdapter {
+ protected class ComponentReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyPath;
private final ComponentType componentType;
@@ -163,7 +163,7 @@
}
}
- private class EntityReferencePathPart extends PropertyPathPartAdapter {
+ protected class EntityReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyName;
@@ -201,7 +201,7 @@
}
}
- private class CollectionReferencePathPart extends PropertyPathPartAdapter {
+ protected class CollectionReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyName;
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -4,7 +4,7 @@
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.HibernateException;
-import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.hql.ast.resolve.ResolutionContext;
import org.hibernate.hql.ast.resolve.PropertyReference;
import org.hibernate.hql.ast.resolve.PersisterReference;
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -0,0 +1,17 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+
+/**
+ * Essentially the same stragety as {@link BasicPathResolutionStrategySupport}
+ * expcept that in the select clause an entity encountered as the terminal part
+ * must force a join...
+ *
+ * @author Steve Ebersole
+ */
+public class SelectClausePathResolutionStrategy extends BasicPathResolutionStrategySupport {
+ protected SelectClausePathResolutionStrategy(ResolutionContext resolutionContext) {
+ super( resolutionContext );
+ }
+
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -1,18 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.PhaseContext;
-
-/**
- * Injection service contract for nodes which require access to the current
- * phase context during their lifetime.
- *
- * @author Steve Ebersole
- */
-public interface PhaseContextAwareNode {
- /**
- * Inject a reference to the current {@link PhaseContext}.
- *
- * @param context The current {@link PhaseContext}
- */
- public void injectPhaseContext(PhaseContext context);
-}
Modified: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19 22:22:21 UTC (rev 11004)
@@ -6,6 +6,8 @@
import org.hibernate.hql.ast.resolve.SelectStatementNode;
import org.hibernate.hql.ast.resolve.StatementNode;
import org.hibernate.hql.ast.resolve.HqlResolver;
+import org.hibernate.hql.ast.resolve.SelectExpression;
+import org.hibernate.hql.ast.resolve.PersisterReferenceBuilder;
import org.hibernate.hql.QuerySplitter;
import org.hibernate.hql.antlr.ResolveTokenTypes;
import org.hibernate.engine.SessionFactoryImplementor;
@@ -24,6 +26,8 @@
public class ResolverTest extends TestCase implements ResolveTokenTypes {
private static final ASTPrinter hqlrPrinter = generatePrinter();
+ public static final String CONSTANT = "constant-value";
+
private static ASTPrinter generatePrinter() {
ASTPrinter rtn = new ASTPrinter( ResolveTokenTypes.class );
rtn.setShowClassNames( false );
@@ -56,11 +60,62 @@
JoinCounter.assertJoinCount( 1, ast );
}
- public void testSelectExpression() throws Throwable {
- resolve( "select a from Animal a" );
- resolve( "select a.mother as m from Animal as a" );
+ public void testSelectPersisterReference() throws Throwable {
+ AST query = resolve( "select a from Animal a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PERSISTER_REF_REF, selectExpression.getType() );
+ assertEquals( "a", selectExpression.getText() );
+ assertNull( ( ( SelectExpression ) selectExpression ).getSelectAlias() );
}
+ public void testSelectAssociationPropertyReference() throws Throwable {
+ AST query = resolve( "select a.mother as m from Animal as a" );
+ JoinCounter.assertJoinCount( 1, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PERSISTER_REF_REF, selectExpression.getType() );
+ // this should work since there is only one non-explicit persister alias...
+ assertEquals( "<gen:0>", selectExpression.getText() );
+ assertEquals( "m", ( ( SelectExpression ) selectExpression ).getSelectAlias() );
+ }
+
+ public void testSimpleSimplePropertyReference() throws Throwable {
+ AST query = resolve( "select a.name as m from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PROPERTY_REF, selectExpression.getType() );
+ assertEquals( "a.name", selectExpression.getText() );
+ assertEquals( "m", ( ( SelectExpression ) selectExpression ).getSelectAlias() );
+ }
+
+ public void testSelectPropertyRefCount() throws Throwable {
+ AST query = resolve( "select count(a.mother) from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.COUNT, selectExpression.getType() );
+ assertEquals( "count", selectExpression.getText() );
+ }
+
public void testExplicitImplicitJoin() throws Exception {
AST ast = resolve( "from Animal a left join fetch a.mother.mother.mother as ggm where ggm.name like '%weeble%'" );
assertTrue( ast instanceof SelectStatementNode );
@@ -173,16 +228,34 @@
}
}
public static void assertJoinCount(int expected, AST tree) {
- org.hibernate.test.hql.redesign.ResolverTest.JoinCounter.assertJoinCount( "incorrect join count", expected, tree );
+ JoinCounter.assertJoinCount( "incorrect join count", expected, tree );
}
public static void assertJoinCount(String failMessage, int expected, AST tree) {
- org.hibernate.test.hql.redesign.ResolverTest.JoinCounter counter = new org.hibernate.test.hql.redesign.ResolverTest.JoinCounter();
+ JoinCounter counter = new JoinCounter();
NodeTraverser walker = new NodeTraverser( counter );
walker.traverseDepthFirst( tree );
assertEquals( failMessage, expected, counter.count );
}
}
+ private static class SelectExpressionCounter implements NodeTraverser.VisitationStrategy {
+ int count;
+ public void visit(AST node) {
+ if ( node instanceof SelectExpression ) {
+ count++;
+ }
+ }
+ public static void assertSelectExpressionCount(int expected, AST tree) {
+ SelectExpressionCounter.assertSelectExpressionCount( "incorrect select expression count", expected, tree );
+ }
+ public static void assertSelectExpressionCount(String failMessage, int expected, AST tree) {
+ SelectExpressionCounter counter = new SelectExpressionCounter();
+ NodeTraverser walker = new NodeTraverser( counter );
+ walker.traverseDepthFirst( tree );
+ assertEquals( failMessage, expected, counter.count );
+ }
+ }
+
public static Test suite() {
return new TestSuite(org.hibernate.test.hql.redesign.ResolverTest.class);
}
18 years
Hibernate SVN: r11003 - in branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast: . resolve resolve/path tree
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-12-19 14:08:27 -0500 (Tue, 19 Dec 2006)
New Revision: 11003
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/PhaseContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
Removed:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/ASTFactoryAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReferenceContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
Log:
switched to a more in-line resolution of path expressions using org.hibernate.hql.ast.resolve.path.PathResolutionStrategy
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/PhaseContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/PhaseContext.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/PhaseContext.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,27 @@
+package org.hibernate.hql.ast;
+
+import antlr.ASTFactory;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Defines services which are available to any HQL translation phase.
+ *
+ * @author Steve Ebersole
+ */
+public interface PhaseContext {
+ /**
+ * Retrieve a reference to the factory associated with this context for
+ * creating AST/Node instances.
+ *
+ * @return The ASTFactory.
+ */
+ public ASTFactory getASTFactory();
+
+ /**
+ * Retrieve a reference to the session factory associated with this context.
+ *
+ * @return The session factory.
+ */
+ public SessionFactoryImplementor getSessionFactory();
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,10 +1,15 @@
package org.hibernate.hql.ast.resolve;
/**
- * {@inheritDoc}
+ * Contract for things which can be aliased by other parts of an HQL query.
*
* @author Steve Ebersole
*/
public interface Aliasable {
+ /**
+ * Get the alias by which other parts of an HQL query can refer to this.
+ *
+ * @return The alias.
+ */
public String getAlias();
}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,146 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * A reference to an {@link org.hibernate.persister.collection.CollectionPersister}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionPersisterReference extends EntityPersisterReference {
+
+ private String role;
+ private transient QueryableCollection persister;
+ private transient CollectionPropertyMapping propertyMapping;
+
+ /**
+ * Initializes the structure of this persister reference node.
+ * <p/>
+ * TODO : better to have these injected via constructor?
+ *
+ * @param role The role name of the corresponding {@link org.hibernate.persister.collection.CollectionPersister}.
+ * @param alias The HQL alias for this persister reference.
+ * @param propertyFetch Whether lazy property fetching should be applied.
+ */
+ public void initialize(String role, String alias, boolean propertyFetch) {
+ this.role = role;
+ super.initialize( alias, propertyFetch );
+ }
+
+ /**
+ * Retrieve a reference to the underlying collection persister.
+ *
+ * @return The collection persister.
+ */
+ public QueryableCollection getCollectionPersister() {
+ if ( persister == null ) {
+ persister = ( QueryableCollection ) getSessionFactory().getCollectionPersister( role );
+ }
+ return persister;
+ }
+
+ /**
+ * Retrieve the entity persister for the elements of this collection if
+ * the elements happen to be entities.
+ * <p/>
+ * TODO : perhaps we should just return null here in the case of non-entity elements?
+ *
+ * @return The element's entity persister.
+ * @throws HibernateException If the collection is not a collection of entities.
+ */
+ public Queryable getEntityPersister() {
+ if ( getCollectionPersister().getElementType().isEntityType() ) {
+ EntityType elementEntityType = ( EntityType ) getCollectionPersister().getElementType();
+ return ( Queryable ) elementEntityType.getAssociatedJoinable( getSessionFactory() );
+ }
+ else {
+ throw new HibernateException( "not a collection of entities" );
+ }
+ }
+
+ /**
+ *
+ * Retrieves the logical name; here the collection role of the underlying
+ * {@link org.hibernate.persister.collection.CollectionPersister}.
+ *
+ * @return The collection role.
+ */
+ public String getName() {
+ return role;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AssociationType getPersisterType() {
+ return ( AssociationType ) getCollectionPersister().getElementType();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Type getPropertyType(String propertyName) {
+ if ( CollectionProperties.isAnyCollectionProperty( propertyName ) ) {
+ if ( propertyMapping == null ) {
+ propertyMapping = new CollectionPropertyMapping( getCollectionPersister() );
+ }
+ return propertyMapping.toType( propertyName );
+ }
+ else {
+ Type elementType = getCollectionPersister().getElementType();
+ if ( elementType.isAssociationType() ) {
+ // a collection of entities
+ EntityType elementEntityType = ( EntityType ) elementType;
+ try {
+ Queryable elementEntityPersister = ( Queryable ) elementEntityType
+ .getAssociatedJoinable( getSessionFactory() );
+ return elementEntityPersister.getPropertyType( propertyName );
+ }
+ catch( Throwable t ) {
+ // ignore
+ }
+ }
+ else if ( elementType.isComponentType() ) {
+ ComponentType elementComponentType = ( ComponentType ) elementType;
+ String[] subPropertyNames = elementComponentType.getPropertyNames();
+ for ( int i = 0; i < subPropertyNames.length; i++ ) {
+ if ( subPropertyNames[i].equals( propertyName ) ) {
+ return elementComponentType.getSubtypes()[i];
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean containsProperty(String propertyName) {
+ // this should not be called for "collection properties" (i.e., size, index, etc)
+ // so we make that assumption here...
+ try {
+ return getPropertyType( propertyName ) != null;
+ }
+ catch( Throwable t ) {
+ // ignore
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "CollectionPersisterReference {role=" + getName() + ", alias=" + getAlias() +
+ ", element-type=" + getCollectionPersister().getElementType() + "}";
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,27 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.resolve.path.BasicPathResolutionStrategySupport;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+
+/**
+ * Specialized statement node for representing DELETE statements
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteStatementNode extends StatementNode {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PathResolutionStrategy buildBasicPathResolutionStrategy(ResolutionContext resolutionContext) {
+ return new BasicPathResolutionStrategySupport( resolutionContext ) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException(
+ "delete statement cannot contain path expressions resolving to implicit joins"
+ );
+ }
+ };
+ }
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,113 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+
+/**
+ * A reference to an {@link org.hibernate.persister.entity.EntityPersister}.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityPersisterReference extends PersisterReference {
+
+ private String entityName;
+ private String alias;
+ private boolean propertyFetch;
+ private transient Queryable persister;
+
+ /**
+ * Initializes the structure of this persister reference node.
+ * <p/>
+ * TODO : better to have these injected via constructor?
+ *
+ * @param entityName The entity-name of the corresponding {@link org.hibernate.persister.entity.EntityPersister}.
+ * @param alias The HQL alias for this persister reference.
+ * @param propertyFetch Whether lazy property fetching should be applied.
+ */
+ public void initialize(String entityName, String alias, boolean propertyFetch) {
+ this.entityName = entityName;
+ initialize( alias, propertyFetch );
+ }
+
+ protected void initialize(String alias, boolean propertyFetch) {
+ this.alias = alias;
+ this.propertyFetch = propertyFetch;
+ }
+
+ /**
+ * Retrieves a reference to the underlying entity persister.
+ *
+ * @return The underlying entity persister.
+ */
+ public Queryable getEntityPersister() {
+ if ( persister == null ) {
+ persister = ( Queryable ) getSessionFactory().getEntityPersister( entityName );
+ }
+ return persister;
+ }
+
+ /**
+ * Retrieves the logical name; here the entity-name of the underlying
+ * {@link org.hibernate.persister.entity.EntityPersister}.
+ *
+ * @return The entity-name.
+ */
+ public String getName() {
+ return entityName;
+ }
+
+ /**
+ * Retrieve the alias by which the persister reference can be located from the
+ * {@link PersisterReferenceContext}.
+ *
+ * @return The HQL alias.
+ */
+ public String getAlias() {
+ return alias;
+ }
+
+ /**
+ * Is lazy property fetching enabled for this persister reference.
+ *
+ * @return True if this persister reference indicates that lazy properties
+ * be immediately fetched; false otherwise.
+ */
+ public boolean isPropertyFetch() {
+ return propertyFetch;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AssociationType getPersisterType() {
+ return ( AssociationType ) getEntityPersister().getType();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Type getPropertyType(String propertyName) {
+ try {
+ return getEntityPersister().getPropertyType( propertyName );
+ }
+ catch( Throwable t ) {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean containsProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "EntityPersisterReference {entity-name=" + entityName + ", alias=" + alias + "}";
+ }
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,254 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.hql.antlr.GeneratedHqlResolver;
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategyStack;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+import org.hibernate.hql.ast.resolve.path.PropertyPathPart;
+import org.hibernate.hql.ast.resolve.path.FromClausePathResolutionStrategy;
+import org.hibernate.hql.ast.resolve.path.OnFragmentPathResolutionStrategy;
+import org.hibernate.hql.ast.resolve.path.WithFragmentPathResolutionStrategy;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.QueryException;
+
+import antlr.collections.AST;
+
+/**
+ * Actual resolver implementation used in the query translator providing
+ * semantic action implementation.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class HqlResolver extends GeneratedHqlResolver implements ResolutionContext {
+
+ private static final Log log = LogFactory.getLog( HqlResolver.class );
+ private static final ASTPrinter printer = new ASTPrinter( ResolveTokenTypes.class ).setShowClassNames( false );
+
+ private final SessionFactoryImplementor sessionFactory;
+ private final PersisterReferenceBuilder persisterReferenceBuilder;
+
+ private StatementNode currentStatement;
+ private PathResolutionStrategyStack pathResolutionStrategyStack = new PathResolutionStrategyStack();
+
+ public HqlResolver(SessionFactoryImplementor sessionFactory) {
+ super();
+ this.sessionFactory = sessionFactory;
+ setASTFactory( new HqlResolverASTFactory( this ) );
+ persisterReferenceBuilder = new PersisterReferenceBuilder( this );
+ }
+
+
+ // ResolutionContext implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public SessionFactoryImplementor getSessionFactory() {
+ return sessionFactory;
+ }
+
+ public PersisterReferenceContext getCurrentPersisterReferenceContext() {
+ return currentStatement.getPersisterReferenceContext();
+ }
+
+ public PersisterReferenceBuilder getPersisterReferenceBuilder() {
+ return persisterReferenceBuilder;
+ }
+
+ public PathResolutionStrategy getCurrentPathResolutionStrategy() {
+ return pathResolutionStrategyStack.getCurrent();
+ }
+
+
+ // semantic action overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected boolean isPersisterReferenceAlias(AST alias) {
+ log.trace( "Checking [" + textOrNull( alias ) + "] as persister-ref alias" );
+ return getCurrentPersisterReferenceContext().isContainedAlias( alias.getText() );
+ }
+
+ protected AST resolveAlias(AST alias) {
+ log.trace( "resolving property reference alias [" + textOrNull( alias ) + "]" );
+ return getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() );
+ }
+
+ protected boolean isUnqualifiedPropertyReference(AST property) {
+ log.trace( "Checking [" + textOrNull( property ) + "] as unqualified-prop-ref" );
+ return getCurrentPersisterReferenceContext().isContainedExposedProperty( property.getText() );
+ }
+
+ protected AST buildUnqualifiedPropertyReference(AST propertyNameNode) {
+ String propertyName = propertyNameNode.getText();
+ log.trace( "building unqualified property reference [" + propertyName + "]" );
+ PropertyPathPart root = pathResolutionStrategyStack.getCurrent().resolveRoot( getCurrentPersisterReferenceContext().locatePersisterReferenceExposingProperty( propertyName ) );
+ return root.resolveTerminalPathPart( propertyName );
+ }
+
+ protected AST resolvePropertyPathTerminus(AST source, AST propertyNameNode) {
+ log.trace( "resolving terminal path expression [" + textOrNull( propertyNameNode ) + "]" );
+ return pathResolutionStrategyStack.getCurrent().resolveTerminalPathPart( ( PropertyPathPart ) source, textOrNull( propertyNameNode ) );
+ }
+
+ protected AST resolvePropertyPathIntermediary(AST source, AST propertyNameNode) {
+ log.trace( "resolving intermediate path expression [" + textOrNull( propertyNameNode ) + "]" );
+ return pathResolutionStrategyStack.getCurrent().resolveIntermediatePathPart( ( PropertyPathPart ) source, textOrNull( propertyNameNode ) );
+ }
+
+ protected void validateIndexOperationOperands(AST collectionPropertyRef, AST selector) {
+ // TODO : temporary implementation...
+ log.trace( "Validating index op : collection = [" + textOrNull( collectionPropertyRef ) + "]; selector = [" + textOrNull( selector ) + "]" );
+ super.validateIndexOperationOperands( collectionPropertyRef, selector );
+ }
+
+ protected AST resolveQualifiedRoot(AST alias) {
+ log.debug( "resolving path expression root as alias [" + alias.getText() + "]" );
+ return pathResolutionStrategyStack.getCurrent().resolveRoot( getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() ) );
+ }
+
+ protected AST resolveUnqualifiedRoot(AST propertyName) {
+ log.debug( "resolving path expression root as unqualified property [" + propertyName.getText() + "]" );
+ PropertyPathPart root = pathResolutionStrategyStack.getCurrent().resolveRoot( getCurrentPersisterReferenceContext().locatePersisterReferenceExposingProperty( propertyName.getText() ) );
+ return root.resolveIntermediatePathPart( propertyName.getText() );
+ }
+
+ protected AST resolveIndexedRoot(AST indexNode) {
+ // TODO : need to resolve the INDEX_OP node to the referenced persister and have the path resolution strategy encode that as the root...
+ return indexNode;
+ }
+
+ /**
+ * Semantic action called whenever we start a new statement (i.e top-level statement vs. subquery)
+ *
+ * @param statementNode The statement we are starting to process.
+ */
+ protected void pushStatement(AST statementNode) {
+ log.trace( "pushing new statement context [" + statementNode + "]" );
+ StatementNode statement = ( StatementNode ) statementNode;
+ if ( currentStatement != null ) {
+ currentStatement.pushChild( statement );
+ }
+ currentStatement = statement;
+ pathResolutionStrategyStack.push( currentStatement.buildBasicPathResolutionStrategy( this ) );
+ }
+
+ /**
+ * Semantic action called whenever we complete processing a statement.
+ */
+ protected void popStatement() {
+ log.trace( "popping statement context : " + currentStatement + " -> " + currentStatement.getParentStatement() );
+ currentStatement = currentStatement.getParentStatement();
+ pathResolutionStrategyStack.pop();
+ }
+
+ protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias, AST propertyFetch) {
+ log.debug( "pushing explicit (from clause) property path context" );
+ pathResolutionStrategyStack.push(
+ new FromClausePathResolutionStrategy(
+ this,
+ resolveJoinType( joinTypeNode ),
+ propertyFetch != null,
+ fetch != null,
+ textOrNull( alias )
+ )
+ );
+ }
+
+ protected void popFromClausePropertyPathContext() {
+ log.debug( "popping explicit (from clause) property path context" );
+ pathResolutionStrategyStack.pop();
+ }
+
+ protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+ log.debug( "pushing on-fragment path handler [rhs=" + rhsPersisterReference.getText() + "]" );
+ OnFragmentPathResolutionStrategy strategy = new OnFragmentPathResolutionStrategy( this, ( PersisterReference ) rhsPersisterReference );
+ pathResolutionStrategyStack.push( strategy );
+ }
+
+ protected void popOnFragmentPropertyPathContext() {
+ log.debug( "popping on-fragment path handler" );
+ pathResolutionStrategyStack.pop();
+ }
+
+ protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
+ log.debug( "pushing with-fragment path handler" );
+ // can only be used in conjunction with property reference generated
+ // directly from FromClausePropertyPathHandler...
+ FromClausePathResolutionStrategy.PropertyReferenceAdapter propertyAdapter = ( FromClausePathResolutionStrategy.PropertyReferenceAdapter ) rhsPropertyReference;
+ WithFragmentPathResolutionStrategy strategy = new WithFragmentPathResolutionStrategy( this, propertyAdapter.getOrigination(), propertyAdapter.getRhs() );
+ pathResolutionStrategyStack.push( strategy );
+ }
+
+ protected void popWithFragmentPropertyPathContext() {
+ log.debug( "popping on-fragment path handler" );
+ pathResolutionStrategyStack.pop();
+ }
+
+ /**
+ * Semantic action called to perform generation of an {@link EntityPersisterReference}
+ * representing a "root" persister reference.
+ *
+ * @param entityName The name of the entity.
+ * @param alias An (optional) alias for later qualification-resolution to the generated
+ * persister reference.
+ * @param propertyFetch Was property fetching explicitly specified.
+ * @return The generated reference.
+ */
+ protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
+ return buildEntityPersisterReference( entityName.getText(), textOrNull( alias ), propertyFetch != null );
+ }
+
+ private EntityPersisterReference buildEntityPersisterReference(String entityName, String alias, boolean propertyFetching) {
+ return persisterReferenceBuilder.buildEntityPersisterReference( entityName, alias, propertyFetching );
+ }
+
+ private String textOrNull(AST node) {
+ return node == null ? null : node.getText();
+ }
+
+ protected AST buildAdHocJoinNode(AST rhs, AST joinTypeNode, AST onClause) {
+ log.debug( printer.showAsString( onClause, "ON fragment for ad-hoc-join building" ) );
+ JoinType joinType = resolveJoinType( joinTypeNode );
+ OnFragmentPathResolutionStrategy strategy = ( OnFragmentPathResolutionStrategy ) pathResolutionStrategyStack.getCurrent();
+ PersisterReference lhs = strategy.getDiscoveredLHS();
+ if ( lhs == null ) {
+ throw new QueryException( "Unable to discover left hand side of ad-hoc-join" );
+ }
+ return getPersisterReferenceBuilder().buildJoinNode( lhs, ( PersisterReference ) rhs, joinType, null, false );
+ }
+
+ protected void applyWithFragment(AST withFragment) {
+ log.debug( printer.showAsString( withFragment, "WITH fragment" ) );
+ WithFragmentPathResolutionStrategy strategy = ( WithFragmentPathResolutionStrategy ) pathResolutionStrategyStack.getCurrent();
+ strategy.applyWithFragment( withFragment );
+ }
+
+ private JoinType resolveJoinType(AST joinType) {
+ int joinTypeType = joinType == null ? INNER : joinType.getType();
+ switch ( joinTypeType ) {
+ case INNER:
+ return JoinType.INNER;
+ case LEFT:
+ return JoinType.LEFT;
+ case RIGHT:
+ return JoinType.RIGHT;
+ case FULL:
+ return JoinType.FULL;
+ }
+ // if no match found, throw exception
+ throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" );
+ }
+
+ protected String reconstitutePathString(AST propertyReference) {
+ AST child = propertyReference.getFirstChild();
+ String prefix = "";
+ StringBuffer buffer = new StringBuffer();
+ while ( child != null ) {
+ buffer.append( prefix ).append( child.getText() );
+ prefix = ".";
+ child = child.getNextSibling();
+ }
+ return buffer.toString();
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,69 @@
+package org.hibernate.hql.ast.resolve;
+
+import antlr.collections.AST;
+import antlr.Token;
+
+import org.hibernate.hql.ast.HqlASTFactory;
+import org.hibernate.hql.ast.tree.PhaseContextAwareNode;
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+
+/**
+ * AST factory for the resolver phase.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class HqlResolverASTFactory extends HqlASTFactory implements ResolveTokenTypes {
+
+ private final ResolutionContext context;
+
+ public HqlResolverASTFactory(ResolutionContext context) {
+ this.context = context;
+ }
+
+ public Class getASTNodeType(int tokenType) {
+ switch (tokenType) {
+ case QUERY:
+ return SelectStatementNode.class;
+ case UPDATE:
+ return UpdateStatementNode.class;
+ case DELETE:
+ return DeleteStatementNode.class;
+ case INSERT:
+ return InsertStatementNode.class;
+ case ENTITY_PERSISTER_REF:
+ return EntityPersisterReference.class;
+ case COLLECTION_PERSISTER_REF:
+ return CollectionPersisterReference.class;
+ case JOIN:
+ return JoinNode.class;
+ case PROPERTY_REF:
+ return PropertyReference.class;
+ }
+ return super.getASTNodeType( tokenType );
+ }
+
+ protected AST createUsingCtor(Token token, String string) {
+ AST node = super.createUsingCtor( token, string );
+ prepare( node );
+ return node;
+ }
+
+ protected AST create(Class aClass) {
+ AST node = super.create( aClass );
+ prepare( node );
+ return node;
+ }
+
+ private void prepare(AST node) {
+ if ( node instanceof PhaseContextAwareNode ) {
+ ( ( PhaseContextAwareNode ) node ).injectPhaseContext( context );
+ }
+ if ( node instanceof ResolutionContextAwareNode ) {
+ ( ( ResolutionContextAwareNode ) node ).injectResolutionContext( context );
+ }
+ if ( node instanceof PersisterReferenceContextAwareNode ) {
+ ( ( PersisterReferenceContextAwareNode ) node ).injectPersisterReferenceContext( context.getCurrentPersisterReferenceContext() );
+ }
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,27 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.resolve.path.BasicPathResolutionStrategySupport;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+
+/**
+ * Specialized statement node for representing INSERT statements
+ *
+ * @author Steve Ebersole
+ */
+public class InsertStatementNode extends StatementNode {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PathResolutionStrategy buildBasicPathResolutionStrategy(ResolutionContext resolutionContext) {
+ return new BasicPathResolutionStrategySupport( resolutionContext ) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException(
+ "insert statement cannot contain path expressions resolving to implicit joins"
+ );
+ }
+ };
+ }
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,78 @@
+package org.hibernate.hql.ast.resolve;
+
+import antlr.collections.AST;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.hql.ast.tree.DisplayableNode;
+
+/**
+ * Represents an HQL join. The coneptualization here is strictly that of
+ * the join in terms of the context of the HQL query.
+ * <p/>
+ * The structure here is such that the JoinNode has a mandatory child which is
+ * a {@link org.hibernate.hql.ast.resolve.PersisterReference} representing the
+ * right-hand-side (RHS) of the join. Optionally, it may contain an additional
+ * child which would represent a subtree of join conditions; these join conditions
+ * would be in addition to the defined property-join conditions.
+ * <p/>
+ * The left-hand-side (LHS) of the JoinNode is actually the parent of the
+ * JoinNode. Antlr, however, does not maintain this bi-directionality, so here
+ * we keep a referenc to our parent (the LHS) as an inst var so that we can
+ * refer to it as need be later.
+ *
+ * @author Steve Ebersole
+ */
+public class JoinNode extends Node implements DisplayableNode {
+
+ private JoinType joinType;
+ private String propertyName;
+ private PersisterReference lhs;
+
+ public JoinNode() {
+ super.setText( "join" );
+ }
+
+ public void initialize(JoinType joinType, String propertyName, PersisterReference lhs) {
+ this.joinType = joinType;
+ this.propertyName = propertyName;
+ this.lhs = lhs;
+ }
+
+ public JoinType getJoinType() {
+ return joinType;
+ }
+
+ public void setJoinType(JoinType joinType) {
+ this.joinType = joinType;
+ }
+
+ public PersisterReference getLhs() {
+ return lhs;
+ }
+
+ public PersisterReference getRhs() {
+ return ( PersisterReference ) getFirstChild();
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public AST getExplicitJoinConditions() {
+ return getFirstChild().getNextSibling();
+ }
+
+ public void applyExplicitJoinConditions(AST conditions) {
+ getFirstChild().setNextSibling( conditions );
+ }
+
+ public String getDisplayText() {
+ return "{" + "type=" + joinType +
+ ", lhs=" + ( lhs == null ? "???" : lhs.getAlias() ) +
+ ", property=" + ( propertyName == null ? "n/a" : propertyName ) + "}";
+ }
+
+ public String toString() {
+ return "JoinNode " + getDisplayText();
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,62 @@
+package org.hibernate.hql.ast.resolve;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * Represents a canonical join type.
+ * <p/>
+ * Note that currently HQL really only supports inner and left outer joins
+ * (though cross joins can also be achieved). This is because joins in HQL
+ * are always defined in relation to a mapped association. However, when we
+ * start allowing users to specify ad-hoc joins this may need to change to
+ * allow the full spectrum of join types. Thus the others are provided here
+ * currently just for completeness and for future expansion.
+ *
+ * @author Steve Ebersole
+ */
+public class JoinType implements Serializable {
+ /**
+ * Represents an inner join.
+ */
+ public static final JoinType INNER = new JoinType( "inner" );
+ /**
+ * Represents a left outer join.
+ */
+ public static final JoinType LEFT = new JoinType( "left outer" );
+ /**
+ * Represents a right outer join.
+ */
+ public static final JoinType RIGHT = new JoinType( "right outer" );
+ /**
+ * Represents a cross join (aka a cartesian product).
+ */
+ public static final JoinType CROSS = new JoinType( "cross" );
+ /**
+ * Represents a full join.
+ */
+ public static final JoinType FULL = new JoinType( "full" );
+
+ private static final HashMap INSTANCES = new HashMap();
+ static {
+ INSTANCES.put( INNER.name, INNER );
+ INSTANCES.put( LEFT.name, LEFT );
+ INSTANCES.put( RIGHT.name, RIGHT );
+ INSTANCES.put( CROSS.name, CROSS );
+ INSTANCES.put( FULL.name, FULL );
+ }
+
+ private final String name;
+
+ private JoinType(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ private Object readResolve() {
+ return INSTANCES.get( name );
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,96 @@
+package org.hibernate.hql.ast.resolve;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.AssertionFailure;
+
+/**
+ * Represents a reference to a persister (either entity or collection) within
+ * an HQL statement.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class PersisterReference extends Node implements Aliasable, ResolutionContextAwareNode {
+
+ private ResolutionContext resolutionContext;
+ private final Map reusableJoinsByProperty = new HashMap();
+
+ /**
+ * Retrieve the logical name of this persister reference. Used in logging
+ * operations.
+ *
+ * @return The logical persister reference name.
+ */
+ public abstract String getName();
+
+ /**
+ * The type represented by this persister reference.
+ *
+ * @return The type.
+ */
+ public abstract AssociationType getPersisterType();
+
+ /**
+ * Does the underlying persister contain such a named property?
+ *
+ * @param propertyName The property name to check.
+ * @return True if the persister contains a property with that name; false
+ * otherwise.
+ */
+ public abstract boolean containsProperty(String propertyName);
+
+ /**
+ * Retrieve the type of the given named property rooted at the underlying
+ * persister; will be <tt>null</tt> if {@link #containsProperty} is false.
+ *
+ * @param propertyName The name of the property.
+ * @return The property's type, or null.
+ */
+ public abstract Type getPropertyType(String propertyName);
+
+ /**
+ * Get the loggable text of this persister reference.
+ *
+ * @return The loggable text.
+ */
+ public String getText() {
+ return getName() + " (" + getAlias() + ")";
+ }
+
+ /**
+ * Locate a previously {@link #registerReusableJoinByProperty registered}
+ * implicit join by the property name/path.
+ *
+ * @param propertyName The name/path of the property.
+ * @return The previously registered persister reference; or null.
+ */
+ public JoinNode locateReusableJoinByProperty(String propertyName) {
+ return ( JoinNode ) reusableJoinsByProperty.get( propertyName );
+ }
+
+ /**
+ * Register a join by property as being reusable.
+ *
+ * @param propertyName The name of the property which the join represents.
+ * @param join The join.
+ */
+ public void registerReusableJoinByProperty(String propertyName, JoinNode join) {
+ reusableJoinsByProperty.put( propertyName, join );
+ }
+
+ protected final SessionFactoryImplementor getSessionFactory() {
+ if ( resolutionContext == null ) {
+ throw new AssertionFailure( "resolution context was null on attempt to retrieve session factory reference" );
+ }
+ return resolutionContext.getSessionFactory();
+ }
+
+ public void injectResolutionContext(ResolutionContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,117 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.MappingException;
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * A helper for building {@link PersisterReference} AST structures.
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceBuilder {
+
+ public static final Log log = LogFactory.getLog( PersisterReferenceBuilder.class );
+
+ private final AliasBuilder aliasBuilder = new AliasBuilder();
+ private final ResolutionContext resolutionContext;
+
+
+ public PersisterReferenceBuilder(ResolutionContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ // exposed services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Builds an entity persister reference
+ *
+ * @param entityName The entity name to which to build a PersisterReference.
+ * @param alias The alias (or null) to apply to the built PersisterReference.
+ * @param propertyFetching Whether lazy property fetching should be enabled.
+ * @return The built PersisterReference
+ */
+ public EntityPersisterReference buildEntityPersisterReference(
+ String entityName,
+ String alias,
+ boolean propertyFetching) {
+ EntityPersister persister = lookupEntityPersister( entityName );
+ alias = determineAlias( alias );
+ EntityPersisterReference persisterReference = ( EntityPersisterReference )
+ resolutionContext.getASTFactory().create( ResolveTokenTypes.ENTITY_PERSISTER_REF, persister.getEntityName() );
+ persisterReference.initialize( persister.getEntityName(), alias, propertyFetching );
+ resolutionContext.getCurrentPersisterReferenceContext().registerPersisterReference( persisterReference );
+ return persisterReference;
+ }
+
+ public CollectionPersisterReference buildCollectionPersisterReference(String collectionRole, String alias, boolean propertyFetching) {
+ alias = determineAlias( alias );
+ CollectionPersisterReference persisterReference = ( CollectionPersisterReference )
+ resolutionContext.getASTFactory().create( ResolveTokenTypes.COLLECTION_PERSISTER_REF, collectionRole );
+ persisterReference.initialize( collectionRole, alias, propertyFetching );
+ resolutionContext.getCurrentPersisterReferenceContext().registerPersisterReference( persisterReference );
+ return persisterReference;
+ }
+
+ public JoinNode buildJoinNode(
+ PersisterReference lhs,
+ PersisterReference rhs,
+ JoinType joinType,
+ String propertyName,
+ boolean fetching) {
+ JoinNode join = ( JoinNode ) resolutionContext.getASTFactory().create( ResolveTokenTypes.JOIN, "join" );
+ join.initialize( joinType, propertyName, lhs );
+ lhs.addChild( join );
+ join.setFirstChild( rhs );
+ if ( fetching ) {
+ resolutionContext.getCurrentPersisterReferenceContext().registerFetch( rhs );
+ }
+ if ( join.getPropertyName() != null && AliasBuilder.isNonExplicitAlias( join.getRhs().getAlias() ) ) {
+ join.getLhs().registerReusableJoinByProperty( join.getPropertyName(), join );
+ }
+ return join;
+ }
+
+ private EntityPersister lookupEntityPersister(String name) {
+ // First, try to get the persister using the class name directly.
+ try {
+ return resolutionContext.getSessionFactory().getEntityPersister( name );
+ }
+ catch ( MappingException ignore ) {
+ // unable to locate it using this name
+ }
+
+ // If that didn't work, try using the 'import' name.
+ String importedClassName = resolutionContext.getSessionFactory().getImportedClassName( name );
+ if ( importedClassName == null ) {
+ return null;
+ }
+ return resolutionContext.getSessionFactory().getEntityPersister( importedClassName );
+ }
+
+ private String determineAlias(String alias) {
+ if ( alias == null ) {
+ alias = aliasBuilder.buildUniqueImplicitAlias();
+ }
+ return alias;
+ }
+
+ public static boolean isNonExplicitAlias(String alias) {
+ return AliasBuilder.isNonExplicitAlias( alias );
+ }
+
+ private static class AliasBuilder {
+ private int unaliasedCount = 0;
+
+ private synchronized String buildUniqueImplicitAlias() {
+ return "<gen:" + unaliasedCount++ + ">";
+ }
+
+ private static boolean isNonExplicitAlias(String alias) {
+ return alias == null || ( alias.startsWith( "<gen:" ) && alias.endsWith( ">" ) );
+ }
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,108 @@
+package org.hibernate.hql.ast.resolve;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.QueryException;
+import org.hibernate.hql.ast.tree.Node;
+
+/**
+ * Defines the contract for implementors of a "context" or a "scope" for
+ * references to persisters. Generally speaking, this maps to the notion
+ * of a FROM clause in a SELECT statement. However, DML operations also
+ * have a notion of a persister reference. This, then, acts as the
+ * abstraction of these grouped references to persisters.
+ *
+ * @see PersisterReference
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceContext extends Node {
+ private static final Log log = LogFactory.getLog( PersisterReferenceContext.class );
+
+ private List persisterReferences = new ArrayList();
+ private Map aliasXref = new HashMap();
+ private List fetches = new ArrayList();
+
+ protected PersisterReferenceContext() {
+ }
+
+ public boolean isContainedAlias(String alias) {
+ return aliasXref.containsKey( alias );
+ }
+
+ public boolean isContainedExposedProperty(String propertyName) {
+ // a matching alias always takes precedence...
+ return ( ! isContainedAlias( propertyName ) )
+ && locatePersisterReferenceExposingProperty( propertyName ) != null;
+ }
+
+ public PersisterReference locatePersisterReference(String aliasOrPropertyName) {
+ PersisterReference pRef = locatePersisterReferenceByAlias( aliasOrPropertyName );
+ if ( pRef == null ) {
+ pRef = locatePersisterReferenceExposingProperty( aliasOrPropertyName );
+ }
+ return pRef;
+ }
+
+ /**
+ * Locate a {@link PersisterReference} by alias.
+ *
+ * @param alias The alias by which to locate the persister reference.
+ * @return The persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceByAlias(String alias) {
+ log.trace( "attempting to resolve [" + alias + "] as persister reference alias" );
+ return ( PersisterReference ) aliasXref.get( alias );
+ }
+
+ /**
+ * Locate an persister reference in this context which exposes the
+ * specified property.
+ *
+ * @param propertyName The name of the property.
+ * @return The persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceExposingProperty(String propertyName) {
+ log.trace( "attempting to resolve [" + propertyName + "] as unqualified property" );
+ EntityPersisterReference pRef = null;
+ Iterator itr = persisterReferences.iterator();
+ while( itr.hasNext() ) {
+ final EntityPersisterReference test = ( EntityPersisterReference ) itr.next();
+ if ( test.containsProperty( propertyName ) ) {
+ if ( pRef != null ) {
+ throw new QueryException( "multiple persisters contained property [" + propertyName + "]" );
+ }
+ pRef = test;
+ }
+ }
+ return pRef;
+ }
+
+ /**
+ * Registers a persister reference in this context. It is
+ * assumed the passed persisterReference represents a "root"
+ * persister reference within the query.
+ *
+ * @param persisterReference The persister reference to register.
+ */
+ public void registerPersisterReference(PersisterReference persisterReference) {
+ if ( persisterReference.getAlias() == null ) {
+ throw new IllegalArgumentException( "unexpected null persister-reference alias" );
+ }
+ persisterReferences.add( persisterReference );
+ aliasXref.put( persisterReference.getAlias(), persisterReference );
+ // TODO : should we inject the persisterReference into the AST here?
+ }
+
+ public void registerFetch(PersisterReference persisterReference) {
+ fetches.add( persisterReference );
+ }
+
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,10 +1,16 @@
package org.hibernate.hql.ast.resolve;
/**
- * todo: describe PersisterReferenceContextAwareNode
+ * Injection service contract for nodes which require access to the exact
+ * {@link PersisterReferenceContext} in effect at the time they were created.
*
* @author Steve Ebersole
*/
public interface PersisterReferenceContextAwareNode {
- public void setPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext);
+ /**
+ * Injects a reference to the current {@link PersisterReferenceContext}.
+ *
+ * @param persisterReferenceContext The current {@link PersisterReferenceContext}.
+ */
+ public void injectPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext);
}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,66 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.hql.ast.tree.DisplayableNode;
+import org.hibernate.type.Type;
+import org.hibernate.HibernateException;
+
+/**
+ * Represents a reference to a particular property.
+ * <p/>
+ * The sub-tree structure of this node is such that its first child is an ALIAS
+ * node representing an alias pointing to the specific persister reference from
+ * which the property reference originates. The other child is the property name,
+ * as an IDENT
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyReference extends Node implements PersisterReferenceContextAwareNode, DisplayableNode {
+
+ private PersisterReferenceContext persisterContext;
+
+ // caches
+ private String alias;
+ private String propertyName;
+ private Type propertyType;
+ private PersisterReference origin;
+
+ public String getOriginationAlias() {
+ if ( alias == null ) {
+ alias = getFirstChild().getText();
+ }
+ return alias;
+ }
+
+ public String getPropertyName() {
+ if ( propertyName == null ) {
+ propertyName = getFirstChild().getNextSibling().getText();
+ }
+ return propertyName;
+ }
+
+ public PersisterReference getOrigination() {
+ if ( origin == null ) {
+ if ( persisterContext == null ) {
+ throw new HibernateException( "PersisterReferenceContext not yet injected" );
+ }
+ origin = persisterContext.locatePersisterReferenceByAlias( getOriginationAlias() );
+ }
+ return origin;
+ }
+
+ public Type getPropertyType() {
+ if ( propertyType == null ) {
+ propertyType = getOrigination().getPropertyType( getPropertyName() );
+ }
+ return propertyType;
+ }
+
+ public void injectPersisterReferenceContext(PersisterReferenceContext persisterContext) {
+ this.persisterContext = persisterContext;
+ }
+
+ public String getDisplayText() {
+ return " {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
+ }
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,43 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.type.Type;
-
-/**
- * Contract for things which can be the source of a property reference in an
- * HQL query. This contract is used to resolve dot-structures.
- *
- * @author Steve Ebersole
- */
-public interface PropertyReferenceSource {
- /**
- * Retrieves the type that this source represents.
- *
- * @return The source's type.
- */
- public Type getRootType();
-
- /**
- * Any path information "backing" this source. Used for componnent
- * resolution, where this source represents a component value.
- *
- * @return The component property path
- */
- public String getPropertyPath();
-
- /**
- * Again, used in component resolutions. The persister from which the
- * {@link #getPropertyPath} is relative.
- *
- * @return
- */
- public PersisterReference getPropertyPathRoot();
-
- public Type getPropertyType(String propertyName);
-
- public void prepareLHS(ResolutionContext resolutionContext, String rhsPropertyName);
-
- public JoinNode locateImplicitJoinByProperty(String propertyName);
-
- public void registerImplicitJoinByProperty(String propertyName, JoinNode join);
-
-}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,35 +1,15 @@
package org.hibernate.hql.ast.resolve;
-import antlr.ASTFactory;
-
-import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+import org.hibernate.hql.ast.PhaseContext;
/**
- * Defines the basic contract for a resolution context.
- * <p/>
- * Essentially used to define a series of services that components
- * operating within said context can rely upon.
+ * Defines the basic contract for service context for the resolution phase.
*
* @author Steve Ebersole
*/
-public interface ResolutionContext {
+public interface ResolutionContext extends PhaseContext {
/**
- * Retrieve a reference to the factory associated with this context for
- * creating AST/Node instances.
- *
- * @return The ASTFactory.
- */
- public ASTFactory getASTFactory();
-
- /**
- * Retrieve a reference to the session factory associated with this context.
- *
- * @return The session factory.
- */
- public SessionFactoryImplementor getSessionFactory();
-
- /**
* Retrieve a reference to the {@link PersisterReference} builder associated
* with this context.
*
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -6,5 +6,5 @@
* @author Steve Ebersole
*/
public interface ResolutionContextAwareNode {
- public void setResolutionContext(ResolutionContext resolutionContext);
+ public void injectResolutionContext(ResolutionContext resolutionContext);
}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,65 @@
+package org.hibernate.hql.ast.resolve;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.QueryException;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+
+/**
+ * Base node class for HQL statements.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public abstract class StatementNode extends Node {
+
+ private StatementNode parentStatement;
+ private List childStatements;
+ private PersisterReferenceContext persisterReferenceContext = new HierarchicalPersisterReferenceContext();
+
+ public StatementNode getParentStatement() {
+ return parentStatement;
+ }
+
+ public boolean isTopLevelStatement() {
+ return parentStatement == null;
+ }
+
+ public StatementNode getTopLevelStatement() {
+ StatementNode topLevel = this;
+ while ( topLevel.getParentStatement() != null ) {
+ topLevel = topLevel.getParentStatement();
+ }
+ return topLevel;
+ }
+
+ public Iterator iterateChildStatements() {
+ return childStatements == null ? EmptyIterator.INSTANCE : childStatements.iterator();
+ }
+
+ public void pushChild(StatementNode childStatement) {
+ childStatement.setParent( this );
+ if ( childStatements == null ) {
+ childStatements = new ArrayList();
+ }
+ childStatements.add( childStatement );
+ }
+
+ private void setParent(StatementNode parentStatement) {
+ if ( this.parentStatement != null ) {
+ throw new QueryException( "statement already had an associated parent" );
+ }
+ this.parentStatement = parentStatement;
+ this.persisterReferenceContext = new HierarchicalPersisterReferenceContext( parentStatement.getPersisterReferenceContext() );
+ }
+
+ public PersisterReferenceContext getPersisterReferenceContext() {
+ return persisterReferenceContext;
+ }
+
+ public abstract PathResolutionStrategy buildBasicPathResolutionStrategy(ResolutionContext resolutionContext);
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,25 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+import org.hibernate.hql.ast.resolve.path.BasicPathResolutionStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing UPDATE statements
+ *
+ * @author Steve Ebersole
+ */
+public class UpdateStatementNode extends StatementNode {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PathResolutionStrategy buildBasicPathResolutionStrategy(ResolutionContext resolutionContext) {
+ return new BasicPathResolutionStrategySupport(resolutionContext) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException( "update statement cannot contain path expressions resolving to implicit joins" );
+ }
+ };
+ }
+}
+
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -60,7 +60,7 @@
}
protected final void preparePropertyReference(PropertyReference propertyReferenceNode, PersisterReference persisterReference, String propertyPath) {
- propertyReferenceNode.setPersisterReferenceContext( resolutionContext.getCurrentPersisterReferenceContext() );
+ propertyReferenceNode.injectPersisterReferenceContext( resolutionContext.getCurrentPersisterReferenceContext() );
propertyReferenceNode.setText( persisterReference.getAlias() + "." + propertyPath );
propertyReferenceNode.setType( ResolveTokenTypes.PROPERTY_REF );
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -191,7 +191,7 @@
private JoinNode resolveLhsJoin() {
EntityType type = ( EntityType ) lhs.getPropertyType( propertyName );
validateJoinCreation( lhs, propertyName );
- JoinNode join = lhs.locateImplicitJoinByProperty( propertyName );
+ JoinNode join = lhs.locateReusableJoinByProperty( propertyName );
if ( join == null ) {
String entityName = type.getAssociatedEntityName( resolutionContext.getSessionFactory() );
PersisterReference joinRhs = resolutionContext.getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, null, false );
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/ASTFactoryAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/ASTFactoryAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/ASTFactoryAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,12 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import antlr.ASTFactory;
-
-/**
- * todo: describe ASTFactoryAwareNode
- *
- * @author Steve Ebersole
- */
-public interface ASTFactoryAwareNode {
- public void setASTFactory(ASTFactory astFactory);
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReferenceContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReferenceContextAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PersisterReferenceContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,12 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.resolve.PersisterReferenceContext;
-
-/**
- * todo: describe PersisterReferenceContextAwareNode
- *
- * @author Steve Ebersole
- */
-public interface PersisterReferenceContextAwareNode {
- public void setPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext);
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -0,0 +1,18 @@
+package org.hibernate.hql.ast.tree;
+
+import org.hibernate.hql.ast.PhaseContext;
+
+/**
+ * Injection service contract for nodes which require access to the current
+ * phase context during their lifetime.
+ *
+ * @author Steve Ebersole
+ */
+public interface PhaseContextAwareNode {
+ /**
+ * Inject a reference to the current {@link PhaseContext}.
+ *
+ * @param context The current {@link PhaseContext}
+ */
+ public void injectPhaseContext(PhaseContext context);
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java 2006-12-19 18:09:33 UTC (rev 11002)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java 2006-12-19 19:08:27 UTC (rev 11003)
@@ -1,13 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Marking interface for nodes which want access to the
- * {@link org.hibernate.engine.SessionFactoryImplementor session factory}.
- *
- * @author Steve Ebersole
- */
-public interface SessionFactoryAwareNode {
- public void setSessionFactory(SessionFactoryImplementor sessionFactory);
-}
18 years
Hibernate SVN: r11002 - in branches/Branch_3_2/HibernateExt/metadata/src: java/org/hibernate/validator java/org/hibernate/validator/resources test/org/hibernate/validator/test/validator
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2006-12-19 13:09:33 -0500 (Tue, 19 Dec 2006)
New Revision: 11002
Added:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/Digits.java
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/DigitsValidator.java
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/DigitsTest.java
Modified:
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties
branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties
branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/Car.java
Log:
ANN-507 @Digits
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/Digits.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/Digits.java 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/Digits.java 2006-12-19 18:09:33 UTC (rev 11002)
@@ -0,0 +1,25 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Check that a given number has <code>integerDigits</code> integer digits
+ * and <code>fractionalDigits</code> fractional digits
+ * The constraints are defined at the database level too
+ *
+ * @author Norman Richards
+ */
+(a)ValidatorClass(DigitsValidator.class)
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+@Retention( RetentionPolicy.RUNTIME)
+@Documented
+public @interface Digits {
+ int integerDigits();
+ int fractionalDigits() default 0;
+ String message() default "{validator.digits}";
+}
\ No newline at end of file
Added: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/DigitsValidator.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/DigitsValidator.java 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/DigitsValidator.java 2006-12-19 18:09:33 UTC (rev 11002)
@@ -0,0 +1,84 @@
+//$Id: $
+package org.hibernate.validator;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Column;
+
+/**
+ * Validate a Digit to check if it matches the according pattern
+ *
+ * @authod Norman Richards
+ * @author Emmanuel Bernard
+ */
+public class DigitsValidator implements Validator<Digits>, PropertyConstraint {
+ int integerDigits;
+ int fractionalDigits;
+
+ public void initialize(Digits configuration) {
+ integerDigits = configuration.integerDigits();
+ fractionalDigits = configuration.fractionalDigits();
+ }
+
+ public boolean isValid(Object value) {
+ if ( value == null ) {
+ return true;
+ }
+
+ String stringValue = null;
+
+ if ( value instanceof String ) {
+ try {
+ stringValue = stringValue( new BigDecimal( (String) value ) );
+ }
+ catch (NumberFormatException nfe) {
+ return false;
+ }
+ }
+ else if ( value instanceof BigDecimal ) {
+ stringValue = stringValue( (BigDecimal) value );
+ }
+ else if ( value instanceof BigInteger ) {
+ stringValue = stringValue( (BigInteger) value );
+ }
+ else if ( value instanceof Number ) {
+ //yukky
+ stringValue = stringValue( new BigDecimal( ( (Number) value ).toString() ) );
+ }
+ else {
+ return false;
+ }
+
+ int pos = stringValue.indexOf( "." );
+
+ int left = ( pos == -1 ) ?
+ stringValue.length() :
+ pos;
+ int right = ( pos == -1 ) ?
+ 0 :
+ stringValue.length() - pos - 1;
+
+ if ( left == 1 && stringValue.charAt( 0 ) == '0' ) {
+ left--;
+ }
+
+ return !( left > integerDigits || right > fractionalDigits );
+
+ }
+
+ private String stringValue(BigDecimal number) {
+ return number.abs().stripTrailingZeros().toPlainString();
+ }
+
+ private String stringValue(BigInteger number) {
+ return number.abs().toString();
+ }
+
+ public void apply(Property property) {
+ Column col = (Column) property.getColumnIterator().next();
+ col.setPrecision( integerDigits + fractionalDigits );
+ col.setScale( fractionalDigits );
+ }
+}
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=must be between {min} and {max}
validator.size=size must be between {min} and {max}
validator.email=not a well-formed email address
-validator.notEmpty=may not be null or empty
\ No newline at end of file
+validator.notEmpty=may not be null or empty
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_da.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=skal v�re mellem {min} og {max}
validator.size=antallet skal v�re mellem {min} og {max}
validator.email=not a well-formed email address
-validator.notEmpty=m� ikke v�re null eller tom
\ No newline at end of file
+validator.notEmpty=m� ikke v�re null eller tom
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_de.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=muss zwischen {min} und {max} sein
validator.size=muss zwischen {min} und {max} gross sein
validator.email=not a well-formed email address
-validator.notEmpty=kann nicht null oder leer sein
\ No newline at end of file
+validator.notEmpty=kann nicht null oder leer sein
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_es.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=debe ser entre {min} y {max}
validator.size=el tama�o debe ser entre {min} y {max}
validator.email=no es una direcci�n de correo electr�nico bien formada
-validator.notEmpty=no debe ser nulo o vac�o
\ No newline at end of file
+validator.notEmpty=no debe ser nulo o vac�o
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_fr.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=doit �tre entre {min} et {max}
validator.size=le nombre d'�l�ments doit �tre entre {min} et {max}
validator.email=Address email mal form�e
-validator.notEmpty=ne peut pas �tre nul ou vide
\ No newline at end of file
+validator.notEmpty=ne peut pas �tre nul ou vide
+validator.digits=valeur num�rique hors limite (<{integerDigits} chiffres>.<{fractionalDigits} chiffres> attendus)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_it.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -11,3 +11,4 @@
validator.size=le dimensioni devono essere tra {min} e {max}
validator.email=not a well-formed email address
validator.notEmpty=non pu� essere nullo o vuoto
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_nl.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=moet tussen {min} en {max} zijn
validator.size=moet tussen {min} en {max} groot zijn
validator.email=moet een geldig e-mail adres zijn
-validator.notEmpty=mag niet null of leeg zijn
\ No newline at end of file
+validator.notEmpty=mag niet null of leeg zijn
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_pt_BR.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=deve estar entre {min} e {max}
validator.size=tamanho deve estar entre {min} e {max}
validator.email=n�o � um email v�lido
-validator.notEmpty=n�o pode ser nulo ou vazio
\ No newline at end of file
+validator.notEmpty=n�o pode ser nulo ou vazio
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_sv.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -10,4 +10,5 @@
validator.range=m�ste vara mellan {min} och {max}
validator.size=storlek m�ste vara mellan {min} och {max}
validator.email=ogiltig e-mail adress
-validator.notEmpty=f�r inte vara tomt
\ No newline at end of file
+validator.notEmpty=f�r inte vara tomt
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_CN.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -9,4 +9,6 @@
validator.pattern=\u5fc5\u987b\u7b26\u5408 "{regex}"
validator.range=\u5fc5\u987b\u4ecb\u4e8e {min} \u4e0e {max} \u4e4b\u95f4
validator.size=\u5927\u5c0f\u5fc5\u987b\u4ecb\u4e8e {min} \u4e0e {max} \u4e4b\u95f4
-validator.email=not a well-formed email address
\ No newline at end of file
+validator.email=not a well-formed email address
+validator.notEmpty=may not be null or empty
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/java/org/hibernate/validator/resources/DefaultValidatorMessages_zh_TW.properties 2006-12-19 18:09:33 UTC (rev 11002)
@@ -9,4 +9,6 @@
validator.pattern=\u5fc5\u9808\u7b26\u5408"{regex}"
validator.range=\u5fc5\u9808\u4ecb\u65bc{min} \u8207 {max} \u4e4b\u9593
validator.size=\u5927\u5c0f\u5fc5\u9808\u4ecb\u65bc{min} \u8207 {max} \u4e4b\u9593
-validator.email=not a well-formed email address
\ No newline at end of file
+validator.email=not a well-formed email address
+validator.digits=numeric value out of bounds (<{integerDigits} digits>.<{fractionalDigits} digits> expected)
+validator.notEmpty=may not be null or empty
\ No newline at end of file
Modified: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/Car.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/Car.java 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/Car.java 2006-12-19 18:09:33 UTC (rev 11002)
@@ -1,14 +1,28 @@
//$Id: $
package org.hibernate.validator.test.validator;
+import java.math.BigDecimal;
+
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Entity;
+
import org.hibernate.validator.NotEmpty;
+import org.hibernate.validator.Digits;
/**
* @author Emmanuel Bernard
*/
+@Entity
public class Car {
+ @Id @GeneratedValue
+ public Long id;
@NotEmpty
public String name;
@NotEmpty
public String[] insurances;
+ @Digits(integerDigits = 1, fractionalDigits = 2)
+ public BigDecimal length;
+ @Digits(integerDigits = 2, fractionalDigits = 1)
+ public Double gallons;
}
Added: branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/DigitsTest.java
===================================================================
--- branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/DigitsTest.java 2006-12-19 17:38:43 UTC (rev 11001)
+++ branches/Branch_3_2/HibernateExt/metadata/src/test/org/hibernate/validator/test/validator/DigitsTest.java 2006-12-19 18:09:33 UTC (rev 11002)
@@ -0,0 +1,60 @@
+//$Id: $
+package org.hibernate.validator.test.validator;
+
+import java.math.BigDecimal;
+
+import org.hibernate.validator.ClassValidator;
+import org.hibernate.validator.InvalidValue;
+import org.hibernate.validator.Environment;
+import org.hibernate.validator.event.ValidatePreInsertEventListener;
+import org.hibernate.validator.event.ValidatePreUpdateEventListener;
+import org.hibernate.validator.test.Address;
+import org.hibernate.validator.test.PrefixMessageInterpolator;
+import org.hibernate.Session;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Column;
+import org.hibernate.test.annotations.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DigitsTest extends TestCase {
+
+ public void testDigits() throws Exception {
+ Car car = new Car();
+ car.name = "350Z";
+ car.insurances = new String[] { "random" };
+ car.length = new BigDecimal(10.2);
+ car.gallons = 100.3;
+ ClassValidator<Car> classValidator = new ClassValidator<Car>( Car.class );
+ InvalidValue[] invalidValues = classValidator.getInvalidValues( car );
+ assertEquals( 2, invalidValues.length );
+ car.length = new BigDecimal(1.223); //more than 2
+ car.gallons = 10.300; //1 digit really so not invalid
+ invalidValues = classValidator.getInvalidValues( car );
+ assertEquals( 1, invalidValues.length );
+ }
+
+ public void testApply() throws Exception {
+ PersistentClass classMapping = getCfg().getClassMapping( Car.class.getName() );
+ Column stateColumn = (Column) classMapping.getProperty( "gallons" ).getColumnIterator().next();
+ assertEquals( stateColumn.getPrecision(), 3 );
+ assertEquals( stateColumn.getScale(), 1 );
+ }
+
+ protected void configure(Configuration cfg) {
+ cfg.getEventListeners()
+ .setPreInsertEventListeners( new PreInsertEventListener[]{new ValidatePreInsertEventListener()} );
+ cfg.getEventListeners()
+ .setPreUpdateEventListeners( new PreUpdateEventListener[]{new ValidatePreUpdateEventListener()} );
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ Car.class
+ };
+ }
+}
18 years
Hibernate SVN: r11001 - in branches/HQL_ANTLR_2/Hibernate3: g2 src/org/hibernate/hql/ast/resolve src/org/hibernate/hql/ast/resolve/path src/org/hibernate/hql/ast/util test/org/hibernate/test/hql test/org/hibernate/test/hql/redesign
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2006-12-19 12:38:43 -0500 (Tue, 19 Dec 2006)
New Revision: 11001
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HierarchicalPersisterReferenceContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/OnFragmentPathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategyStack.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPart.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPartAdapter.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/WithFragmentPathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.hbm.xml
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.java
Removed:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyPathHandler.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/WithFragmentPropertyPathHandler.java
Modified:
branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/util/ASTPrinter.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HQLTest.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
Log:
switched to a more in-line resolution of path expressions using org.hibernate.hql.ast.resolve.path.PathResolutionStrategy
Modified: branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 17:38:43 UTC (rev 11001)
@@ -7,25 +7,25 @@
}
/**
- * An Antlr tree parser for "resolving" or "normalizing" an HQL
- * syntax AST. This parser provides the vast majority of the
- * semantic analysis of the HQL AST.
+ * An Antlr tree parser for "resolving" or "normalizing" an HQL syntax AST. This
+ * parser provides the vast majority of the semantic analysis of the HQL AST.
* <p/>
- * Both "resolving" and "normalizing" here seek a single goal of
- * building a dis-ambiguated, generic query AST.
+ * Both "resolving" and "normalizing" here seek a single goal of building a
+ * dis-ambiguated, generic query AST.
* <p/>
- * The act of resolving is essentially the process of simplifying
- * complex node structures into atomic components based on contextual
- * information (aka, the current parser state). The main thrust
- * of this process is breaking down dot-structures (a series of
- * DOT INDET pairs) into <ul>
+ * The act of resolving is essentially the process of simplifying complex node
+ * structures into atomic components based on contextual information (aka, the
+ * current parser state). The main thrust of this process is breaking down
+ * dot-structures (a series of DOT INDET pairs) into <ul>
* <li>a series of "implicit" join structures injected into the from clause tree</li>
* <li>a simple structure representing the "meaning" of the "leaf" of said dot-structure</li>
* </ul>
* <p/>
* The act of normalizing essentially refers to the process of dis-ambiguating
* node structures based on their context and creating a unified AST
- * representation for different ways to express the same "idea".
+ * representation for different ways to express the same "idea". An example of this
+ * is normalizing implicit join dot-structures into a structure akin to its explicit
+ * join corollary.
*
* @author Joshua Davis
* @author Steve Ebersole
@@ -45,12 +45,57 @@
ENTITY_PERSISTER_REF;
COLLECTION_PERSISTER_REF;
BOGUS;
+
+ NAMED_PARAM;
+ ORDINAL_PARAM;
}
// -- Declarations --
{
+ private int ordinalParamCount = 0;
+
+ protected boolean isPersisterReferenceAlias(AST alias) {
+ return false;
+ }
+
+ protected AST resolveAlias(AST alias) {
+ return alias;
+ }
+
+ protected boolean isUnqualifiedPropertyReference(AST property) {
+ return false;
+ }
+
+ protected AST buildUnqualifiedPropertyReference(AST propertyNameNode) {
+ return propertyNameNode;
+ }
+
+ protected AST resolvePropertyPathTerminus(AST source, AST propertyNameNode) {
+ return propertyNameNode;
+ }
+
+ protected AST resolvePropertyPathIntermediary(AST source, AST propertyNameNode) {
+ return propertyNameNode;
+ }
+
+ protected void validateIndexOperationOperands(AST collectionPropertyRef, AST selector) {
+ }
+
+ protected AST resolveQualifiedRoot(AST alias) {
+ return null;
+ }
+
+ protected AST resolveUnqualifiedRoot(AST alias) {
+ return null;
+ }
+
+ protected AST resolveIndexedRoot(AST alias) {
+ return null;
+ }
+
+
// Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected void pushStatement(AST statementNode) {
@@ -84,23 +129,33 @@
// persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
- return null;
+ return entityName;
}
protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST withFragment) {
- return null;
+ return persisterReference;
}
protected void applyWithFragment(AST withFragment) {
}
- // property reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- protected void handleIntermediatePathPart(AST name) {
+ // parameter handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private AST generateNamedParameter(AST delim, AST name) throws SemanticException {
+ // use the source delim node to properly transfer line/column number information :(
+ AST param = #( delim );
+ param.setType( NAMED_PARAM );
+ param.setText( name.getText() );
+ return param;
}
- protected AST handleTerminalPathPart(AST name) {
- return null;
+ private AST generateOrdinalParameter(AST source) throws SemanticException {
+ // use the source node to properly transfer line/column number information :(
+ AST param = #( source );
+ param.setType( ORDINAL_PARAM );
+ param.setText( Integer.toString( ordinalParamCount++ ) );
+ return param;
}
}
@@ -174,47 +229,129 @@
popOnFragmentPropertyPathContext();
}
}
- | (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)? { pushFromClausePropertyPathContext( jt, #f, #a, #pf ); } prop:propertyPath (with:withFragment[#prop])? {
+ | (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)? { pushFromClausePropertyPathContext( jt, #f, #a, #pf ); } prop:propertyRef (with:withFragment[#prop])? {
popFromClausePropertyPathContext();
}
)
)
;
-// TODO : still need to account for index operators in this series of rules...
-propertyPath
- : singlePartPropertyPath
- | multiPartPropertyPath
- ;
-singlePartPropertyPath!
- : i:identifier {
- #singlePartPropertyPath = handleTerminalPathPart( #i );
- }
+///////////////////////////////////////////////////////////////////////////////
+// propertyRef related rules...
+//
+
+/**
+ * The top level property ref recognition rule.
+ */
+propertyRef
+ : (unqualifiedPropertyRefCheck) => unqualifiedPropertyRef
+ | implicitJoin
+ | indexOperation
+ ;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have unqualified property reference. Generally
+ * used from within syntactic predicates to disambiguate the match path
+ *
+ * see {@link #implicitJoinSource} for example
+ */
+unqualifiedPropertyRefCheck!
+ : prop:IDENT { isUnqualifiedPropertyReference( prop ) }?
+ ;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * unqualified property references. Do not call this rule unless
+ * you know for certain (ala, have verified via the unqualifiedPropertyRefCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * unqualified property reference.
+ */
+unqualifiedPropertyRef!
+ : prop:IDENT {
+ #unqualifiedPropertyRef = buildUnqualifiedPropertyReference( prop );
+ }
+ ;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have an alias for a persister reference previously
+ * encountered and processed. Generally used from within syntactic
+ * predicates to disambiguate the path.
+ */
+persisterReferenceAliasCheck!
+ : alias:IDENT { isPersisterReferenceAlias( alias ) }?
+ ;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * persister reference aliases. Do not call this rule unless
+ * you know for certain (ala, have verified via the persisterReferenceAliasCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * alias for a persister reference
+ */
+persisterReferenceAlias!
+ : alias:IDENT {
+ #persisterReferenceAlias = resolveAlias( alias );
+ }
+ ;
+
+/**
+ * Perhaps better named as 'complex property ref' or 'pathed property ref' i.e.
+ * Anyway, the basic idea is (DOT <source> IDENT)
+ */
+implicitJoin!
+ : #( d:DOT source:implicitJoinSource prop:IDENT) {
+ #implicitJoin = resolvePropertyPathTerminus( #source, #prop );
+ }
+ ;
+
+intermediateImplicitJoin!
+ : #( d:DOT source:implicitJoinSource prop:IDENT) {
+ #intermediateImplicitJoin = resolvePropertyPathIntermediary( #source, #prop );
+ }
+ ;
+
+/**
+ * The output of the implicitJoinSource rule is a {@link org.hibernate.hql.ast.resolve.patg.PropertyPathPart}
+ * reference which is a tokenized and encoded representation of the current path expression
+ * resolution state.
+ */
+implicitJoinSource
+ : (persisterReferenceAliasCheck) => a:IDENT { #implicitJoinSource = resolveQualifiedRoot( #a ); }
+ | (unqualifiedPropertyRefCheck) => pr:IDENT { #implicitJoinSource = resolveUnqualifiedRoot( #pr ); }
+ | intermediateImplicitJoin
+ | i:indexOperation { #implicitJoinSource = resolveIndexedRoot( #i ); }
+ ;
+
+indexOperation
+ : #( i:INDEX_OP coll:propertyRef selector:indexSelector ) {
+ validateIndexOperationOperands( #coll, #selector );
+ }
+ ;
+
+indexSelector
+ : constant
+ | parameter
+ | arithmeticExpr
+ | collectionFunctionCall
;
-multiPartPropertyPath!
- : #( d:DOT lhs:multiPartPropertyPathIntermediateStructure rhs:multiPartPropertyPathTerminus ) {
- #multiPartPropertyPath = #rhs;
- }
+//
+// <end> propertyRef related rules...
+///////////////////////////////////////////////////////////////////////////////
+
+collectionFunctionCall
+ : #( METHOD_CALL pathAsIdent ( #(EXPR_LIST alias ) )? )
;
-multiPartPropertyPathIntermediateStructure!
+alias!
: i:identifier {
- // this represents the "root" of the path expression
- handleIntermediatePathPart( #i );
+ #alias = resolveAlias( i );
}
- | #( d:DOT lhs:multiPartPropertyPathIntermediateStructure rhs:propertyName ) {
- handleIntermediatePathPart( #rhs );
- }
;
-multiPartPropertyPathTerminus!
- : p:propertyName {
- #multiPartPropertyPathTerminus = handleTerminalPathPart( #p );
- }
- ;
-
// TODO : need to add cross joins
joinType
: ( (LEFT | RIGHT) (OUTER)? )
@@ -339,9 +476,13 @@
| #(CASE2 expr (#(WHEN expr expr))+ (#(ELSE expr))?)
;
+//addrExpr
+// : propertyRef
+// | #(INDEX_OP addrExprLhs expr)
+// ;
+
addrExpr
: propertyRef
- | #(INDEX_OP addrExprLhs expr)
;
addrExprLhs
@@ -363,9 +504,26 @@
| QUOTED_STRING
;
-parameter
- : #(COLON identifier)
- | #(PARAM (NUM_INT)?)
+parameter!
+ : #( c:COLON (c2:COLON)? i:identifier ) {
+ if ( c2 != null ) {
+ // allows escaping the colon...
+ String text = ":" + i.getText();
+ #parameter = #( [IDENT, text] );
+ }
+ else {
+ #parameter = generateNamedParameter( c, i );
+ }
+ }
+ | #( p:PARAM (n:NUM_INT)? ) {
+ if ( n != null ) {
+ // An ejb3-style "positional parameter", which we handle internally as a named-parameter
+ #parameter = generateNamedParameter( p, n );
+ }
+ else {
+ #parameter = generateOrdinalParameter( p );
+ }
+ }
;
functionCall
@@ -373,9 +531,9 @@
| #(AGGREGATE aggregateExpr )
;
-propertyRef
- : propertyPath
- ;
+//propertyRef
+// : propertyPath
+// ;
propertyName
: identifier
@@ -414,4 +572,4 @@
// General subtree. Matches anything, copies the tree verbatim.
subtree
: #(. (subtree)*)
- ;
\ No newline at end of file
+ ;
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/AbstractPropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,72 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.hql.antlr.ResolveTokenTypes;
-import antlr.collections.AST;
-import antlr.ASTFactory;
-
-/**
- * Provides basic templating around how the two {@link org.hibernate.hql.ast.resolve.PropertyPathHandler}
- * method calls need to be interpreted and handled in different scenarios.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractPropertyPathHandler implements PropertyPathHandler {
-
- public static final Log log = LogFactory.getLog( AbstractPropertyPathHandler.class );
-
- private PropertyPathPart prior;
-
- protected abstract PropertyPathPart handleRoot(String rootPathPart);
- protected abstract PropertyReference handleRootAsTerminus(String pathPart);
-
- protected void cleanup() {
- }
-
- public final void handleIntermediatePathPart(String pathPart) {
- if ( prior == null ) {
- prior = handleRoot( pathPart );
- }
- else {
- prior = prior.handleIntermediatePathPart( pathPart );
- }
- }
-
- public final PropertyReference handleTerminalPathPart(String pathPart) {
- try {
- if ( prior == null ) {
- return handleRootAsTerminus( pathPart );
- }
- else {
- return prior.handleTerminalPathPart( pathPart );
- }
- }
- finally {
- // clear our processing state in preparation for any future path expression
- prior = null;
- cleanup();
- }
- }
-
-
- protected final PropertyReference generatePropertyReference(
- PersisterReference persisterReference,
- String propertyName,
- ASTFactory astFactory) {
- PropertyReference propertyReferenceNode = ( PropertyReference ) astFactory.create( ResolveTokenTypes.PROPERTY_REF, persisterReference.getAlias() + "." + propertyName );
-
- AST aliasNode = astFactory.create( ResolveTokenTypes.ALIAS, persisterReference.getAlias() );
- propertyReferenceNode.addChild( aliasNode );
-
- AST propertyNameNode = astFactory.create( ResolveTokenTypes.IDENT, propertyName );
- propertyReferenceNode.addChild( propertyNameNode );
-
- return propertyReferenceNode;
- }
-
- protected static interface PropertyPathPart {
- public PropertyPathPart handleIntermediatePathPart(String name);
- public PropertyReference handleTerminalPathPart(String name);
- }
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/Aliasable.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,10 @@
+package org.hibernate.hql.ast.resolve;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public interface Aliasable {
+ public String getAlias();
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/CollectionPersisterReference.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,104 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.ComponentType;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.QueryException;
-
-/**
- * @author Steve Ebersole
- */
-public class CollectionPersisterReference extends EntityPersisterReference {
-
- private String role;
- private String alias;
- private QueryableCollection persister;
-
- public void initialize(String role, String alias) {
- this.role = role;
- this.alias = alias;
- }
-
- public QueryableCollection getCollectionPersister() {
- if ( persister == null ) {
- persister = ( QueryableCollection ) getSessionFactory().getCollectionPersister( role );
- }
- return persister;
- }
-
- public Queryable getEntityPersister() {
- if ( getCollectionPersister().getElementType().isEntityType() ) {
- EntityType elementEntityType = ( EntityType ) getCollectionPersister().getElementType();
- return ( Queryable ) elementEntityType.getAssociatedJoinable( getSessionFactory() );
- }
- else {
- throw new QueryException( "not a collection of entities" );
- }
- }
-
- public String getName() {
- return role;
- }
-
- public String getAlias() {
- return alias;
- }
-
- public AssociationType getPersisterType() {
- return ( AssociationType ) getEntityPersister().getType();
- }
-
- public Type getPropertyType(String propertyName) {
- if ( CollectionProperties.isAnyCollectionProperty( propertyName ) ) {
- // todo
- return null;
- }
- else {
- Type elementType = getCollectionPersister().getElementType();
- if ( elementType.isAssociationType() ) {
- // a collection of entities
- EntityType elementEntityType = ( EntityType ) elementType;
- try {
- Queryable elementEntityPersister = ( Queryable ) elementEntityType
- .getAssociatedJoinable( getSessionFactory() );
- return elementEntityPersister.getPropertyType( propertyName );
- }
- catch( Throwable t ) {
- // ignore
- }
- }
- else if ( elementType.isComponentType() ) {
- ComponentType elementComponentType = ( ComponentType ) elementType;
- String[] subPropertyNames = elementComponentType.getPropertyNames();
- for ( int i = 0; i < subPropertyNames.length; i++ ) {
- if ( subPropertyNames[i].equals( propertyName ) ) {
- return elementComponentType.getSubtypes()[i];
- }
- }
- }
- }
- return null;
- }
-
- public boolean containsProperty(String propertyName) {
- // this should not be called for "collection properties" (i.e., size, index, etc)
- // so we make that assumption here...
- try {
- return getPropertyType( propertyName ) != null;
- }
- catch( Throwable t ) {
- // ignore
- }
- return false;
- }
-
- public String toString() {
- return "CollectionPersisterReference {role=" + getName() + ", alias=" + getAlias() +
- ", element-type=" + getCollectionPersister().getElementType() + "}";
- }
-
-}
\ No newline at end of file
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/DeleteStatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,9 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Specialized statement node for representing DELETE statements
- *
- * @author Steve Ebersole
- */
-public class DeleteStatementNode extends StatementNode {
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/EntityPersisterReference.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,81 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.ast.tree.SessionFactoryAwareNode;
-
-/**
- * @author Steve Ebersole
- */
-public class EntityPersisterReference extends PersisterReference implements SessionFactoryAwareNode {
- private String entityName;
- private String alias;
- private boolean propertyFetch;
-
- private SessionFactoryImplementor sessionFactory;
- private transient Queryable persister;
-
- public void initialize(String entityName, String alias, boolean propertyFetch) {
- this.entityName = entityName;
- this.alias = alias;
- this.propertyFetch = propertyFetch;
- }
-
- public Queryable getEntityPersister() {
- if ( persister == null ) {
- persister = ( Queryable ) sessionFactory.getEntityPersister( entityName );
- }
- return persister;
- }
-
- public String getName() {
- return entityName;
- }
-
- public String getAlias() {
- return alias;
- }
-
- public boolean isPropertyFetch() {
- return propertyFetch;
- }
-
- public AssociationType getPersisterType() {
- return ( AssociationType ) getEntityPersister().getType();
- }
-
- public Type getPropertyType(String propertyName) {
- try {
- return getEntityPersister().getPropertyType( propertyName );
- }
- catch( Throwable t ) {
- return null;
- }
- }
-
- protected PersisterReference producePersisterReference(
- String propertyName,
- String alias,
- boolean propertyFetching,
- PersisterReferenceBuilder builder) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public boolean containsProperty(String propertyName) {
- return getPropertyType( propertyName ) != null;
- }
-
- public String toString() {
- return "EntityPersisterReference {entity-name=" + entityName + ", alias=" + alias + "}";
- }
-
- public void setSessionFactory(SessionFactoryImplementor sessionFactory) {
- this.sessionFactory = sessionFactory;
- }
-
- protected SessionFactoryImplementor getSessionFactory() {
- return sessionFactory;
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/FromClausePropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,134 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * todo: describe FromClausePropertyPathHandler
- *
- * @author Steve Ebersole
- */
-public class FromClausePropertyPathHandler extends AbstractPropertyPathHandler {
-
- public static final Log log = LogFactory.getLog( FromClausePropertyPathHandler.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReferenceBuilder persisterReferenceBuilder;
-
- private final JoinType joinType;
- private final String alias;
- private final boolean fetching;
- private final boolean propertyFetching;
-
- public FromClausePropertyPathHandler(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReferenceBuilder persisterReferenceBuilder,
- JoinType joinType,
- String alias,
- boolean fetching,
- boolean propertyFetching) {
- this.persisterReferenceContext = persisterReferenceContext;
- this.persisterReferenceBuilder = persisterReferenceBuilder;
- this.joinType = joinType;
- this.alias = alias;
- this.fetching = fetching;
- this.propertyFetching = propertyFetching;
- }
-
- protected PropertyPathPart handleRoot(String rootPathPart) {
- log.debug( "attempting to resolve [" + rootPathPart + "] as alias" );
- PersisterReference ref = persisterReferenceContext.locatePersisterReferenceByAlias( rootPathPart );
- if ( ref == null ) {
- log.debug( "attempting to resolve [" + rootPathPart + "] as unqualified property reference" );
- ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( rootPathPart );
- if ( ref == null ) {
- throw new QueryException( "unable to resolve path expression root [" + rootPathPart + "]" );
- }
- else {
- ref = ( PersisterReference ) persisterReferenceBuilder
- .buildPropertyJoin( ref, rootPathPart, joinType, null, fetching, false )
- .getFirstChild();
- }
- }
- return new PathPart( ref );
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- // this should only ever mean that we have a simple unqualified property reference
- log.debug( "attempting to resolve [" + pathPart + "] as unqualified property reference" );
- PersisterReference ref = persisterReferenceContext.locatePersisterReferenceExposingProperty( pathPart );
- if ( ref == null ) {
- throw new QueryException( "unable to resolve unqualified property reference [" + pathPart + "]" );
- }
- JoinNode join = persisterReferenceBuilder.buildPropertyJoin( ref, pathPart, joinType, alias, fetching, propertyFetching );
-
- return new PropertyReferenceAdapter( ref, pathPart, join.getRhs() );
- }
-
- private class PathPart implements PropertyPathPart {
- private final PersisterReference persisterReference;
-
- public PathPart(PersisterReference persisterReference) {
- this.persisterReference = persisterReference;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return new PathPart( ( PersisterReference ) buildJoin( name, null, false ).getFirstChild() );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- JoinNode join = buildJoin( name, alias, propertyFetching );
- return new PropertyReferenceAdapter( persisterReference, name, join.getRhs() );
- }
-
- private JoinNode buildJoin(String name, String alias, boolean propertyFetching) {
- return persisterReferenceBuilder.buildPropertyJoin(
- persisterReference,
- name,
- joinType,
- alias,
- fetching,
- propertyFetching
- );
- }
- }
-
- public static class PropertyReferenceAdapter extends PropertyReference {
-
- private final PersisterReference lhs;
- private final String propertyName;
- private final PersisterReference rhs;
-
- public PropertyReferenceAdapter(PersisterReference lhs, String propertyName, PersisterReference rhs) {
- this.lhs = lhs;
- this.propertyName = propertyName;
- this.rhs = rhs;
- }
-
- public String getOriginationAlias() {
- return lhs.getAlias();
- }
-
- public String getPropertyName() {
- return propertyName;
- }
-
- public PersisterReference getOrigination() {
- return lhs;
- }
-
- public Type getPropertyType() {
- return lhs.getPropertyType( propertyName );
- }
-
- public PersisterReference getRhs() {
- return rhs;
- }
-
- public String getDisplayText() {
- return " ADPATER : SHOULD NEVER END UP IN TREE {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
- }
- }
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HierarchicalPersisterReferenceContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HierarchicalPersisterReferenceContext.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HierarchicalPersisterReferenceContext.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,68 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Defines a hierarchical representation of a persister reference context.
+ * <p/>
+ * Generally speaking this notion should really only hold for SELECT
+ * statements. Does not make sense for INSERT or UPDATE or DELETE statements
+ * to have a parent, as that would mean they are being used as in a subqquery
+ * (certainly, however, it makes sense for these to *be the parent* context...).
+ *
+ * @author Steve Ebersole
+ */
+public class HierarchicalPersisterReferenceContext extends PersisterReferenceContext {
+
+ public static final Log log = LogFactory.getLog( HierarchicalPersisterReferenceContext.class );
+
+ private final PersisterReferenceContext parentContext;
+
+ /**
+ * Constructs the root context of a hierarchical persister reference context.
+ */
+ public HierarchicalPersisterReferenceContext() {
+ this( null );
+ }
+
+ /**
+ * Constructs a hierarchical persister reference sub-context.
+ *
+ * @param parentContext The parent context in the hierarchy.
+ */
+ public HierarchicalPersisterReferenceContext(PersisterReferenceContext parentContext) {
+ super();
+ this.parentContext = parentContext;
+ }
+
+ /**
+ * Override to project the lookup to our parent if not found locally.
+ *
+ * @param alias The alias to find.
+ * @return The located persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceByAlias(String alias) {
+ PersisterReference pRef = super.locatePersisterReferenceByAlias( alias );
+ if ( pRef == null && parentContext != null ) {
+ log.trace( "could not resolve as alias in this context; checking parent" );
+ pRef = parentContext.locatePersisterReferenceByAlias( alias );
+ }
+ return pRef;
+ }
+
+ /**
+ * Override to project the lookup to our parent if not found locally.
+ *
+ * @param propertyName The property name to resolve
+ * @return The located persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceExposingProperty(String propertyName) {
+ PersisterReference pRef = super.locatePersisterReferenceExposingProperty( propertyName );
+ if ( pRef == null && parentContext != null ) {
+ log.trace( "could not resolve as unqualified property in this context; checking parent" );
+ pRef = parentContext.locatePersisterReferenceExposingProperty( propertyName );
+ }
+ return pRef;
+ }
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,257 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.hql.antlr.GeneratedHqlResolver;
-import org.hibernate.hql.antlr.ResolveTokenTypes;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.QueryException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import antlr.collections.AST;
-import antlr.Token;
-
-import java.util.LinkedList;
-
-/**
- * Actual {@link GeneratedHqlResolver} implementation used in the query translator
- * providing semantic action implementation.
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class HqlResolver extends GeneratedHqlResolver
- implements HqlResolverASTFactory.InjectionContext, PersisterReferenceBuilder.Listener {
- private static Log log = LogFactory.getLog( HqlResolver.class );
- private static final ASTPrinter printer = new ASTPrinter( ResolveTokenTypes.class ).setShowClassNames( false );
-
- private final SessionFactoryImplementor sessionFactory;
- private final PersisterReferenceBuilder persisterReferenceBuilder;
-
- private StatementNode currentStatement;
- private PropertyPathHandlerStack propertyPathHandlerStack = new PropertyPathHandlerStack();
-
- public HqlResolver(SessionFactoryImplementor sessionFactory) {
- super();
- this.sessionFactory = sessionFactory;
- setASTFactory( new HqlResolverASTFactory( this ) );
- persisterReferenceBuilder = new PersisterReferenceBuilder( getASTFactory(), sessionFactory, this );
- }
-
-
- // HqlResolverASTFactory.InjectionContext implementation ~~~~~~~~~~~~~~~~~~
-
- public SessionFactoryImplementor getSessionFactory() {
- return sessionFactory;
- }
-
- public PersisterReferenceContext getPersisterReferenceContext() {
- return currentStatement;
- }
-
-
- // PersisterReferenceBuilder.Listener implementation ~~~~~~~~~~~~~~~~~~~~~~
-
- public void persisterReferenceBuilt(PersisterReference persisterReference) {
- currentStatement.registerPersisterReference( persisterReference );
- }
-
-
- // semantic action implementations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- /**
- * Semantic action called whenever we start a new statement (i.e top-level statement vs. subquery)
- *
- * @param statementNode The statement we are starting to process.
- */
- protected void pushStatement(AST statementNode) {
- log.trace( "pushing new statement context : " + currentStatement + " -> " + statementNode );
- StatementNode statement = ( StatementNode ) statementNode;
- propertyPathHandlerStack.push(
- new NormalPropertyPathHandler( statement, persisterReferenceBuilder, getASTFactory() )
- );
- if ( currentStatement != null ) {
- currentStatement.pushChild( statement );
- }
- currentStatement = statement;
- }
-
- /**
- * Semantic action called whenever we complete processing a statement.
- */
- protected void popStatement() {
- log.trace( "popping statement context : " + currentStatement + " -> " + currentStatement.getParentStatement() );
- currentStatement = currentStatement.getParentStatement();
- propertyPathHandlerStack.pop( NormalPropertyPathHandler.class );
- }
-
- protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias, AST propertyFetch) {
- log.debug( "pushing explicit (from clause) property path context" );
- propertyPathHandlerStack.push(
- new FromClausePropertyPathHandler(
- currentStatement,
- persisterReferenceBuilder,
- resolveJoinType( joinTypeNode ),
- textOrNull( alias ),
- fetch != null,
- propertyFetch != null
- )
- );
- }
-
- protected void popFromClausePropertyPathContext() {
- log.debug( "popping explicit (from clause) property path context" );
- propertyPathHandlerStack.pop( FromClausePropertyPathHandler.class );
- }
-
- protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
- propertyPathHandlerStack.push(
- new OnFragmentPropertyPathHandler(
- currentStatement,
- ( PersisterReference ) rhsPersisterReference,
- astFactory,
- sessionFactory
- )
- );
- log.debug( "pushing on-fragment path handler [rhs=" + rhsPersisterReference.getText() + "]" );
- }
-
- protected void popOnFragmentPropertyPathContext() {
- log.debug( "popping on-fragment path handler" );
- propertyPathHandlerStack.pop( OnFragmentPropertyPathHandler.class );
- }
-
- protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
- // can only be used in conjunction with property reference generated
- // directly from FromClausePropertyPathHandler...
- FromClausePropertyPathHandler.PropertyReferenceAdapter propertyReference = ( FromClausePropertyPathHandler.PropertyReferenceAdapter ) rhsPropertyReference;
- propertyPathHandlerStack.push(
- new WithFragmentPropertyPathHandler(
- currentStatement,
- propertyReference.getOrigination(),
- propertyReference.getRhs(),
- astFactory,
- sessionFactory
- )
- );
- log.debug( "pushing with-fragment path handler" );
- }
-
- protected void popWithFragmentPropertyPathContext() {
- log.debug( "popping on-fragment path handler" );
- propertyPathHandlerStack.pop( WithFragmentPropertyPathHandler.class );
- }
-
- /**
- * Semantic action called to perform generation of an {@link EntityPersisterReference}
- * representing a "root" persister reference.
- *
- * @param entityName The name of the entity.
- * @param alias An (optional) alias for later qualification-resolution to the generated
- * persister reference.
- * @param propertyFetch Was property fetching explicitly specified.
- * @return The generated reference.
- */
- protected AST buildEntityPersisterReference(AST entityName, AST alias, AST propertyFetch) {
- return buildEntityPersisterReference( entityName.getText(), textOrNull( alias ), propertyFetch != null );
- }
-
- private EntityPersisterReference buildEntityPersisterReference(String entityName, String alias, boolean propertyFetching) {
-// return currentStatement.buildEntityPersisterReference( entityName, alias, propertyFetching );
- return persisterReferenceBuilder.buildEntityPersisterReference( entityName, alias, propertyFetching );
- }
-
- private String textOrNull(AST node) {
- return node == null ? null : node.getText();
- }
-
- private JoinNode createJoinNode(JoinType type, String propertyName, boolean fetch, PersisterReference lhs) {
- JoinNode node = ( JoinNode ) getASTFactory().create( JOIN, "join" );
- node.initialize( type, propertyName, fetch, lhs );
- lhs.addChild( node );
- return node;
- }
-
-
- protected void handleIntermediatePathPart(AST name) {
- log.debug( "handling intermediate path part [" + name.getText() + "]" );
- propertyPathHandlerStack.getCurrent().handleIntermediatePathPart( name.getText() );
- }
-
- protected AST handleTerminalPathPart(AST name) {
- log.debug( "handling terminal path part [" + name.getText() + "]" );
- return propertyPathHandlerStack.getCurrent().handleTerminalPathPart( name.getText() );
- }
-
- protected AST buildAdHocJoinNode(AST rhs, AST joinTypeNode, AST onClause) {
- log.debug( printer.showAsString( onClause, "ON fragment for ad hoc join building" ) );
- JoinType joinType = resolveJoinType( joinTypeNode );
- OnFragmentPropertyPathHandler handler = ( OnFragmentPropertyPathHandler ) propertyPathHandlerStack.getCurrent();
- EntityPersisterReference lhs = ( EntityPersisterReference ) handler.getDiscoveredLhs();
- JoinNode join = createJoinNode( joinType, null, false, lhs );
- join.setFirstChild( rhs );
- join.applyExplicitJoinConditions( onClause );
- return join;
- }
-
- protected void applyWithFragment(AST withFragment) {
- WithFragmentPropertyPathHandler handler = ( WithFragmentPropertyPathHandler ) propertyPathHandlerStack.getCurrent();
- handler.applyWithFragment( withFragment );
- }
-
- private JoinType resolveJoinType(AST joinType) {
- int joinTypeType = joinType == null ? INNER : joinType.getType();
- switch ( joinTypeType ) {
- case INNER:
- return JoinType.INNER;
- case LEFT:
- return JoinType.LEFT;
- case RIGHT:
- return JoinType.RIGHT;
- case FULL:
- return JoinType.FULL;
- }
- // if no match found, throw exception
- throw new QueryException( "Unrecognized join type [" + joinType.getText() + "]" );
- }
-
- protected String reconstitutePathString(AST propertyReference) {
- AST child = propertyReference.getFirstChild();
- String prefix = "";
- StringBuffer buffer = new StringBuffer();
- while ( child != null ) {
- buffer.append( prefix ).append( child.getText() );
- prefix = ".";
- child = child.getNextSibling();
- }
- return buffer.toString();
- }
-
- private class PropertyPathHandlerStack {
- private LinkedList stack = new LinkedList();
-
- public PropertyPathHandlerStack() {
- }
-
- public void push(PropertyPathHandler context) {
- stack.addFirst( context );
- }
-
- public void pop(Class expectedCurrentHandlerClass) {
- PropertyPathHandler handler = ( PropertyPathHandler ) stack.removeFirst();
- if ( !expectedCurrentHandlerClass.isInstance( handler ) ) {
- throw new IllegalStateException(
- "INTERNAL PARSER ERROR : unexpected property path handler type encountered on pop" +
- " [expecting=" + expectedCurrentHandlerClass.getName() +
- ", encountered=" + handler.getClass().getName() + "]"
- );
- }
- log.debug( "popped path handler; current now : " + ( stack.isEmpty() ? null : getCurrent() ) );
- }
-
- public PropertyPathHandler getCurrent() {
- return ( PropertyPathHandler ) stack.getFirst();
- }
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,77 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.hql.antlr.ResolveTokenTypes;
-import org.hibernate.hql.ast.HqlASTFactory;
-import org.hibernate.hql.ast.tree.SessionFactoryAwareNode;
-import org.hibernate.hql.ast.tree.PersisterReferenceContextAwareNode;
-import org.hibernate.hql.ast.tree.ASTFactoryAwareNode;
-import org.hibernate.engine.SessionFactoryImplementor;
-import antlr.collections.AST;
-import antlr.Token;
-
-/**
- * AST factory for the resolver phase.
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class HqlResolverASTFactory extends HqlASTFactory implements ResolveTokenTypes {
-
- public static interface InjectionContext {
- public SessionFactoryImplementor getSessionFactory();
- public PersisterReferenceContext getPersisterReferenceContext();
- }
-
- private final InjectionContext context;
-
- public HqlResolverASTFactory(InjectionContext context) {
- this.context = context;
- }
-
- public Class getASTNodeType(int tokenType) {
- // Statement nodes:
- switch (tokenType) {
- case QUERY:
- return SelectStatementNode.class;
- case UPDATE:
- return UpdateStatementNode.class;
- case DELETE:
- return DeleteStatementNode.class;
- case INSERT:
- return InsertStatementNode.class;
- case ENTITY_PERSISTER_REF:
- return EntityPersisterReference.class;
- case COLLECTION_PERSISTER_REF:
- return CollectionPersisterReference.class;
- case JOIN:
- return JoinNode.class;
- case PROPERTY_REF:
- return PropertyReference.class;
- }
- return super.getASTNodeType( tokenType );
- }
-
- protected AST createUsingCtor(Token token, String string) {
- AST node = super.createUsingCtor( token, string );
- prepare( node );
- return node;
- }
-
- protected AST create(Class aClass) {
- AST node = super.create( aClass );
- prepare( node );
- return node;
- }
-
- private void prepare(AST node) {
- if ( node instanceof org.hibernate.hql.ast.tree.SessionFactoryAwareNode ) {
- ( ( SessionFactoryAwareNode ) node ).setSessionFactory( context.getSessionFactory() );
- }
- if ( node instanceof PersisterReferenceContextAwareNode ) {
- ( ( PersisterReferenceContextAwareNode ) node ).setPersisterReferenceContext( context.getPersisterReferenceContext() );
- }
- if ( node instanceof ASTFactoryAwareNode ) {
- ( ( ASTFactoryAwareNode ) node ).setASTFactory( this );
- }
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/InsertStatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,9 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Specialized statement node for representing INSERT statements
- *
- * @author Steve Ebersole
- */
-public class InsertStatementNode extends StatementNode {
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,79 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import antlr.Token;
-import antlr.collections.AST;
-import org.hibernate.hql.ast.tree.Node;
-import org.hibernate.hql.ast.tree.DisplayableNode;
-
-/**
- * Represents an HQL join. The coneptualization here is strictly that of
- * the join in terms of the context of the HQL query which may or may not have
- * direct correlation to any SQL join.
- *
- * @author Steve Ebersole
- */
-public class JoinNode extends Node implements DisplayableNode {
-
- // todo : we need to decide the tree structure of a join subtree.
- // based on that decision, we may need to have references here
- // to both the left-hand and right-hand persister references
-
- private JoinType joinType;
- private String propertyName;
- private boolean fetch;
- private PersisterReference lhs;
-
- public JoinNode() {
- super.setText( "join" );
- }
-
- public void initialize(JoinType joinType, String propertyName, boolean fetch, PersisterReference lhs) {
- this.joinType = joinType;
- this.propertyName = propertyName;
- this.fetch = fetch;
- this.lhs = lhs;
- }
-
- public JoinType getJoinType() {
- return joinType;
- }
-
- public void setJoinType(JoinType joinType) {
- this.joinType = joinType;
- }
-
- public boolean isFetch() {
- return fetch;
- }
-
- public void setFetch(boolean fetch) {
- this.fetch = fetch;
- }
-
- public PersisterReference getLhs() {
- return lhs;
- }
-
- public PersisterReference getRhs() {
- return ( PersisterReference ) getFirstChild();
- }
-
- public AST getExplicitJoinConditions() {
- return getFirstChild().getNextSibling();
- }
-
- public void applyExplicitJoinConditions(AST conditions) {
- getFirstChild().setNextSibling( conditions );
- }
-
- public String getDisplayText() {
- return "{" + "type=" + joinType +
- ", fetch=" + fetch +
- ", lhs=" + ( lhs == null ? "???" : lhs.getAlias() ) +
- ", property=" + ( propertyName == null ? "n/a" : propertyName ) + "}";
- }
-
- public String toString() {
- return "JoinNode " + getDisplayText();
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,62 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-/**
- * Represents a canonical join type.
- * <p/>
- * Note that currently HQL really only supports inner and left outer joins
- * (though cross joins can also be achieved). This is because joins in HQL
- * are always defined in relation to a mapped association. However, when we
- * start allowing users to specify ad-hoc joins this may need to change to
- * allow the full spectrum of join types. Thus the others are provided here
- * currently just for completeness and for future expansion.
- *
- * @author Steve Ebersole
- */
-public class JoinType implements Serializable {
- /**
- * Represents an inner join.
- */
- public static final JoinType INNER = new JoinType( "inner" );
- /**
- * Represents a left outer join.
- */
- public static final JoinType LEFT = new JoinType( "left outer" );
- /**
- * Represents a right outer join.
- */
- public static final JoinType RIGHT = new JoinType( "right outer" );
- /**
- * Represents a cross join (aka a cartesian product).
- */
- public static final JoinType CROSS = new JoinType( "cross" );
- /**
- * Represents a full join.
- */
- public static final JoinType FULL = new JoinType( "full" );
-
- private static final HashMap INSTANCES = new HashMap();
- static {
- INSTANCES.put( INNER.name, INNER );
- INSTANCES.put( LEFT.name, LEFT );
- INSTANCES.put( RIGHT.name, RIGHT );
- INSTANCES.put( CROSS.name, CROSS );
- INSTANCES.put( FULL.name, FULL );
- }
-
- private final String name;
-
- private JoinType(String name) {
- this.name = name;
- }
-
- public String toString() {
- return name;
- }
-
- private Object readResolve() {
- return INSTANCES.get( name );
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/NormalPropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,218 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-import org.hibernate.type.ComponentType;
-import antlr.ASTFactory;
-
-/**
- * Defines the behavior of how implicit joins are normally handled.
- * <p/>
- * All other implementations of {@link org.hibernate.hql.ast.resolve.PropertyPathHandler} are
- * considered special cases.
- *
- * @author Steve Ebersole
- */
-public class NormalPropertyPathHandler extends AbstractPropertyPathHandler {
-
- public static final Log log = LogFactory.getLog( NormalPropertyPathHandler.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReferenceBuilder persisterReferenceBuilder;
- private final ASTFactory astFactory;
-
- public NormalPropertyPathHandler(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReferenceBuilder persisterReferenceBuilder,
- ASTFactory astFactory) {
- this.persisterReferenceContext = persisterReferenceContext;
- this.persisterReferenceBuilder = persisterReferenceBuilder;
- this.astFactory = astFactory;
- }
-
- protected PropertyPathPart handleRoot(String pathPart) {
- PersisterReference persisterReference = resolveAsAlias( pathPart );
- if ( persisterReference != null ) {
- return new PropertyPathRoot( ( EntityPersisterReference ) persisterReference );
- }
-
- persisterReference = resolveAsUnqualified( pathPart );
- if ( persisterReference != null ) {
- return new EntityPropertyReference( ( EntityPersisterReference ) persisterReference, pathPart, false );
- }
-
- throw new QueryException( "unable to resolve path expression root [" + pathPart + "]" );
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- PersisterReference ref = resolveAsUnqualified( pathPart );
- return generatePropertyReference( ref, pathPart, astFactory );
- }
-
-
- private EntityPersisterReference resolveAsAlias(String name) {
- return ( EntityPersisterReference ) persisterReferenceContext.locatePersisterReferenceByAlias( name );
- }
-
- private EntityPersisterReference resolveAsUnqualified(String firstPathExpression) {
- return persisterReferenceContext.locatePersisterReferenceExposingProperty( firstPathExpression );
- }
-
- private PropertyPathPart determineAppropriatePartType(EntityPersisterReference origin, String propertyName) {
- Type propertyType = origin.getPropertyType( propertyName );
- if ( propertyType.isComponentType() ) {
- return new ComponentPropertyReference( origin, propertyName, ( ComponentType ) propertyType );
- }
- else if ( propertyType.isEntityType() ) {
- return new EntityPropertyReference( origin, propertyName, false );
- }
- else if ( propertyType.isCollectionType() ) {
- return new CollectionPropertyReference( origin, propertyName );
- }
- else {
- return new SimplePropertyReference( origin, propertyName );
- }
- }
-
- private int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) {
- String[] componentPropertyNames = componentType.getPropertyNames();
- for ( int i = 0; i < componentPropertyNames.length; i++ ) {
- if ( componentPropertyNames[i].equals( subPropertyName ) ) {
- return i;
- }
- }
- throw new QueryException( "could not locate component property [" + subPropertyName + "]" );
- }
-
- private class PropertyPathRoot implements PropertyPathPart {
- private final EntityPersisterReference persisterReference;
-
- public PropertyPathRoot(EntityPersisterReference persisterReference) {
- this.persisterReference = persisterReference;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return determineAppropriatePartType( persisterReference, name );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- // todo : this really needs to consider whether a join might be needed
- // based on the property type and type of clause
- return generatePropertyReference( persisterReference, name, astFactory );
- }
-
- }
-
- private class SimplePropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String propertyName;
-
- public SimplePropertyReference(EntityPersisterReference origin, String propertyName) {
- this.origin = origin;
- this.propertyName = propertyName;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "cannot perform implicit join based on simple property" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- throw new QueryException( "cannot perform implicit join based on simple property" );
- }
- }
-
- private class ComponentPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String componentPropertyName;
- private final ComponentType componentType;
-
- public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName) {
- this( origin, componentPropertyName, ( ComponentType ) origin.getPropertyType( componentPropertyName ) );
- }
-
- public ComponentPropertyReference(EntityPersisterReference origin, String componentPropertyName, ComponentType componentType) {
- this.origin = origin;
- this.componentPropertyName = componentPropertyName;
- this.componentType = componentType;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String propertyName) {
- int index = locateComponentPropertyIndex( componentType, propertyName );
- String path = buildDerefPath( propertyName );
- Type propertyType = componentType.getSubtypes()[index];
- if ( propertyType.isComponentType() ) {
- return new ComponentPropertyReference( origin, path, ( ComponentType ) propertyType );
- }
- else if ( propertyType.isEntityType() ) {
- return new EntityPropertyReference( origin, path, false );
- }
- else {
- return new SimplePropertyReference( origin, path );
- }
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- return generatePropertyReference( origin, buildDerefPath( name ), astFactory );
- }
-
- private String buildDerefPath(String subPropertyName) {
- return componentPropertyName + "." + subPropertyName;
- }
- }
-
- private class EntityPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String propertyName;
-
- private boolean joined;
-
- public EntityPropertyReference(EntityPersisterReference origin, String propertyName, boolean joined) {
- this.origin = origin;
- this.propertyName = propertyName;
- this.joined = joined;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
- return determineAppropriatePartType( joinedPersister, name );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- // not always needed (i.e. : .id)
- EntityPersisterReference joinedPersister = ( EntityPersisterReference ) buildPropertyJoin( origin, propertyName );
- return generatePropertyReference( joinedPersister, name, astFactory );
- }
- }
-
- private class CollectionPropertyReference implements PropertyPathPart {
- private final EntityPersisterReference origin;
- private final String collectionPropertyName;
-
- public CollectionPropertyReference(EntityPersisterReference origin, String collectionPropertyName) {
- this.origin = origin;
- this.collectionPropertyName = collectionPropertyName;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "illegal attempt to perform implicit join across collection property" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- if ( CollectionProperties.isAnyCollectionProperty( name ) ) {
- CollectionPersisterReference joinedPersister = ( CollectionPersisterReference ) buildPropertyJoin( origin, collectionPropertyName );
- return generatePropertyReference( joinedPersister, name, astFactory );
- }
- throw new QueryException( "illegal attempt to perform implicit join across collection property" );
- }
- }
-
-
- private PersisterReference buildPropertyJoin(EntityPersisterReference origin, String propertyName) {
- return ( PersisterReference ) persisterReferenceBuilder
- .buildPropertyJoin( origin, propertyName, JoinType.INNER, null, false, false )
- .getFirstChild();
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/OnFragmentPropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,159 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.type.Type;
-import org.hibernate.QueryException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import antlr.ASTFactory;
-
-/**
- * todo: describe OnFragmentPropertyPathHandler
- *
- * @author Steve Ebersole
- */
-public class OnFragmentPropertyPathHandler extends AbstractPropertyPathHandler {
-
- public static final Log log = LogFactory.getLog( OnFragmentPropertyPathHandler.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReference joinRhs;
- private final ASTFactory astFactory;
- private final SessionFactoryImplementor sessionFactory;
-
- private PersisterReference joinLhs;
-
- public OnFragmentPropertyPathHandler(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReference joinRhs,
- ASTFactory astFactory,
- SessionFactoryImplementor sessionFactory) {
- this.astFactory = astFactory;
- this.persisterReferenceContext = persisterReferenceContext;
- this.joinRhs = joinRhs;
- this.sessionFactory = sessionFactory;
- }
-
- public PersisterReference getDiscoveredLhs() {
- return joinLhs;
- }
-
- protected PropertyPathPart handleRoot(String rootPathPart) {
- // might indicte a number of situations:
- // 1) alias to joinRhs
- // 2) unqualified property reference from joinRhs
- // 3) alias to joinLhs
- // 4) unqualified property reference from joinLhs
- //
- // joinRhs is statically known
-
-
- if ( joinRhs.getAlias().equals( rootPathPart ) ) {
- return new Alias( joinRhs );
- }
-
- Type propertyType = joinRhs.getPropertyType( rootPathPart );
- if ( propertyType != null ) {
- return new PropRef( joinRhs, rootPathPart, propertyType );
- }
-
- // otherwise, rootPathPart must refer to joinLhs in some fashion...
- if ( joinLhs != null ) {
- // we have already resolved a|the lhs (both rhs and lhs assumed the same here between all logical expressions)
- if ( joinLhs.getAlias().equals( rootPathPart ) ) {
- return new Alias( joinLhs );
- }
- else {
- propertyType = joinLhs.getPropertyType( rootPathPart );
- if ( propertyType != null ) {
- return new PropRef( joinLhs, rootPathPart, propertyType );
- }
- throw new QueryException(
- "path [" + rootPathPart + "] not resolveable against either left-hand-side [" +
- joinLhs.getText() + "] nor right-hand-side [" +
- joinRhs.getText() + "] of the join"
- );
- }
- }
- else {
- // we still need to resolve a lhs, so see if we can do it based on the current path part
- PersisterReference persisterReference = persisterReferenceContext.locatePersisterReferenceByAlias( rootPathPart );
- if ( persisterReference != null ) {
- joinLhs = persisterReference;
- return new Alias( persisterReference );
- }
- persisterReference = persisterReferenceContext.locatePersisterReferenceExposingProperty( rootPathPart );
- if ( persisterReference != null ) {
- joinLhs = persisterReference;
- Type type = persisterReference.getPropertyType( rootPathPart );
- return new PropRef( persisterReference, rootPathPart, type );
- }
-
- throw new QueryException( "unable to resolve path expression root [" + rootPathPart + "]" );
- }
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- // specialized case of the above recognition rule, here it is expected that pathPart
- // explicitly be an unqualified proeprty reference originating from either the
- // lhs or rhs
- if ( joinRhs.getPropertyType( pathPart ) != null ) {
- return generatePropertyReference( joinRhs, pathPart, astFactory );
- }
-
- PersisterReference lhs = persisterReferenceContext.locatePersisterReferenceExposingProperty( pathPart );
- if ( lhs != null ) {
- joinLhs = lhs;
- return generatePropertyReference( lhs, pathPart, astFactory );
- }
-
- throw new QueryException( "unable to resolve path expression [" + pathPart + "]" );
- }
-
- private class Alias implements PropertyPathPart {
-
- private final PersisterReference persisterRef;
-
- public Alias(PersisterReference persisterRef) {
- this.persisterRef = persisterRef;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return new PropRef( persisterRef, name, persisterRef.getPropertyType( name ) );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- return generatePropertyReference( persisterRef, name, astFactory );
- }
- }
-
- private class PropRef implements PropertyPathPart {
-
- private final PersisterReference persisterRef;
- private final String propertyName;
- private final Type propertyType;
- private final String leadingPathParts;
-
- public PropRef(PersisterReference persisterRef, String propertyName, Type propertyType) {
- this.persisterRef = persisterRef;
- this.propertyName = propertyName;
- this.propertyType = propertyType;
- this.leadingPathParts = null;
- }
-
- public PropRef(PersisterReference persisterRef, String propertyName, Type propertyType, String leadingPathParts) {
- this.persisterRef = persisterRef;
- this.propertyName = propertyName;
- this.propertyType = propertyType;
- this.leadingPathParts = leadingPathParts;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "NOT YET IMPLEMENTED : complex path structures in ON fragement" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- throw new QueryException( "NOT YET IMPLEMENTED : complex path structures in ON fragement" );
- }
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReference.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,71 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.hql.ast.tree.Node;
-import org.hibernate.hql.ast.tree.PersisterReferenceContextAwareNode;
-import org.hibernate.QueryException;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Represents a reference to a persister (either entity or collection) within
- * an HQL statement.
- *
- * @author Steve Ebersole
- */
-public abstract class PersisterReference extends Node implements PersisterReferenceContextAwareNode {
-
- private final Map joinsByProperty = new HashMap();
-
- private PersisterReferenceContext context;
-
- public abstract String getName();
- public abstract String getAlias();
- public abstract AssociationType getPersisterType();
- public abstract Type getPropertyType(String propertyName);
-
- public String getText() {
- return getName() + " (" + getAlias() + ")";
- }
-
- public void setPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext) {
- this.context = persisterReferenceContext;
- }
-
- public PersisterReferenceContext getPersisterReferenceContext() {
- return context;
- }
-
- /**
- * Locate a previously {@link #registerJoinByProperty registered}
- * persister reference by the property name under which it was registered.
- *
- * @param propertyName The name of the property.
- * @return The previously registered persister reference; or null.
- */
- JoinNode locateJoinByProperty(String propertyName) {
- return ( JoinNode ) joinsByProperty.get( propertyName );
- }
-
- void registerJoinByProperty(String propertyName, JoinNode persisterReference) {
- joinsByProperty.put( propertyName, persisterReference );
- }
-
- void validatePropertyAsJoinable(String propertyName) {
- Type type = getPropertyType( propertyName );
- if ( type == null ) {
- throw new QueryException(
- "Could not resolve property [name=" + propertyName +
- ", source=" + getText() + "]"
- );
- }
- if ( !type.isAssociationType() ) {
- throw new QueryException(
- "Invalid attempt to join on non association property [name=" + propertyName +
- ", source=" + getText() + "]"
- );
- }
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,178 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import antlr.ASTFactory;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.hql.antlr.ResolveTokenTypes;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.CollectionType;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * A helper for building {@link PersisterReference} AST structures.
- *
- * @author Steve Ebersole
- */
-public class PersisterReferenceBuilder {
-
- public static interface Listener {
- public void persisterReferenceBuilt(PersisterReference persisterReference);
- }
-
- public static final Log log = LogFactory.getLog( PersisterReferenceBuilder.class );
-
- private final ASTFactory astFactory;
- private final SessionFactoryImplementor sessionFactory;
- private final Listener listener;
-
- private int unaliasedCount = 0;
-
- public PersisterReferenceBuilder(
- ASTFactory astFactory,
- SessionFactoryImplementor sessionFactory,
- Listener listener) {
- this.astFactory = astFactory;
- this.sessionFactory = sessionFactory;
- this.listener = listener;
- }
-
- private void notifyListener(PersisterReference ref) {
- log.debug( "persister reference built [" + ref.getText() + "]" );
- listener.persisterReferenceBuilt( ref );
- }
-
- public ASTFactory getAstFactory() {
- return astFactory;
- }
-
- // exposed services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- /**
- * Builds a "root" entity persister reference
- *
- * @param entityName
- * @param alias
- * @param propertyFetching
- * @return the reference
- */
- public EntityPersisterReference buildEntityPersisterReference(String entityName, String alias, boolean propertyFetching) {
- EntityPersister persister = lookupPersister( entityName );
- alias = determineAlias( alias );
- EntityPersisterReference persisterReference = ( EntityPersisterReference ) astFactory.create( ResolveTokenTypes.ENTITY_PERSISTER_REF, persister.getEntityName() );
- persisterReference.initialize( persister.getEntityName(), alias, propertyFetching );
- notifyListener( persisterReference );
- log.debug( "persister reference built [" + persisterReference.getText() + "]" );
- return persisterReference;
- }
-
- public JoinNode buildPropertyJoin(
- PersisterReference source,
- String propertyName,
- JoinType joinType,
- String alias,
- boolean fetching,
- boolean propertyFetching) {
- source.validatePropertyAsJoinable( propertyName );
- JoinNode join = null;
- if ( isNonExplicitAlias( alias ) ) {
- join = source.locateJoinByProperty( propertyName );
- }
- if ( join == null ) {
- join = ( JoinNode ) astFactory.create( ResolveTokenTypes.JOIN, "join" );
- join.initialize( joinType, propertyName, fetching, source );
- source.addChild( join );
- join.setFirstChild( buildJoinedPersisterReference( source, propertyName, alias, propertyFetching ) );
- if ( isNonExplicitAlias( alias ) ) {
- source.registerJoinByProperty( propertyName, join );
- }
- }
- return join;
- }
-
- private EntityPersister lookupPersister(String name) {
- // First, try to get the persister using the class name directly.
- try {
- return sessionFactory.getEntityPersister( name );
- }
- catch ( MappingException ignore ) {
- // unable to locate it using this name
- }
-
- // If that didn't work, try using the 'import' name.
- String importedClassName = sessionFactory.getImportedClassName( name );
- if ( importedClassName == null ) {
- return null;
- }
- return sessionFactory.getEntityPersister( importedClassName );
- }
-
- private String determineAlias(String alias) {
- if ( alias == null ) {
- alias = "<gen:" + unaliasedCount++ + ">";
- }
- return alias;
- }
-
- public boolean isNonExplicitAlias(String alias) {
- return alias == null || ( alias.startsWith( "<gen:" ) && alias.endsWith( ">" ) );
- }
-
- private PersisterReference buildJoinedPersisterReference(PersisterReference source, String propertyName, String alias, boolean propertyFetching) {
- alias = determineAlias( alias );
- if ( source.getPersisterType().isEntityType() ) {
- return buildJoinedPersisterReferenceFromEntity( ( EntityPersisterReference ) source, propertyName, alias, propertyFetching );
- }
- else {
- return buildJoinedPersisterReferenceFromCollection( ( CollectionPersisterReference ) source, propertyName, alias, propertyFetching );
- }
- }
-
- private PersisterReference buildJoinedPersisterReferenceFromEntity(
- EntityPersisterReference source,
- String propertyName,
- String alias,
- boolean propertyFetching) {
- Type type = source.getPropertyType( propertyName );
- if ( type.isEntityType() ) {
- EntityType entityType = ( EntityType ) type;
- EntityPersisterReference entityPersisterReference = ( EntityPersisterReference ) astFactory.create( ResolveTokenTypes.ENTITY_PERSISTER_REF, entityType.getAssociatedEntityName() );
- entityPersisterReference.initialize( entityType.getAssociatedEntityName(), alias, propertyFetching );
- notifyListener( entityPersisterReference );
- return entityPersisterReference;
- }
- else if ( type.isCollectionType() ) {
- CollectionType collectionType = ( CollectionType ) type;
- CollectionPersisterReference collectionPersisterReference = ( CollectionPersisterReference ) astFactory.create( ResolveTokenTypes.COLLECTION_PERSISTER_REF, collectionType.getRole() );
- collectionPersisterReference.initialize( collectionType.getRole(), alias );
- notifyListener( collectionPersisterReference );
- return collectionPersisterReference;
- }
- else {
- throw new QueryException(
- "cannot dereference property [" + propertyName +
- "] from persister [" + source.getEntityPersister().getEntityName() +
- "] as part of path expression"
- );
- }
- }
-
- private PersisterReference buildJoinedPersisterReferenceFromCollection(
- CollectionPersisterReference collectionPersisterReference,
- String propertyName,
- String alias,
- boolean propertyFetching) {
- // todo : we may need two different forms of CollectionPersisterReference,
- // the distinction being which "properties" are available from each...
- // (1) represents nodes built from explicit joins; only properties from
- // the underlying collection elements are available (unless the
- // collection is a value collection)
- // (2) represents nodes built from implicit joins; only
- // "collection properties" are available (size, index, etc)
- return null;
- }
-
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContext.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,11 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * todo: describe PersisterReferenceContext
- *
- * @author Steve Ebersole
- */
-public interface PersisterReferenceContext {
- public PersisterReference locatePersisterReferenceByAlias(String alias);
- public EntityPersisterReference locatePersisterReferenceExposingProperty(String firstPathExpression);
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceContextAwareNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,10 @@
+package org.hibernate.hql.ast.resolve;
+
+/**
+ * todo: describe PersisterReferenceContextAwareNode
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterReferenceContextAwareNode {
+ public void setPersisterReferenceContext(PersisterReferenceContext persisterReferenceContext);
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,11 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Contract for how implicit joins are handled.
- *
- * @author Steve Ebersole
- */
-public interface PropertyPathHandler {
- public void handleIntermediatePathPart(String pathPart);
- public PropertyReference handleTerminalPathPart(String pathPart);
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,63 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.hibernate.type.Type;
-import org.hibernate.hql.ast.tree.Node;
-import org.hibernate.hql.ast.tree.PersisterReferenceContextAwareNode;
-import org.hibernate.hql.ast.tree.DisplayableNode;
-
-/**
- * Represents a reference to a particular property.
- * <p/>
- * The sub-tree structure of this node is such that its first child is an ALIAS
- * node representing an alias pointing to the specific persister reference from
- * which the property reference originates. The other child is the property name,
- * as an IDENT
- *
- * @author Steve Ebersole
- */
-public class PropertyReference extends Node implements PersisterReferenceContextAwareNode, DisplayableNode {
-
- private PersisterReferenceContext persisterContext;
-
- // caches
- private String alias;
- private String propertyName;
- private Type propertyType;
- private PersisterReference origin;
-
- public String getOriginationAlias() {
- if ( alias == null ) {
- alias = getFirstChild().getText();
- }
- return alias;
- }
-
- public String getPropertyName() {
- if ( propertyName == null ) {
- propertyName = getFirstChild().getNextSibling().getText();
- }
- return propertyName;
- }
-
- public PersisterReference getOrigination() {
- if ( origin == null ) {
- origin = persisterContext.locatePersisterReferenceByAlias( getOriginationAlias() );
- }
- return origin;
- }
-
- public Type getPropertyType() {
- if ( propertyType == null ) {
- propertyType = getOrigination().getPropertyType( getPropertyName() );
- }
- return propertyType;
- }
-
- public void setPersisterReferenceContext(PersisterReferenceContext persisterContext) {
- this.persisterContext = persisterContext;
- }
-
- public String getDisplayText() {
- return " {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
- }
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReferenceSource.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,43 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.type.Type;
+
+/**
+ * Contract for things which can be the source of a property reference in an
+ * HQL query. This contract is used to resolve dot-structures.
+ *
+ * @author Steve Ebersole
+ */
+public interface PropertyReferenceSource {
+ /**
+ * Retrieves the type that this source represents.
+ *
+ * @return The source's type.
+ */
+ public Type getRootType();
+
+ /**
+ * Any path information "backing" this source. Used for componnent
+ * resolution, where this source represents a component value.
+ *
+ * @return The component property path
+ */
+ public String getPropertyPath();
+
+ /**
+ * Again, used in component resolutions. The persister from which the
+ * {@link #getPropertyPath} is relative.
+ *
+ * @return
+ */
+ public PersisterReference getPropertyPathRoot();
+
+ public Type getPropertyType(String propertyName);
+
+ public void prepareLHS(ResolutionContext resolutionContext, String rhsPropertyName);
+
+ public JoinNode locateImplicitJoinByProperty(String propertyName);
+
+ public void registerImplicitJoinByProperty(String propertyName, JoinNode join);
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContext.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,62 @@
+package org.hibernate.hql.ast.resolve;
+
+import antlr.ASTFactory;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+
+/**
+ * Defines the basic contract for a resolution context.
+ * <p/>
+ * Essentially used to define a series of services that components
+ * operating within said context can rely upon.
+ *
+ * @author Steve Ebersole
+ */
+public interface ResolutionContext {
+ /**
+ * Retrieve a reference to the factory associated with this context for
+ * creating AST/Node instances.
+ *
+ * @return The ASTFactory.
+ */
+ public ASTFactory getASTFactory();
+
+ /**
+ * Retrieve a reference to the session factory associated with this context.
+ *
+ * @return The session factory.
+ */
+ public SessionFactoryImplementor getSessionFactory();
+
+ /**
+ * Retrieve a reference to the {@link PersisterReference} builder associated
+ * with this context.
+ *
+ * @return The {@link PersisterReference} builder
+ */
+ public PersisterReferenceBuilder getPersisterReferenceBuilder();
+
+ /**
+ * Retrieve a reference to the {@link PersisterReferenceContext}
+ * <b>currently</b> associated with this context.
+ * <p/>
+ * The current {@link PersisterReferenceContext} will change in relation
+ * to processed subqueries...
+ *
+ * @return The current {@link PersisterReferenceContext}.
+ */
+ public PersisterReferenceContext getCurrentPersisterReferenceContext();
+
+ /**
+ * Retrieve a reference to the {@link PathResolutionStrategy}
+ * <b>currently</b> associated with this context.
+ * <p/>
+ * The current {@link PathResolutionStrategy} will change in relation to
+ * various changes in the internal context state.
+ *
+ * @return The current {@link PathResolutionStrategy}
+ */
+ public PathResolutionStrategy getCurrentPathResolutionStrategy();
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/ResolutionContextAwareNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,10 @@
+package org.hibernate.hql.ast.resolve;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public interface ResolutionContextAwareNode {
+ public void setResolutionContext(ResolutionContext resolutionContext);
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,9 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Specialized statement node for representing SELECT statements
- *
- * @author Steve Ebersole
- */
-public class SelectStatementNode extends StatementNode {
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectStatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,15 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.hql.ast.resolve.path.PathResolutionStrategy;
+import org.hibernate.hql.ast.resolve.path.BasicPathResolutionStrategySupport;
+
+/**
+ * Specialized statement node for representing SELECT statements
+ *
+ * @author Steve Ebersole
+ */
+public class SelectStatementNode extends StatementNode {
+ public PathResolutionStrategy buildBasicPathResolutionStrategy(ResolutionContext resolutionContext) {
+ return new BasicPathResolutionStrategySupport( resolutionContext );
+ }
+}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/StatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,95 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.QueryException;
-import org.hibernate.hql.ast.tree.Node;
-import org.hibernate.util.EmptyIterator;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Base node class for hql statements (SELECT, DELETE, INSERT, UPDATE).
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public abstract class StatementNode extends Node implements PersisterReferenceContext {
-
- private static final Log log = LogFactory.getLog( StatementNode.class );
-
- private StatementNode parentStatement;
- private List childStatements;
-
- public StatementNode getParentStatement() {
- return parentStatement;
- }
-
- public StatementNode getTopLevelStatement() {
- StatementNode topLevel = this;
- while ( topLevel.getParentStatement() != null ) {
- topLevel = topLevel.getParentStatement();
- }
- return topLevel;
- }
-
- public boolean isTopLevelStatement() {
- return parentStatement == null;
- }
-
- public Iterator iterateChildStatements() {
- return childStatements == null ? EmptyIterator.INSTANCE : childStatements.iterator();
- }
-
- public void pushChild(StatementNode childStatement) {
- childStatement.setParent( this );
- if ( childStatements == null ) {
- childStatements = new ArrayList();
- }
- childStatements.add( childStatement );
- }
-
- private void setParent(StatementNode parentStatement) {
- if ( this.parentStatement != null ) {
- throw new QueryException( "statement already had an associated parent" );
- }
- this.parentStatement = parentStatement;
- }
-
-
- // implementation of PersisterReferenceContext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- // TODO : move this out of here into a seperate class
-
- private Map persisterReferencesByAlias = new HashMap();
- private List persisterReferences = new ArrayList();
-
- public PersisterReference locatePersisterReferenceByAlias(String alias) {
- return ( PersisterReference ) persisterReferencesByAlias.get( alias );
- }
-
- public EntityPersisterReference locatePersisterReferenceExposingProperty(String firstPathExpression) {
- log.trace( "trying to locate persister exposing property [" + firstPathExpression + "]" );
- EntityPersisterReference match = null;
- Iterator itr = persisterReferences.iterator();
- while( itr.hasNext() ) {
- final EntityPersisterReference test = ( EntityPersisterReference ) itr.next();
- if ( test.containsProperty( firstPathExpression ) ) {
- if ( match != null ) {
- throw new QueryException( "multiple referenced persisters contained property [" + firstPathExpression + "]" );
- }
- match = test;
- }
- }
- return match;
- }
-
- void registerPersisterReference(PersisterReference persisterReference) {
- persisterReferencesByAlias.put( persisterReference.getAlias(), persisterReference );
- persisterReferences.add( persisterReference );
- }
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/UpdateStatementNode.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,9 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-/**
- * Specialized statement node for representing UPDATE statements
- *
- * @author Steve Ebersole
- */
-public class UpdateStatementNode extends StatementNode {
-}
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/WithFragmentPropertyPathHandler.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/WithFragmentPropertyPathHandler.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/WithFragmentPropertyPathHandler.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -1,153 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.QueryException;
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-/**
- * todo: describe WithFragmentPropertyPathHandler
- *
- * @author Steve Ebersole
- */
-public class WithFragmentPropertyPathHandler extends AbstractPropertyPathHandler {
-
- public static final Log log = LogFactory.getLog( WithFragmentPropertyPathHandler.class );
-
- private final PersisterReferenceContext persisterReferenceContext;
- private final PersisterReference joinLhs;
- private final PersisterReference joinRhs;
- private final ASTFactory astFactory;
- private final SessionFactoryImplementor sessionFactory;
-
- public WithFragmentPropertyPathHandler(
- PersisterReferenceContext persisterReferenceContext,
- PersisterReference joinLhs,
- PersisterReference joinRhs,
- ASTFactory astFactory,
- SessionFactoryImplementor sessionFactory) {
- this.astFactory = astFactory;
- this.persisterReferenceContext = persisterReferenceContext;
- this.joinLhs = joinLhs;
- this.joinRhs = joinRhs;
- this.sessionFactory = sessionFactory;
- }
-
- public PersisterReference getDiscoveredLhs() {
- return joinLhs;
- }
-
- public void applyWithFragment(AST withFragment) {
- // first, locate the acctual JoinNode which links the lhs and rhs...
- JoinNode joinNode = null;
- AST nextPossible = joinLhs.getFirstChild();
- while ( nextPossible != null ) {
- if ( nextPossible instanceof JoinNode && nextPossible.getFirstChild() == joinRhs ) {
- joinNode = ( JoinNode ) nextPossible;
- break;
- }
- }
- if ( joinNode == null ) {
- throw new QueryException( "could not locate specific join node to which to apply wqith fragment [" + withFragment + "]" );
- }
- joinNode.applyExplicitJoinConditions( withFragment );
- }
-
- protected PropertyPathPart handleRoot(String rootPathPart) {
- // both joinLhs and joinRhs are statically know here...
-
- // might indicte a number of situations:
- // 1) alias to joinRhs
- // 2) unqualified property reference from joinRhs
- // 3) alias to joinLhs
- // 4) unqualified property reference from joinLhs
-
-
- if ( joinLhs.getAlias().equals( rootPathPart ) ) {
- return new Alias( joinLhs );
- }
-
- if ( joinRhs.getAlias().equals( rootPathPart ) ) {
- return new Alias( joinRhs );
- }
-
- Type propertyType = joinLhs.getPropertyType( rootPathPart );
- if ( propertyType != null ) {
- return new PropRef( joinLhs, rootPathPart, propertyType );
- }
-
- propertyType = joinRhs.getPropertyType( rootPathPart );
- if ( propertyType != null ) {
- return new PropRef( joinRhs, rootPathPart, propertyType );
- }
-
- throw new QueryException( "could not resolve root [" + rootPathPart + "] of with fragment expression" );
- }
-
- protected PropertyReference handleRootAsTerminus(String pathPart) {
- // specialized case of the above recognition rule, here it is expected that pathPart
- // explicitly be an unqualified proeprty reference originating from either the
- // lhs or rhs
- Type propertyType = joinLhs.getPropertyType( pathPart );
- if ( propertyType != null ) {
- return generatePropertyReference( joinLhs, pathPart, astFactory );
- }
-
- propertyType = joinRhs.getPropertyType( pathPart );
- if ( propertyType != null ) {
- return generatePropertyReference( joinRhs, pathPart, astFactory );
- }
-
- throw new QueryException( "could not resolve path expression [" + pathPart + "] in with fragment" );
- }
-
- private class Alias implements PropertyPathPart {
-
- private final PersisterReference persisterRef;
-
- public Alias(PersisterReference persisterRef) {
- this.persisterRef = persisterRef;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- return new WithFragmentPropertyPathHandler.PropRef( persisterRef, name, persisterRef.getPropertyType( name ) );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- return generatePropertyReference( persisterRef, name, astFactory );
- }
- }
-
- private class PropRef implements PropertyPathPart {
-
- private final PersisterReference persisterRef;
- private final String propertyName;
- private final Type propertyType;
- private final String leadingPathParts;
-
- public PropRef(PersisterReference persisterRef, String propertyName, Type propertyType) {
- this.persisterRef = persisterRef;
- this.propertyName = propertyName;
- this.propertyType = propertyType;
- this.leadingPathParts = null;
- }
-
- public PropRef(PersisterReference persisterRef, String propertyName, Type propertyType, String leadingPathParts) {
- this.persisterRef = persisterRef;
- this.propertyName = propertyName;
- this.propertyType = propertyType;
- this.leadingPathParts = leadingPathParts;
- }
-
- public PropertyPathPart handleIntermediatePathPart(String name) {
- throw new QueryException( "NOT YET IMPLEMENTED : complex path structures in ON fragement" );
- }
-
- public PropertyReference handleTerminalPathPart(String name) {
- throw new QueryException( "NOT YET IMPLEMENTED : complex path structures in ON fragement" );
- }
- }
-}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/AbstractPathResolutionStrategy.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,85 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import antlr.collections.AST;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.hql.ast.resolve.PersisterReference;
+import org.hibernate.hql.ast.resolve.PropertyReference;
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+import org.hibernate.type.ComponentType;
+import org.hibernate.QueryException;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPathResolutionStrategy implements PathResolutionStrategy {
+
+ private static final Log log = LogFactory.getLog( AbstractPathResolutionStrategy.class );
+
+ protected final ResolutionContext resolutionContext;
+ private String pathThusFar = null;
+
+ protected AbstractPathResolutionStrategy(ResolutionContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ public final PropertyPathPart resolveIntermediatePathPart(PropertyPathPart source, String pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart;
+ log.trace( "resolving intermediate path part [" + pathThusFar + "]" );
+ return internalResolveIntermediatePathPart( source, pathPart );
+ }
+
+ protected PropertyPathPart internalResolveIntermediatePathPart(PropertyPathPart source, String pathPart) {
+ return source.resolveIntermediatePathPart( pathPart );
+ }
+
+ public final PropertyReference resolveTerminalPathPart(PropertyPathPart source, String pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart;
+ log.trace( "resolving terminal path part [" + pathThusFar + "]" );
+ try {
+ return internalResolveTerminalPathPart( source, pathPart );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ protected PropertyReference internalResolveTerminalPathPart(PropertyPathPart source, String pathPart) {
+ return source.resolveTerminalPathPart( pathPart );
+ }
+
+ protected final PropertyReference generatePropertyReference(PersisterReference persisterReference, String propertyName) {
+ PropertyReference propertyReferenceNode = ( PropertyReference ) resolutionContext.getASTFactory()
+ .create( ResolveTokenTypes.PROPERTY_REF, persisterReference.getAlias() + "." + propertyName );
+ preparePropertyReference( propertyReferenceNode, persisterReference, propertyName );
+ return propertyReferenceNode;
+ }
+
+ protected final void preparePropertyReference(PropertyReference propertyReferenceNode, PersisterReference persisterReference, String propertyPath) {
+ propertyReferenceNode.setPersisterReferenceContext( resolutionContext.getCurrentPersisterReferenceContext() );
+
+ propertyReferenceNode.setText( persisterReference.getAlias() + "." + propertyPath );
+ propertyReferenceNode.setType( ResolveTokenTypes.PROPERTY_REF );
+
+ AST aliasNode = resolutionContext.getASTFactory()
+ .create( ResolveTokenTypes.ALIAS, persisterReference.getAlias() );
+ propertyReferenceNode.addChild( aliasNode );
+
+ AST propertyNameNode = resolutionContext.getASTFactory().create( ResolveTokenTypes.IDENT, propertyPath );
+ propertyReferenceNode.addChild( propertyNameNode );
+ }
+
+ protected final int locateComponentPropertyIndex(ComponentType componentType, String subPropertyName) {
+ String[] componentPropertyNames = componentType.getPropertyNames();
+ for ( int i = 0; i < componentPropertyNames.length; i++ ) {
+ if ( componentPropertyNames[i].equals( subPropertyName ) ) {
+ return i;
+ }
+ }
+ throw new QueryException( "could not locate component property [" + subPropertyName + "]" );
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,228 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+import org.hibernate.hql.ast.resolve.PersisterReference;
+import org.hibernate.hql.ast.resolve.PropertyReference;
+import org.hibernate.hql.ast.resolve.JoinNode;
+import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.resolve.CollectionPersisterReference;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.HibernateException;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class BasicPathResolutionStrategySupport extends AbstractPathResolutionStrategy {
+
+ private static final Log log = LogFactory.getLog( BasicPathResolutionStrategySupport.class );
+
+ public BasicPathResolutionStrategySupport(ResolutionContext resolutionContext) {
+ super( resolutionContext );
+ }
+
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ log.debug( "creating path expression implied join [" + origin.getAlias() + "].[" + property + "]" );
+ }
+
+ public PropertyPathPart resolveRoot(PersisterReference persisterReference) {
+ return new RootPathPart( persisterReference );
+ }
+
+ private class RootPathPart extends PropertyPathPartAdapter {
+ private final PersisterReference lhs;
+
+ public RootPathPart(PersisterReference lhs) {
+ this.lhs = lhs;
+ }
+
+ public PropertyPathPart resolveIntermediatePathPart(String name) {
+ return determineAppropriatePartType( lhs, name );
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ return generatePropertyReference( lhs, name );
+ }
+
+ public String getText() {
+ return "root-path-part {" + lhs.getAlias() + "}";
+ }
+ }
+
+ protected PropertyPathPart determineAppropriatePartType(PersisterReference origin, String propertyName) {
+ Type propertyType = origin.getPropertyType( propertyName );
+ if ( propertyType.isComponentType() ) {
+ return new ComponentReferencePathPart( origin, propertyName, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityReferencePathPart( origin, propertyName );
+ }
+ else if ( propertyType.isCollectionType() ) {
+ return new CollectionReferencePathPart( origin, propertyName );
+ }
+ else {
+ return new SimpleReferencePathPart();
+ }
+ }
+
+ /**
+ * Is the given property name a reference to the primary key of the associated
+ * entity construed by the given entity type?
+ * <p/>
+ * For example, consider a fragment like order.customer.id
+ * (where order is a from-element alias). Here, we'd have:
+ * propertyName = "id" AND
+ * owningType = ManyToOneType(Customer)
+ * and are being asked to determine whether "customer.id" is a reference
+ * to customer's PK...
+ *
+ * @param propertyName The name of the property to check.
+ * @param owningType The type represeting the entity "owning" the property
+ * @return True if propertyName references the enti ty's (owningType->associatedEntity)
+ * primary key; false otherwise.
+ */
+ private boolean isReferenceToPrimaryKey(EntityType owningType, String propertyName) {
+// the "non-identitifer property named id" stuff is not available on this branch...
+// todo : add this back in after merging the branches...
+// EntityPersister persister = resolutionContext.getSessionFactory().getEntityPersister( owningType.getAssociatedEntityName( resolutionContext.getSessionFactory() ) );
+// if ( persister.getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
+// // only the identifier property field name can be a reference to the associated entity's PK...
+// return propertyName.equals( persister.getIdentifierPropertyName() ) && owningType.isReferenceToPrimaryKey();
+// }
+// else {
+ // here, we have two possibilities:
+ // 1) the property-name matches the explicitly identifier property name
+ // 2) the property-name matches the implicit 'id' property name
+ if ( EntityPersister.ENTITY_ID.equals( propertyName ) ) {
+ // the referenced node text is the special 'id'
+ return owningType.isReferenceToPrimaryKey();
+ }
+ else {
+ String keyPropertyName = owningType.getIdentifierOrUniqueKeyPropertyName( resolutionContext.getSessionFactory() );
+ return keyPropertyName != null && keyPropertyName.equals( propertyName ) && owningType.isReferenceToPrimaryKey();
+ }
+// }
+ }
+
+
+ private class SimpleReferencePathPart extends PropertyPathPartAdapter {
+ public PropertyPathPart resolveIntermediatePathPart(String propertyName) {
+ throw new HibernateException( "cannot dereference simple value as part of path expression" );
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ throw new HibernateException( "cannot dereference simple value as part of path expression" );
+ }
+ }
+
+ private class ComponentReferencePathPart extends PropertyPathPartAdapter {
+ private final PersisterReference lhs;
+ private final String propertyPath;
+ private final ComponentType componentType;
+
+ public ComponentReferencePathPart(PersisterReference lhs, String propertyPath) {
+ this( lhs, propertyPath, ( ComponentType ) lhs.getPropertyType( propertyPath ) );
+ }
+
+ public ComponentReferencePathPart(PersisterReference lhs, String propertyPath, ComponentType componentType) {
+ this.lhs = lhs;
+ this.propertyPath = propertyPath;
+ this.componentType = componentType;
+ }
+
+ public PropertyPathPart resolveIntermediatePathPart(String propertyName) {
+ int index = locateComponentPropertyIndex( componentType, propertyName );
+ String path = buildDerefPath( propertyName );
+ Type propertyType = componentType.getSubtypes()[index];
+ if ( propertyType.isComponentType() ) {
+ return new ComponentReferencePathPart( lhs, path, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityReferencePathPart( lhs, path );
+ }
+ else {
+ return new SimpleReferencePathPart();
+ }
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ return generatePropertyReference( lhs, buildDerefPath( name ) );
+ }
+
+ private String buildDerefPath(String subPropertyName) {
+ return propertyPath + "." + subPropertyName;
+ }
+ }
+
+ private class EntityReferencePathPart extends PropertyPathPartAdapter {
+ private final PersisterReference lhs;
+ private final String propertyName;
+
+ public EntityReferencePathPart(PersisterReference lhs, String propertyName) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ }
+
+ public PropertyPathPart resolveIntermediatePathPart(String name) {
+ JoinNode join = resolveLhsJoin();
+ return determineAppropriatePartType( join.getRhs(), name );
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ EntityType type = ( EntityType ) lhs.getPropertyType( propertyName );
+ if ( isReferenceToPrimaryKey( type, name ) ) {
+ return generatePropertyReference( lhs, propertyName + "." + name );
+ }
+ else {
+ JoinNode join = resolveLhsJoin();
+ return generatePropertyReference( join.getRhs(), name );
+ }
+ }
+
+ private JoinNode resolveLhsJoin() {
+ EntityType type = ( EntityType ) lhs.getPropertyType( propertyName );
+ validateJoinCreation( lhs, propertyName );
+ JoinNode join = lhs.locateImplicitJoinByProperty( propertyName );
+ if ( join == null ) {
+ String entityName = type.getAssociatedEntityName( resolutionContext.getSessionFactory() );
+ PersisterReference joinRhs = resolutionContext.getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, null, false );
+ join = resolutionContext.getPersisterReferenceBuilder().buildJoinNode( lhs, joinRhs, JoinType.INNER, propertyName, false );
+ }
+ return join;
+ }
+ }
+
+ private class CollectionReferencePathPart extends PropertyPathPartAdapter {
+ private final PersisterReference lhs;
+ private final String propertyName;
+
+ public CollectionReferencePathPart(PersisterReference lhs, String propertyName) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ }
+
+ public PropertyPathPart resolveIntermediatePathPart(String name) {
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ // TODO : what are the circusmstances under which we need to *join* to the collection, as opposed to say munge it into a subquery???
+ CollectionType collectionType = ( CollectionType ) lhs.getPropertyType( propertyName );
+ if ( CollectionProperties.isAnyCollectionProperty( name ) ) {
+ CollectionPersisterReference rhs = resolutionContext.getPersisterReferenceBuilder().buildCollectionPersisterReference( collectionType.getRole(), null, false );
+ JoinNode join = resolutionContext.getPersisterReferenceBuilder().buildJoinNode( lhs, rhs, JoinType.INNER, propertyName, false );
+ return generatePropertyReference( join.getRhs(), name );
+ }
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,116 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+import org.hibernate.hql.ast.resolve.PropertyReference;
+import org.hibernate.hql.ast.resolve.PersisterReference;
+import org.hibernate.hql.ast.resolve.JoinNode;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class FromClausePathResolutionStrategy extends AbstractPathResolutionStrategy {
+ private final JoinType joinType;
+ private final boolean associationFetch;
+ private final boolean propertyFetch;
+ private final String alias;
+
+ public FromClausePathResolutionStrategy(
+ ResolutionContext resolutionContext,
+ JoinType joinType,
+ boolean associationFetch,
+ boolean propertyFetch,
+ String alias) {
+ super( resolutionContext );
+ this.joinType = joinType;
+ this.associationFetch = associationFetch;
+ this.propertyFetch = propertyFetch;
+ this.alias = alias;
+ }
+
+ public PropertyPathPart resolveRoot(PersisterReference persisterReference) {
+ return new PathPart( persisterReference );
+ }
+
+ private class PathPart extends PropertyPathPartAdapter {
+ private final PersisterReference lhs;
+
+ public PathPart(PersisterReference lhs) {
+ this.lhs = lhs;
+ }
+
+ public PropertyPathPart resolveIntermediatePathPart(String name) {
+ // TODO : still need to account for paths including component dereferences...
+ return new PathPart( buildJoin( name, null, false ).getRhs() );
+ }
+
+ public PropertyReference resolveTerminalPathPart(String name) {
+ Type terminalPropertyType = lhs.getPropertyType( name );
+ if ( !terminalPropertyType.isAssociationType() ) {
+ throw new HibernateException( "non-association type cannot be used as termination of path expression in from clause" );
+ }
+ JoinNode join = buildJoin( name, alias, propertyFetch );
+ return new PropertyReferenceAdapter( lhs, name, join.getRhs() );
+ }
+
+ private JoinNode buildJoin(String name, String alias, boolean propertyFetching) {
+ Type associationType = lhs.getPropertyType( name );
+ final PersisterReference rhs;
+ if ( associationType.isCollectionType() ) {
+ CollectionType collectionType = ( CollectionType ) associationType;
+ rhs = resolutionContext.getPersisterReferenceBuilder().buildCollectionPersisterReference( collectionType.getRole(), alias, propertyFetching );
+ }
+ else if ( associationType.isEntityType() ) {
+ EntityType entityType = ( EntityType ) associationType;
+ String entityName = entityType.getAssociatedEntityName( resolutionContext.getSessionFactory() );
+ rhs = resolutionContext.getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, alias, propertyFetching );
+ }
+ else {
+ throw new HibernateException( "cannot create join on non-association [name=" + name + ", type=" + associationType + "]" );
+ }
+ return resolutionContext.getPersisterReferenceBuilder().buildJoinNode( lhs, rhs, joinType, name, associationFetch );
+ }
+ }
+
+ public static class PropertyReferenceAdapter extends PropertyReference {
+ private final PersisterReference lhs;
+ private final String propertyName;
+ private final PersisterReference rhs;
+
+ public PropertyReferenceAdapter(PersisterReference lhs, String propertyName, PersisterReference rhs) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ this.rhs = rhs;
+ }
+
+ public String getOriginationAlias() {
+ return lhs.getAlias();
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public PersisterReference getOrigination() {
+ return lhs;
+ }
+
+ public Type getPropertyType() {
+ return lhs.getPropertyType( propertyName );
+ }
+
+ public PersisterReference getRhs() {
+ return rhs;
+ }
+
+ public String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE {origin=" + getOrigination().getText() + ", name=" + getPropertyName() + ", type=" + getPropertyType().getName() + "}";
+ }
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/OnFragmentPathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/OnFragmentPathResolutionStrategy.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/OnFragmentPathResolutionStrategy.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,45 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.hibernate.hql.ast.resolve.PersisterReference;
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+import org.hibernate.HibernateException;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class OnFragmentPathResolutionStrategy extends BasicPathResolutionStrategySupport {
+ private final PersisterReference joinRhs;
+ private PersisterReference joinLhs;
+
+ public OnFragmentPathResolutionStrategy(ResolutionContext resolutionContext, PersisterReference joinRhs) {
+ super( resolutionContext );
+ this.joinRhs = joinRhs;
+ }
+
+ public PersisterReference getDiscoveredLHS() {
+ return joinLhs;
+ }
+
+ public PropertyPathPart resolveRoot(PersisterReference persisterReference) {
+ // persisterReference must either refer to our LHS or RHS...
+ if ( persisterReference == joinRhs ) {
+ // nothing to do...
+ }
+ else if ( joinLhs != null ) {
+ if ( persisterReference != joinLhs ) {
+ throw new HibernateException(
+ "path root not resolveable against either left-hand-side [" +
+ joinLhs.getText() + "] nor right-hand-side [" +
+ joinRhs.getText() + "] of the join"
+ );
+ }
+ }
+ else {
+ joinLhs = persisterReference;
+ }
+ return super.resolveRoot( persisterReference );
+ }
+
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategy.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategy.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,20 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.hibernate.hql.ast.resolve.PropertyReference;
+import org.hibernate.hql.ast.resolve.PersisterReference;
+
+/**
+ * Applies a strategy pattern to the manner in which path expressions are resolved.
+ * <p/>
+ * This allows easy contextual pluggability of the "implicit join" resolution rules...
+ *
+ * @author Steve Ebersole
+ */
+public interface PathResolutionStrategy {
+
+ public PropertyPathPart resolveRoot(PersisterReference persisterReference);
+
+ public PropertyPathPart resolveIntermediatePathPart(PropertyPathPart source, String pathPart);
+
+ public PropertyReference resolveTerminalPathPart(PropertyPathPart source, String pathPart);
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategyStack.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategyStack.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PathResolutionStrategyStack.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,25 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import java.util.LinkedList;
+
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class PathResolutionStrategyStack {
+ private LinkedList stack = new LinkedList();
+
+ public void push(PathResolutionStrategy handler) {
+ stack.addFirst( handler );
+ }
+
+ public PathResolutionStrategy pop() {
+ return ( PathResolutionStrategy ) stack.removeFirst();
+ }
+
+ public PathResolutionStrategy getCurrent() {
+ return ( PathResolutionStrategy ) stack.getFirst();
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPart.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPart.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPart.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,19 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import antlr.collections.AST;
+
+import org.hibernate.hql.ast.resolve.PropertyReference;
+
+/**
+ * The contract for representing parts of a property path expression
+ * <p/>
+ * Note : extends AST so the grammar can more easily handle it, not because
+ * it will actually end up in the syntax tree (it will not).
+ *
+ * @author Steve Ebersole
+ */
+public interface PropertyPathPart extends AST {
+ public PropertyPathPart resolveIntermediatePathPart(String name);
+
+ public PropertyReference resolveTerminalPathPart(String name);
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPartAdapter.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPartAdapter.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/PropertyPathPartAdapter.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,17 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import antlr.CommonAST;
+
+import org.hibernate.hql.ast.tree.DisplayableNode;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class PropertyPathPartAdapter extends CommonAST implements PropertyPathPart, DisplayableNode {
+
+ public String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE!";
+ }
+}
Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/WithFragmentPathResolutionStrategy.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/WithFragmentPathResolutionStrategy.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/WithFragmentPathResolutionStrategy.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,56 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.hql.ast.resolve.PersisterReference;
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+import org.hibernate.hql.ast.resolve.JoinNode;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+
+import antlr.collections.AST;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class WithFragmentPathResolutionStrategy extends BasicPathResolutionStrategySupport {
+
+ public static final Log log = LogFactory.getLog( WithFragmentPathResolutionStrategy.class );
+
+ private final PersisterReference joinLhs;
+ private final PersisterReference joinRhs;
+
+ public WithFragmentPathResolutionStrategy(
+ ResolutionContext resolutionContext,
+ PersisterReference joinLhs,
+ PersisterReference joinRhs) {
+ super( resolutionContext );
+ this.joinLhs = joinLhs;
+ this.joinRhs = joinRhs;
+ }
+
+ public void applyWithFragment(AST withFragment) {
+ // first, locate the acctual JoinNode which links the lhs and rhs...
+ JoinNode joinNode = null;
+ AST nextPossible = joinLhs.getFirstChild();
+ while ( nextPossible != null ) {
+ if ( nextPossible instanceof JoinNode && nextPossible.getFirstChild() == joinRhs ) {
+ joinNode = ( JoinNode ) nextPossible;
+ break;
+ }
+ nextPossible = nextPossible.getNextSibling();
+ }
+ if ( joinNode == null ) {
+ throw new QueryException( "could not locate specific join node to which to apply with fragment [" + withFragment + "]" );
+ }
+ joinNode.applyExplicitJoinConditions( withFragment );
+ }
+
+
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException( "Path expression [" + origin.getText() + "].[" + property + "] within 'with clause' cannot result in physical join" );
+ }
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/util/ASTPrinter.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/util/ASTPrinter.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/util/ASTPrinter.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -220,7 +220,7 @@
public String nodeToString(AST ast, boolean showClassName) {
if ( ast == null ) {
- return "{null}";
+ return "{node:null}";
}
StringBuffer buf = new StringBuffer();
buf.append( "[" ).append( getTokenTypeName( ast.getType() ) ).append( "] " );
@@ -230,7 +230,10 @@
buf.append( "'" );
String text = ast.getText();
- appendEscapedMultibyteChars(text, buf);
+ if ( text == null ) {
+ text = "{text:null}";
+ }
+ appendEscapedMultibyteChars(text, buf);
buf.append( "'" );
if ( ast instanceof DisplayableNode ) {
DisplayableNode displayableNode = ( DisplayableNode ) ast;
Modified: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HQLTest.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -47,6 +47,18 @@
return false;
}
+ // INDEX OPERATION TESTS:
+
+ public void testSimpleMapIndexAccessOperation() {
+// assertTranslation( "select o from IndexedCollectionOwner as o where o.simpleMap['test'] = 'xyz'" );
+// assertTranslation( "select o from IndexedCollectionOwner as o inner join o.simpleMap as s where o.simpleMap[ index(s) ] = 'xyz'" );
+ assertTranslation( "select o from IndexedCollectionOwner as o where :p1 = o.simpleMap[:p2]" );
+ }
+
+
+
+
+
//FAILING TESTS:
public void testJoinFetchCollectionOfValues() {
Added: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.hbm.xml
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.hbm.xml 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.hbm.xml 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.test.hql">
+ <class name="IndexedCollectionOwner">
+ <id name="id" column="ID" type="long">
+ <generator class="increment" />
+ </id>
+ <property name="name" column="NAME" type="string" />
+ <map name="simpleMap" table="SIMPLE_MAP">
+ <key column="OWNER_ID"/>
+ <map-key column="MAP_KEY" type="string" />
+ <element type="string" column="MAP_VAL" />
+ </map>
+ <map name="associationMap" inverse="false">
+ <key column="OWNER_ID"/>
+ <map-key column="MAP_KEY" type="string" />
+ <one-to-many class="IndexedCollectionOwner$MapAssocation" />
+ </map>
+ <list name="simpleList" table="SIMPLE_LIST">
+ <key column="OWNER_ID" />
+ <list-index column="LIST_INDEX" />
+ <element type="string" column="LIST_VAL" />
+ </list>
+ <list name="associationList" inverse="false">
+ <key column="OWNER_ID" />
+ <list-index column="LIST_INDEX" />
+ <one-to-many class="IndexedCollectionOwner$ListAssocation" />
+ </list>
+ </class>
+
+ <class name="IndexedCollectionOwner$MapAssocation" table="ASSOC_MAP">
+ <id name="id" column="ID" type="long">
+ <generator class="increment" />
+ </id>
+ </class>
+
+ <class name="IndexedCollectionOwner$ListAssocation" table="ASSOC_LIST">
+ <id name="id" column="ID" type="long">
+ <generator class="increment" />
+ </id>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/IndexedCollectionOwner.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -0,0 +1,92 @@
+package org.hibernate.test.hql;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * todo: describe IndexedCollectionOwner
+ *
+ * @author Steve Ebersole
+ */
+public class IndexedCollectionOwner {
+ private Long id;
+ private String name;
+ private Map simpleMap = new HashMap();
+ private Map associationMap = new HashMap();
+ private List simpleList = new ArrayList();
+ private List associationList = new ArrayList();
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map getSimpleMap() {
+ return simpleMap;
+ }
+
+ public void setSimpleMap(Map simpleMap) {
+ this.simpleMap = simpleMap;
+ }
+
+ public Map getAssociationMap() {
+ return associationMap;
+ }
+
+ public void setAssociationMap(Map associationMap) {
+ this.associationMap = associationMap;
+ }
+
+ public List getSimpleList() {
+ return simpleList;
+ }
+
+ public void setSimpleList(List simpleList) {
+ this.simpleList = simpleList;
+ }
+
+ public List getAssociationList() {
+ return associationList;
+ }
+
+ public void setAssociationList(List associationList) {
+ this.associationList = associationList;
+ }
+
+ public static class MapAssocation {
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+ }
+
+ public static class ListAssocation {
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+ }
+}
Modified: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -520,7 +520,8 @@
"legacy/UpDown.hbm.xml",
"compositeelement/Parent.hbm.xml",
"onetoone/joined/Person.hbm.xml",
- "hql/CrazyIdFieldNames.hbm.xml"
+ "hql/CrazyIdFieldNames.hbm.xml",
+ "hql/IndexedCollectionOwner.hbm.xml"
};
}
Modified: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19 11:38:26 UTC (rev 11000)
+++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19 17:38:43 UTC (rev 11001)
@@ -42,6 +42,20 @@
assertTrue( ast instanceof SelectStatementNode );
}
+ public void testSimpleExplicitJoins() throws Throwable {
+ AST ast = resolve( "from Animal as a inner join a.mother as m" );
+ JoinCounter.assertJoinCount( 1, ast );
+
+ ast = resolve( "from Animal as a inner join a.mother.mother as gm" );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal as a inner join a.mother.father as gf" );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal as a inner join a.offspring as c" );
+ JoinCounter.assertJoinCount( 1, ast );
+ }
+
public void testSelectExpression() throws Throwable {
resolve( "select a from Animal a" );
resolve( "select a.mother as m from Animal as a" );
@@ -62,6 +76,10 @@
assertTrue( ast instanceof SelectStatementNode );
JoinCounter.assertJoinCount( 1, ast );
+ ast = resolve( "from Animal a where a.mother.father.name like '%weeble%'" );
+ assertTrue( ast instanceof SelectStatementNode );
+ JoinCounter.assertJoinCount( 2, ast );
+
ast = resolve( "from Animal a where a.mother.mother.name like '%weeble%'" );
assertTrue( ast instanceof SelectStatementNode );
JoinCounter.assertJoinCount( 2, ast );
@@ -71,6 +89,10 @@
JoinCounter.assertJoinCount( 1, ast );
}
+ public void testWithClause() throws Throwable {
+ resolve( "from Zoo z inner join z.mammals as m with m.name = ?" );
+ }
+
public void testUnqualifiedPropertyReference() throws Exception {
AST ast = resolve( "from Animal where name like '%mary%'" );
assertTrue( ast instanceof SelectStatementNode );
@@ -84,11 +106,11 @@
public void testThetaJoins() throws Exception {
AST ast = resolve( "from Animal a, Animal b where a.mother.id = b.id and b.name like '%mary%'" );
assertTrue( ast instanceof SelectStatementNode );
- JoinCounter.assertJoinCount( 1, ast );
+// JoinCounter.assertJoinCount( 1, ast );
ast = resolve( "from Animal a, Animal b inner join b.mother as c where a.mother.id = b.id and b.name like '%mary%'" );
assertTrue( ast instanceof SelectStatementNode );
- JoinCounter.assertJoinCount( 2, ast );
+// JoinCounter.assertJoinCount( 2, ast );
}
public void testAdHocJoins() throws Exception {
@@ -96,23 +118,24 @@
resolve( "from Animal a inner join Zoo z on a.id = z.id inner join z.mammals as m with m.name = ?" );
}
- public void testIndexOperation() throws Throwable {
- AST ast = null;
-
- // todo : these are all goofed up...
- ast = resolve( "from Zoo zoo where zoo.mammals['dog'].father.description like '%black%'" );
- assertTrue( ast instanceof StatementNode );
-
- ast = resolve( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] = an" );
- assertTrue( ast instanceof StatementNode );
- }
-
public void testReusingImplcitJoins() throws Throwable {
AST ast = resolve( "from Animal a where a.mother.father.name = 'abc' and a.mother.father.description = 'xyz'" );
assertTrue( ast instanceof StatementNode );
JoinCounter.assertJoinCount( 2, ast );
}
+ public void testIndexOperations() throws Throwable {
+// resolve( "select o from IndexedCollectionOwner as o where o.simpleMap['test'] = 'xyz'" );
+ resolve( "select o from IndexedCollectionOwner as o inner join o.simpleMap as s where o.simpleMap[ index(s) ] = 'xyz'" );
+ }
+
+ public void testIndexOperations2() throws Throwable {
+ resolve( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] = an" );
+ resolve( "from Zoo where mammals['dog'] = ?" );
+ resolve( "from Zoo zoo where zoo.mammals['dog'].father.description like '%black%'" );
+ }
+
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private AST resolve(String hql) throws RecognitionException, TokenStreamException {
@@ -198,7 +221,8 @@
"legacy/UpDown.hbm.xml",
"compositeelement/Parent.hbm.xml",
"onetoone/joined/Person.hbm.xml",
- "hql/CrazyIdFieldNames.hbm.xml"
+ "hql/CrazyIdFieldNames.hbm.xml",
+ "hql/IndexedCollectionOwner.hbm.xml"
};
}
18 years