Hibernate SVN: r16392 - in search/branches/Branch_3_1: src/java/org/hibernate/search/backend/impl and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-04-22 02:52:05 -0400 (Wed, 22 Apr 2009)
New Revision: 16392
Added:
search/branches/Branch_3_1/src/test/org/hibernate/search/test/engine/EventListenerSerializationTest.java
Removed:
search/branches/Branch_3_1/src/java/org/hibernate/search/event/IndexWorkFlushEventListener.java
Modified:
search/branches/Branch_3_1/doc/reference/en/modules/configuration.xml
search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java
search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java
search/branches/Branch_3_1/src/java/org/hibernate/search/event/EventListenerRegister.java
search/branches/Branch_3_1/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
search/branches/Branch_3_1/src/test/org/hibernate/search/test/TestCase.java
Log:
merging changes for HSEARCH-178 from trunk to branch 3.1
Modified: search/branches/Branch_3_1/doc/reference/en/modules/configuration.xml
===================================================================
--- search/branches/Branch_3_1/doc/reference/en/modules/configuration.xml 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/doc/reference/en/modules/configuration.xml 2009-04-22 06:52:05 UTC (rev 16392)
@@ -600,8 +600,8 @@
<para>To enable Hibernate Search in Hibernate Core (ie. if you don't use
Hibernate Annotations), add the
<literal>FullTextIndexEventListener</literal> for the following six
- Hibernate events and add the <literal>IndexWorkFlushEventListener</literal> after
- the default <literal>DefaultFlushEventListener</literal>, as in the following example.</para>
+ Hibernate events and also add it after the default
+ <literal>DefaultFlushEventListener</literal>, as in the following example.</para>
<example>
<title>Explicitly enabling Hibernate Search by configuring the
@@ -630,7 +630,7 @@
</event>
<event type="flush">
<listener class="org.hibernate.event.def.DefaultFlushEventListener"/>
- <listener class="org.hibernate.search.event.IndexWorkFlushEventListener"/>
+ <listener class="org.hibernate.search.event.FullTextIndexEventListener"/>
</event>
</session-factory>
</hibernate-configuration></programlisting>
Modified: search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/EventSourceTransactionContext.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -5,12 +5,12 @@
import javax.transaction.Synchronization;
-import org.hibernate.AssertionFailure;
import org.hibernate.Transaction;
import org.hibernate.event.EventSource;
import org.hibernate.event.FlushEventListener;
+import org.hibernate.search.SearchException;
import org.hibernate.search.backend.TransactionContext;
-import org.hibernate.search.event.IndexWorkFlushEventListener;
+import org.hibernate.search.event.FullTextIndexEventListener;
import org.hibernate.search.util.LoggerFactory;
import org.slf4j.Logger;
@@ -26,7 +26,9 @@
private static final Logger log = LoggerFactory.make();
private final EventSource eventSource;
- private final IndexWorkFlushEventListener flushListener;
+
+ //this transient is required to break recursive serialization
+ private transient FullTextIndexEventListener flushListener;
//constructor time is too early to define the value of realTxInProgress,
//postpone it, otherwise doing
@@ -36,7 +38,7 @@
public EventSourceTransactionContext(EventSource eventSource) {
this.eventSource = eventSource;
- this.flushListener = findIndexWorkFlushEventListener();
+ this.flushListener = getIndexWorkFlushEventListener();
}
public Object getTransactionIdentifier() {
@@ -54,25 +56,32 @@
transaction.registerSynchronization( synchronization );
}
else {
+ //registerSynchronization is only called if isRealTransactionInProgress or if
+ // a flushListener was found; still we might need to find the listener again
+ // as it might have been cleared by serialization (is transient).
+ flushListener = getIndexWorkFlushEventListener();
if ( flushListener != null ) {
flushListener.addSynchronization( eventSource, synchronization );
}
else {
- //It appears we are flushing out of transaction and have no way to perform the index update
- //Not expected: see check in isTransactionInProgress()
- throw new AssertionFailure( "On flush out of transaction: IndexWorkFlushEventListener not registered" );
+ //shouldn't happen if the code about serialization is fine:
+ throw new SearchException( "AssertionFailure: flushListener not registered any more.");
}
}
}
- private IndexWorkFlushEventListener findIndexWorkFlushEventListener() {
+ private FullTextIndexEventListener getIndexWorkFlushEventListener() {
+ if ( this.flushListener != null) {
+ //for the "transient" case: might have been nullified.
+ return flushListener;
+ }
FlushEventListener[] flushEventListeners = eventSource.getListeners().getFlushEventListeners();
for (FlushEventListener listener : flushEventListeners) {
- if ( listener.getClass().equals( IndexWorkFlushEventListener.class ) ) {
- return (IndexWorkFlushEventListener) listener;
+ if ( listener.getClass().equals( FullTextIndexEventListener.class ) ) {
+ return (FullTextIndexEventListener) listener;
}
}
- log.debug( "No IndexWorkFlushEventListener was registered" );
+ log.debug( "No FullTextIndexEventListener was registered" );
return null;
}
@@ -81,7 +90,7 @@
//This is because we want to behave as "inTransaction" if the flushListener is registered.
public boolean isTransactionInProgress() {
// either it is a real transaction, or if we are capable to manage this in the IndexWorkFlushEventListener
- return isRealTransactionInProgress() || flushListener != null;
+ return getIndexWorkFlushEventListener() != null || isRealTransactionInProgress();
}
private boolean isRealTransactionInProgress() {
Modified: search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/PostTransactionWorkQueueSynchronization.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -15,6 +15,13 @@
* @author Emmanuel Bernard
*/
public class PostTransactionWorkQueueSynchronization implements Synchronization {
+
+ /**
+ * FullTextIndexEventListener is using a WeakIdentityHashMap<Session,Synchronization>
+ * So make sure all Synchronization implementations don't have any
+ * (direct or indirect) reference to the Session.
+ */
+
private final QueueingProcessor queueingProcessor;
private boolean consumed;
private final WeakIdentityHashMap queuePerTransaction;
Modified: search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/backend/impl/TransactionalWorker.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -30,8 +30,8 @@
private static final Logger log = LoggerFactory.make();
- //FIXME: discuss the next line! it looks like there actually is concurrent access
- //not a synchronized map since for a given transaction, we have not concurrent access
+ //this is being used from different threads, but doesn't need a
+ //synchronized map since for a given transaction, we have not concurrent access
protected final WeakIdentityHashMap<Object, Synchronization> synchronizationPerTransaction = new WeakIdentityHashMap<Object, Synchronization>();
private QueueingProcessor queueingProcessor;
Modified: search/branches/Branch_3_1/src/java/org/hibernate/search/event/EventListenerRegister.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/event/EventListenerRegister.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/event/EventListenerRegister.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -6,6 +6,7 @@
import org.slf4j.Logger;
import org.hibernate.event.EventListeners;
+import org.hibernate.event.FlushEventListener;
import org.hibernate.event.PostCollectionRecreateEventListener;
import org.hibernate.event.PostCollectionRemoveEventListener;
import org.hibernate.event.PostCollectionUpdateEventListener;
@@ -15,7 +16,6 @@
import org.hibernate.search.Environment;
import org.hibernate.search.util.LoggerFactory;
-
/**
* Helper methods initializing Hibernate Search event listeners.
*
@@ -94,13 +94,14 @@
new PostCollectionUpdateEventListener[] { searchListener }
)
);
- // Adding IndexWorkFlushEventListener to manage events out-of-transaction
- if ( ! isFlushEventListenerRegistered( listeners.getFlushEventListeners() ) ) {
- listeners.setFlushEventListeners( appendToArray(
- listeners.getFlushEventListeners(),
- new IndexWorkFlushEventListener()
- ) );
- }
+ // Adding also as FlushEventListener to manage events out-of-transaction
+ listeners.setFlushEventListeners(
+ addIfNeeded(
+ listeners.getFlushEventListeners(),
+ searchListener,
+ new FlushEventListener[] { searchListener }
+ )
+ );
}
/**
@@ -166,18 +167,4 @@
return false;
}
- /**
- * Verifies if an IndexWorkFlushEventListener is contained in the array of listeners.
- * @param listeners
- * @return true if it found in the listeners, false otherwise.
- */
- private static boolean isFlushEventListenerRegistered(Object[] listeners) {
- for ( Object eventListener : listeners ) {
- if ( IndexWorkFlushEventListener.class == eventListener.getClass() ) {
- return true;
- }
- }
- return false;
- }
-
}
Modified: search/branches/Branch_3_1/src/java/org/hibernate/search/event/FullTextIndexEventListener.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/event/FullTextIndexEventListener.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -1,15 +1,27 @@
//$Id$
package org.hibernate.search.event;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.Map;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
import org.slf4j.Logger;
+import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.EntityEntry;
import org.hibernate.event.AbstractCollectionEvent;
import org.hibernate.event.AbstractEvent;
import org.hibernate.event.Destructible;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.FlushEvent;
+import org.hibernate.event.FlushEventListener;
import org.hibernate.event.Initializable;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostCollectionRecreateEventListener;
@@ -28,6 +40,7 @@
import org.hibernate.search.backend.impl.EventSourceTransactionContext;
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.search.util.WeakIdentityHashMap;
/**
* This listener supports setting a parent directory for all generated index files.
@@ -36,20 +49,27 @@
* @author Gavin King
* @author Emmanuel Bernard
* @author Mattias Arbin
+ * @author Sanne Grinovero
*/
-//TODO work on sharing the same indexWriters and readers across a single post operation...
//TODO implement and use a LockableDirectoryProvider that wraps a DP to handle the lock inside the LDP
//TODO make this class final as soon as FullTextIndexCollectionEventListener is removed.
@SuppressWarnings( "serial" )
public class FullTextIndexEventListener implements PostDeleteEventListener,
PostInsertEventListener, PostUpdateEventListener,
PostCollectionRecreateEventListener, PostCollectionRemoveEventListener,
- PostCollectionUpdateEventListener, Initializable, Destructible {
+ PostCollectionUpdateEventListener, FlushEventListener, Initializable, Destructible {
private static final Logger log = LoggerFactory.make();
protected boolean used;
protected SearchFactoryImplementor searchFactoryImplementor;
+
+ //only used by the FullTextIndexEventListener instance playing in the FlushEventListener role.
+ // transient because it's not serializable (and state doesn't need to live longer than a flush).
+ // final because it's initialization should be published to other threads.
+ // ! update the readObject() method in case of name changes !
+ // make sure the Synchronization doesn't contain references to Session, otherwise we'll leak memory.
+ private transient final Map<Session,Synchronization> flushSynch = new WeakIdentityHashMap<Session,Synchronization>(0);
/**
* Initialize method called by Hibernate Core when the SessionFactory starts
@@ -157,4 +177,59 @@
}
return id;
}
+
+ /**
+ * Make sure the indexes are updated right after the hibernate flush,
+ * avoiding object loading during a flush. Not needed during transactions.
+ */
+ public void onFlush(FlushEvent event) {
+ if ( used ) {
+ Session session = event.getSession();
+ Synchronization synchronization = flushSynch.get( session );
+ if ( synchronization != null ) {
+ //first cleanup
+ flushSynch.remove( session );
+ log.debug( "flush event causing index update out of transaction" );
+ synchronization.beforeCompletion();
+ synchronization.afterCompletion( Status.STATUS_COMMITTED );
+ }
+ }
+ }
+
+ /**
+ * Adds a synchronization to be performed in the onFlush method;
+ * should only be used as workaround for the case a flush is happening
+ * out of transaction.
+ * Warning: if the synchronization contains a hard reference
+ * to the Session proper cleanup is not guaranteed and memory leaks
+ * will happen.
+ * @param eventSource should be the Session doing the flush
+ * @param synchronization
+ */
+ public void addSynchronization(EventSource eventSource, Synchronization synchronization) {
+ this.flushSynch.put( eventSource, synchronization );
+ }
+
+ /* Might want to implement AutoFlushEventListener in future?
+ public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
+ // Currently not needed as auto-flush is not happening
+ // when out of transaction.
+ }
+ */
+
+ private void writeObject(ObjectOutputStream os) throws IOException {
+ os.defaultWriteObject();
+ }
+
+ //needs to implement custom readObject to restore the transient fields
+ private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+ is.defaultReadObject();
+ Class<FullTextIndexEventListener> cl = FullTextIndexEventListener.class;
+ Field f = cl.getDeclaredField("flushSynch");
+ f.setAccessible( true );
+ Map<Session,Synchronization> flushSynch = new WeakIdentityHashMap<Session,Synchronization>(0);
+ // setting a final field by reflection during a readObject is considered as safe as in a constructor:
+ f.set( this, flushSynch );
+ }
+
}
Deleted: search/branches/Branch_3_1/src/java/org/hibernate/search/event/IndexWorkFlushEventListener.java
===================================================================
--- search/branches/Branch_3_1/src/java/org/hibernate/search/event/IndexWorkFlushEventListener.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/java/org/hibernate/search/event/IndexWorkFlushEventListener.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -1,61 +0,0 @@
-// $Id$
-package org.hibernate.search.event;
-
-import java.io.Serializable;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.FlushEvent;
-import org.hibernate.event.FlushEventListener;
-import org.hibernate.search.util.LoggerFactory;
-import org.slf4j.Logger;
-
-/**
- * FlushEventListener to make sure the indexes are updated right after the hibernate flush,
- * avoiding object loading during a flush. Not needed during transactions.
- *
- * @author Sanne Grinovero
- */
-public final class IndexWorkFlushEventListener implements FlushEventListener, Serializable {
-
- private static final Logger log = LoggerFactory.make();
-
- private final ConcurrentHashMap<Session, Synchronization> synchronizationPerTransaction
- = new ConcurrentHashMap<Session, Synchronization>();
-
- public IndexWorkFlushEventListener() {
- }
-
- public void onFlush(FlushEvent event) throws HibernateException {
- Session session = event.getSession();
- Synchronization synchronization = synchronizationPerTransaction.get( session );
- if ( synchronization != null ) {
- log.debug( "flush event causing index update out of transaction" );
- synchronizationPerTransaction.remove( session );
- synchronization.beforeCompletion();
- synchronization.afterCompletion( Status.STATUS_COMMITTED );
- }
- }
-
- public void addSynchronization(EventSource eventSource, Synchronization synchronization) {
- Synchronization previousSync = synchronizationPerTransaction.put( eventSource, synchronization );
- if ( previousSync != null ) {
- throw new AssertionFailure( "previous registered sync not discarded in IndexWorkFlushEventListener" );
- }
- }
-
- /*
- * Might want to implement AutoFlushEventListener in future?
- public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
- // Currently not needed as auto-flush is not happening
- // when out of transaction.
- }
- */
-
-}
Modified: search/branches/Branch_3_1/src/test/org/hibernate/search/test/TestCase.java
===================================================================
--- search/branches/Branch_3_1/src/test/org/hibernate/search/test/TestCase.java 2009-04-21 20:24:58 UTC (rev 16391)
+++ search/branches/Branch_3_1/src/test/org/hibernate/search/test/TestCase.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -15,7 +15,7 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.event.FlushEventListener;
import org.hibernate.event.def.DefaultFlushEventListener;
-import org.hibernate.search.event.IndexWorkFlushEventListener;
+import org.hibernate.search.event.FullTextIndexEventListener;
/**
* A modified base class for tests without annotations.
@@ -154,7 +154,7 @@
cfg.setListener( "post-collection-remove", "org.hibernate.search.event.FullTextIndexEventListener" );
cfg.setListener( "post-collection-update", "org.hibernate.search.event.FullTextIndexEventListener" );
- cfg.setListeners( "flush", new FlushEventListener[]{new DefaultFlushEventListener(), new IndexWorkFlushEventListener()} );
+ cfg.setListeners( "flush", new FlushEventListener[]{new DefaultFlushEventListener(), new FullTextIndexEventListener()} );
cfg.setProperty( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
cfg.setProperty( org.hibernate.search.Environment.ANALYZER_CLASS, StopAnalyzer.class.getName() );
Copied: search/branches/Branch_3_1/src/test/org/hibernate/search/test/engine/EventListenerSerializationTest.java (from rev 16306, search/trunk/src/test/java/org/hibernate/search/test/engine/EventListenerSerializationTest.java)
===================================================================
--- search/branches/Branch_3_1/src/test/org/hibernate/search/test/engine/EventListenerSerializationTest.java (rev 0)
+++ search/branches/Branch_3_1/src/test/org/hibernate/search/test/engine/EventListenerSerializationTest.java 2009-04-22 06:52:05 UTC (rev 16392)
@@ -0,0 +1,26 @@
+package org.hibernate.search.test.engine;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.hibernate.search.event.FullTextIndexEventListener;
+import org.hibernate.search.test.SerializationTestHelper;
+
+/**
+ * Tests that the FullTextIndexEventListener is Serializable
+ *
+ * @author Sanne Grinovero
+ */
+public class EventListenerSerializationTest extends TestCase {
+
+ public void testEventListenerSerializable() throws IOException, ClassNotFoundException {
+ FullTextIndexEventListener eventListener = new FullTextIndexEventListener();
+ eventListener.addSynchronization( null, null );
+ Object secondListener = SerializationTestHelper
+ .duplicateBySerialization(eventListener);
+ assertNotNull(secondListener);
+ assertFalse(secondListener == eventListener);
+ }
+
+}
15 years, 7 months
Hibernate SVN: r16391 - in core/branches/antlr3/src/main/java/org/hibernate/sql/ast: tree and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-04-21 16:24:58 -0400 (Tue, 21 Apr 2009)
New Revision: 16391
Added:
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/FromClausePathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/OnFragmentPathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/SelectClausePathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/WithFragmentPathResolutionStrategy.java
Modified:
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java
Log:
remainder of path resolution strategies
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java 2009-04-21 19:41:54 UTC (rev 16390)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -457,6 +457,18 @@
}
}
+ protected Table createJoin(PersisterSpace lhs, String propertyName, String alias) {
+ validateJoinable( lhs, propertyName );
+ Type propertyType = lhs.getPropertyType( propertyName );
+ if ( propertyType.isEntityType() ) {
+ return createJoin( lhs, resolveEntityPersister( lhs, propertyName ), alias );
+ }
+ else {
+ // assume collection because of validation of being joinable...
+ return createJoin( lhs, resolveCollectionPersister( lhs, propertyName ), alias, null );
+ }
+ }
+
protected Table createJoin(PersisterSpace lhs, Queryable entityPersister, String alias) {
EntityType entityType = entityPersister.getEntityMetamodel().getEntityType();
@@ -554,6 +566,16 @@
return collectionTableExpression;
}
+ protected void validateJoinable(PersisterSpace lhs, String propertyName) {
+ if ( ! isAssociation( lhs.getPropertyType( propertyName ) ) ) {
+ throw new InvalidPropertyJoinException( getPathThusFar(), lhs.getName(), propertyName );
+ }
+ }
+
+ protected boolean isAssociation(Type propertyType) {
+ return propertyType.isAssociationType();
+ }
+
protected void validateCollectionReference(PersisterSpace lhs, String propertyName) {
if ( ! isCollectionReference( lhs.getPropertyType( propertyName ) ) ) {
throw new CollectionExpectedException( getPathThusFar(), lhs.getName(), propertyName );
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/FromClausePathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/FromClausePathResolutionStrategy.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/FromClausePathResolutionStrategy.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -0,0 +1,125 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.hibernate.QueryException;
+import org.hibernate.sql.ast.common.HibernateTree;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.sql.ast.phase.hql.parse.HQLParser;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
+import org.hibernate.sql.ast.phase.hql.resolve.ResolutionContext;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.tree.Table;
+
+/**
+ *
+ * {@link org.hibernate.sql.ast.phase.hql.resolve.path.PathResolutionStrategy} for dealing with path expressions
+ * occuring in the <tt>FROM</tt> clause of a query.
+ *
+ * @author Steve Ebersole
+ */
+public class FromClausePathResolutionStrategy extends AbstractPathResolutionStrategy {
+ private final JoinType joinType;
+ private final boolean associationFetch;
+ private final boolean propertyFetch;
+ private final String alias;
+
+ /**
+ * Instantiate a normalization strategy for handling path expressions in a <tt>FROM</tt> clause.
+ *
+ * @param resolutionContext The context for resolution.
+ * @param joinType The type of explicit-join specified at the root of this path expression.
+ * @param associationFetch Was association fetching indicated on this path expression?
+ * @param propertyFetch Was property fetching indicated on this path expression?
+ * @param alias The alias (if one) specified on this joined path expression.
+ */
+ 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;
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterSpace persisterSpace) {
+ return new SourceImpl( persisterSpace );
+ }
+
+ private class SourceImpl extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace lhs;
+
+ private SourceImpl(PersisterSpace lhs) {
+ this.lhs = lhs;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ // TODO : still need to account for paths including component dereferences...
+ Table joinedTable = buildPropertyJoinedTable( lhs, name, null, false, associationFetch );
+ return new SourceImpl( joinedTable.getTableSpace().getPersisterSpace() );
+ }
+
+ public HibernateTree handleTerminalPathPart(String propertyName) {
+ validateJoinable( lhs, propertyName );
+
+ Table joinedTable = buildPropertyJoinedTable( lhs, propertyName, alias, propertyFetch, associationFetch );
+ return joinedTable.getTableSpace().buildIdentifierColumnReferences();
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ throw new UnsupportedOperationException( "index operation not supported in from clause" );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String name, HibernateTree selector) {
+ throw new UnsupportedOperationException( "index operation not supported in from clause" );
+ }
+ }
+
+ protected HibernateTree buildJoinTypeNode() {
+ if ( joinType == JoinType.INNER ) {
+ return new HibernateTree( HQLParser.INNER );
+ }
+ else if ( joinType == JoinType.LEFT ) {
+ return new HibernateTree( HQLParser.LEFT );
+ }
+ else if ( joinType == JoinType.RIGHT ) {
+ return new HibernateTree( HQLParser.RIGHT );
+ }
+ // if no match found, throw exception
+ throw new QueryException( "Unrecognized join type [" + joinType.toString() + "]" );
+ }
+
+ protected boolean areJoinsReusable() {
+ return false;
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/OnFragmentPathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/OnFragmentPathResolutionStrategy.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/OnFragmentPathResolutionStrategy.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
+import org.hibernate.sql.ast.phase.hql.resolve.ResolutionContext;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathedPropertyReferenceSource;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.resolve.path.PathResolutionStrategy} for dealing with path expressions
+ * occuring in the <tt>ON</tt> clause of a persister join.
+ *
+ * @author Steve Ebersole
+ */
+public class OnFragmentPathResolutionStrategy extends BasicPathResolutionStrategySupport {
+ private final PersisterSpace joinRhs;
+ private PersisterSpace joinLhs;
+
+ public OnFragmentPathResolutionStrategy(ResolutionContext resolutionContext, PersisterSpace joinRhs) {
+ super( resolutionContext );
+ this.joinRhs = joinRhs;
+ }
+
+ public PersisterSpace getDiscoveredLHS() {
+ return joinLhs;
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterSpace persisterSpace) {
+ // persisterSpace must either refer to our LHS or RHS...
+ if ( persisterSpace == joinRhs ) {
+ // nothing to do...
+ }
+ else if ( joinLhs != null ) {
+ if ( persisterSpace != joinLhs ) {
+ throw new HibernateException(
+ "path root not resolveable against either left-hand-side [" +
+ joinLhs.getSourceAlias() + "] nor right-hand-side [" +
+ joinRhs.getSourceAlias() + "] of the join"
+ );
+ }
+ }
+ else {
+ joinLhs = persisterSpace;
+ }
+ return super.internalHandleRoot( persisterSpace );
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/SelectClausePathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/SelectClausePathResolutionStrategy.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/SelectClausePathResolutionStrategy.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.hibernate.sql.ast.phase.hql.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...
+ * <p/>
+ * todo : the above is true as long as the path is not a function argument...
+ *
+ * @author Steve Ebersole
+ */
+public class SelectClausePathResolutionStrategy extends BasicPathResolutionStrategySupport {
+ public SelectClausePathResolutionStrategy(ResolutionContext resolutionContext) {
+ super( resolutionContext );
+ }
+
+ protected boolean shouldTerminalEntityPropertyForceJoin() {
+ // here we should *as long as* we are not part of a function processing
+ return ! resolutionContext().isCurrentlyProcessingFunction();
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/WithFragmentPathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/WithFragmentPathResolutionStrategy.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/WithFragmentPathResolutionStrategy.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -0,0 +1,125 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
+import org.hibernate.sql.ast.phase.hql.resolve.ResolutionContext;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.common.HibernateTree;
+import org.hibernate.sql.ast.tree.Table;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.resolve.path.PathResolutionStrategy} for dealing with <tt>WITH</tt>
+ * fragments used to supply addition join conditions to property joins.
+ *
+ * @author Steve Ebersole
+ */
+public class WithFragmentPathResolutionStrategy extends BasicPathResolutionStrategySupport {
+ private final PersisterSpace lhs;
+
+ private String baseRhsPropertyName;
+ private PersisterSpace rhs;
+
+ public WithFragmentPathResolutionStrategy(ResolutionContext resolutionContext, PersisterSpace lhs) {
+ super( resolutionContext );
+ this.lhs = lhs;
+ }
+
+ @Override
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterSpace persisterSpace) {
+ rhs = persisterSpace;
+ return super.internalHandleRoot( persisterSpace );
+ }
+
+ @Override
+ protected PathedPropertyReferenceSource internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, String pathPart) {
+ if ( baseRhsPropertyName == null ) {
+ baseRhsPropertyName = pathPart;
+ }
+ return super.internalResolveIntermediatePathPart( source, pathPart );
+ }
+
+ @Override
+ protected HibernateTree internalResolveTerminalPathPart(PathedPropertyReferenceSource source, String pathPart) {
+ if ( baseRhsPropertyName == null ) {
+ baseRhsPropertyName = pathPart;
+ }
+ return super.internalResolveTerminalPathPart( source, pathPart );
+ }
+
+ @Override
+ protected PathedPropertyReferenceSource internalHandleIntermediateIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ if ( baseRhsPropertyName == null ) {
+ baseRhsPropertyName = pathPart;
+ }
+ return super.internalHandleIntermediateIndexAccess( source, pathPart, selector );
+ }
+
+ @Override
+ protected HibernateTree internalHandleTerminalIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ if ( baseRhsPropertyName == null ) {
+ baseRhsPropertyName = pathPart;
+ }
+ return super.internalHandleTerminalIndexAccess( source, pathPart, selector );
+ }
+
+ public void applyWithFragment(HibernateTree withFragment) {
+ // first, locate the actual Join node which links the lhs and rhs...
+ Table lhsTable = lhs.getTableSpace().getContainingTable( baseRhsPropertyName );
+
+ // todo : implement...
+
+ // as simple as finding the table under lhsTable which contains a join to a table from the table-space associated with
+ // the rhs persister-space???
+
+// Join join = null;
+// AST nextPossible = lhs.getFirstChild();
+// while ( nextPossible != null ) {
+// if ( nextPossible instanceof Join ) {
+// if ( ( ( Join ) nextPossible ).locateRhs() == rhs ) {
+// join = ( Join ) nextPossible;
+// break;
+// }
+// }
+// nextPossible = nextPossible.getNextSibling();
+// }
+// if ( join == null ) {
+// throw new QueryException( "could not locate specific join node to which to apply with fragment [" + withFragment + "]" );
+// }
+// join.addChild( withFragment );
+ }
+
+ protected void validateJoinCreation(PersisterSpace origin, String property) {
+ // todo : why not???
+ throw new HibernateException( "Path expressions [" + origin.getSourceAlias() + "." + property + "] within 'with clause' cannot result in physical join" );
+ }
+}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java 2009-04-21 19:41:54 UTC (rev 16390)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java 2009-04-21 20:24:58 UTC (rev 16391)
@@ -180,6 +180,10 @@
public void registerReusablePropertyJoinedTable(String propertyName, Table table) {
propertyToJoinedTableMap.put( propertyName, table );
}
+
+ public boolean contansProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
}
public static class EntityTableSpace extends AbstractTableSpace {
15 years, 7 months
Hibernate SVN: r16390 - core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-04-21 15:41:54 -0400 (Tue, 21 Apr 2009)
New Revision: 16390
Added:
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/HierarchicalPersisterSpaceContext.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/RootPersisterSpaceContext.java
Modified:
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java
Log:
persister space context impls
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/HierarchicalPersisterSpaceContext.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/HierarchicalPersisterSpaceContext.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/HierarchicalPersisterSpaceContext.java 2009-04-21 19:41:54 UTC (rev 16390)
@@ -0,0 +1,103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.resolve;
+
+/**
+ * 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 HierarchicalPersisterSpaceContext extends RootPersisterSpaceContext {
+ private final PersisterSpaceContext parent;
+
+ public HierarchicalPersisterSpaceContext(PersisterSpaceContext parent) {
+ super();
+ if ( parent == null ) {
+ throw new IllegalArgumentException( "Parent PersisterSpaceContext cannot be null!" );
+ }
+ this.parent = parent;
+ }
+
+ /**
+ * Get the parent context of this context.
+ *
+ * @return Our parent context.
+ */
+ public PersisterSpaceContext getParent() {
+ return parent;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public boolean isContainedAlias(String alias) {
+ return super.isContainedAlias( alias ) || getParent().isContainedAlias( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public boolean isContainedExposedProperty(String propertyName) {
+ return super.isContainedExposedProperty( propertyName ) || getParent().isContainedExposedProperty( propertyName );
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public PersisterSpace locatePersisterSpaceByAlias(String alias) {
+ PersisterSpace persisterSpace = super.locatePersisterSpaceByAlias( alias );
+ if ( persisterSpace == null ) {
+ persisterSpace = getParent().locatePersisterSpaceByAlias( alias );
+ }
+ return persisterSpace;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public PersisterSpace locatePersisterSpaceExposingProperty(String propertyName) {
+ PersisterSpace persisterSpace = super.locatePersisterSpaceExposingProperty( propertyName );
+ if ( persisterSpace == null ) {
+ persisterSpace = getParent().locatePersisterSpaceExposingProperty( propertyName );
+ }
+ return persisterSpace;
+ }
+}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java 2009-04-21 19:33:36 UTC (rev 16389)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java 2009-04-21 19:41:54 UTC (rev 16390)
@@ -61,6 +61,8 @@
public Table.TableSpace getTableSpace();
+ public boolean contansProperty(String propertyName);
+
public Type getPropertyType(String propertyName);
public Table locateReusablePropertyJoinedTable(String propertyName);
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/RootPersisterSpaceContext.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/RootPersisterSpaceContext.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/RootPersisterSpaceContext.java 2009-04-21 19:41:54 UTC (rev 16390)
@@ -0,0 +1,107 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.QueryException;
+
+/**
+ * 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.
+ *
+ * @author Steve Ebersole
+ */
+public class RootPersisterSpaceContext implements PersisterSpaceContext {
+ private static final Logger log = LoggerFactory.getLogger( RootPersisterSpaceContext.class );
+
+ private List<PersisterSpace> persisterSpaces = new ArrayList<PersisterSpace>();
+ private Map<String,PersisterSpace> aliasXref = new HashMap<String,PersisterSpace>();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void registerPersisterSpace(PersisterSpace persisterSpace) {
+ if ( persisterSpace.getSourceAlias() == null ) {
+ throw new IllegalArgumentException( "unexpected null persister-reference alias" );
+ }
+ persisterSpaces.add( persisterSpace );
+ aliasXref.put( persisterSpace.getSourceAlias(), persisterSpace );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isContainedAlias(String alias) {
+ return aliasXref.containsKey( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isContainedExposedProperty(String propertyName) {
+ // a matching alias always takes precedence...
+ return ( ! isContainedAlias( propertyName ) ) && locatePersisterSpaceExposingProperty( propertyName ) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterSpace locatePersisterSpaceByAlias(String alias) {
+ log.trace( "attempting to resolve [" + alias + "] as persister space alias" );
+ return aliasXref.get( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterSpace locatePersisterSpaceExposingProperty(String propertyName) {
+ log.trace( "attempting to resolve [" + propertyName + "] as unqualified property" );
+ PersisterSpace match = null;
+ for ( PersisterSpace persisterSpace : persisterSpaces ) {
+ if ( persisterSpace.contansProperty( propertyName ) ) {
+ if ( match != null ) {
+ // todo : better exception type
+ throw new QueryException( "multiple persisters contained property [" + propertyName + "]" );
+ }
+ match = persisterSpace;
+ }
+ }
+ return match;
+ }
+
+}
15 years, 7 months
Hibernate SVN: r16389 - validator/trunk and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-04-21 15:33:36 -0400 (Tue, 21 Apr 2009)
New Revision: 16389
Modified:
beanvalidation/trunk/validation-tck/impl/src/main/resources/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/validation.xml
validator/trunk/hibernate-validator-tck-runner/pom.xml
validator/trunk/hibernate-validator/pom.xml
validator/trunk/pom.xml
Log:
Setting up the framework for the TCK
Modified: beanvalidation/trunk/validation-tck/impl/src/main/resources/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/validation.xml
===================================================================
--- beanvalidation/trunk/validation-tck/impl/src/main/resources/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/validation.xml 2009-04-21 18:29:41 UTC (rev 16388)
+++ beanvalidation/trunk/validation-tck/impl/src/main/resources/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/validation.xml 2009-04-21 19:33:36 UTC (rev 16389)
@@ -2,5 +2,5 @@
<validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <default-provider>foo.Bar</default-provider>
+ <default-provider>org.hibernate.validation.engine.HibernateValidatorConfiguration</default-provider>
</validation-config>
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2009-04-21 18:29:41 UTC (rev 16388)
+++ validator/trunk/hibernate-validator/pom.xml 2009-04-21 19:33:36 UTC (rev 16389)
@@ -24,7 +24,6 @@
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
- <version>1.0.CR2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Modified: validator/trunk/hibernate-validator-tck-runner/pom.xml
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/pom.xml 2009-04-21 18:29:41 UTC (rev 16388)
+++ validator/trunk/hibernate-validator-tck-runner/pom.xml 2009-04-21 19:33:36 UTC (rev 16389)
@@ -13,6 +13,10 @@
<dependencies>
<dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${version}</version>
@@ -61,6 +65,25 @@
<classifier>suite</classifier>
<overWrite>true</overWrite>
</artifactItem>
+ <artifactItem>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/dependency/lib</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/dependency/lib</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <overWrite>true</overWrite>
+ <outputDirectory>${project.build.directory}/dependency/lib</outputDirectory>
+ </artifactItem>
+
</artifactItems>
</configuration>
</execution>
Modified: validator/trunk/pom.xml
===================================================================
--- validator/trunk/pom.xml 2009-04-21 18:29:41 UTC (rev 16388)
+++ validator/trunk/pom.xml 2009-04-21 19:33:36 UTC (rev 16389)
@@ -47,6 +47,11 @@
<dependencyManagement>
<dependencies>
<dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>1.0.CR2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.6</version>
15 years, 7 months
Hibernate SVN: r16388 - in core/branches/antlr3/src/main/java/org/hibernate: sql/ast/phase/hql/resolve and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-04-21 14:29:41 -0400 (Tue, 21 Apr 2009)
New Revision: 16388
Added:
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategyStack.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractUnexpectedPropertyTypeException.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/BasicPathResolutionStrategySupport.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/CollectionExpectedException.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/IndexedCollectionExectedException.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/InvalidPropertyJoinException.java
Modified:
core/branches/antlr3/src/main/java/org/hibernate/QueryException.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterTableExpressionGenerator.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/ResolutionContext.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategy.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathedPropertyReferenceSource.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java
Log:
initial path resolution
Modified: core/branches/antlr3/src/main/java/org/hibernate/QueryException.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/QueryException.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/QueryException.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -32,9 +32,14 @@
private String queryString;
+ protected QueryException() {
+ super( "<expecting override of message building>" );
+ }
+
public QueryException(String message) {
super(message);
}
+
public QueryException(String message, Throwable e) {
super(message, e);
}
@@ -47,6 +52,7 @@
public QueryException(Exception e) {
super(e);
}
+
public String getQueryString() {
return queryString;
}
@@ -56,11 +62,16 @@
}
public String getMessage() {
- String msg = super.getMessage();
- if ( queryString!=null ) msg += " [" + queryString + ']';
+ String msg = internalGetMessage();
+ if ( queryString != null ) {
+ msg += " [" + queryString + ']';
+ }
return msg;
}
+ protected String internalGetMessage() {
+ return super.getMessage();
+ }
}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterSpace.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -28,19 +28,41 @@
*/
package org.hibernate.sql.ast.phase.hql.resolve;
-import java.util.List;
-
-import org.antlr.runtime.tree.Tree;
-
import org.hibernate.type.Type;
+import org.hibernate.sql.ast.tree.Table;
/**
*
* @author Steve Ebersole
*/
public interface PersisterSpace {
- public String getAlias();
- public List<Tree> getTables();
+ /**
+ * Retrieve the corresponding alias from the input (HQL, etc).
+ *
+ * @return The source alias.
+ */
+ public String getSourceAlias();
+ /**
+ * Retrieve the name of the underlying persister.
+ *
+ * @return The persister name.
+ */
+ public String getName();
+
+ /**
+ * Retrieve the short (unqualified) version of the persister name.
+ * <p/>
+ * Useful for alias basing.
+ *
+ * @return The persister short name.
+ */
+ public String getShortName();
+
+ public Table.TableSpace getTableSpace();
+
public Type getPropertyType(String propertyName);
+
+ public Table locateReusablePropertyJoinedTable(String propertyName);
+ public void registerReusablePropertyJoinedTable(String propertyName, Table table);
}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterTableExpressionGenerator.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterTableExpressionGenerator.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/PersisterTableExpressionGenerator.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -30,6 +30,7 @@
package org.hibernate.sql.ast.phase.hql.resolve;
import org.hibernate.persister.MappedTableMetadata;
+import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.sql.ast.alias.TableAliasGenerator;
import org.hibernate.sql.ast.common.HibernateTree;
@@ -44,6 +45,7 @@
* @author Steve Ebersole
*/
public class PersisterTableExpressionGenerator {
+
public static Table generateTableExpression(
Queryable persister,
TableAliasGenerator.TableAliasRoot aliasRoot,
@@ -57,14 +59,13 @@
int suffix = 0;
- MappedTableMetadata.JoinedTable[] tables = tableMetadata.getJoinedTables();
- for ( int i = 0; i < tables.length; i++ ) {
+ for ( MappedTableMetadata.JoinedTable joinedTable : tableMetadata.getJoinedTables() ) {
final String joinTableAlias = aliasRoot.generate( ++suffix );
- final Table table = generateTableReference( tables[i].getName(), joinTableAlias, tableSpace );
+ final Table table = generateTableReference( joinedTable.getName(), joinTableAlias, tableSpace );
final HibernateTree join = new HibernateTree( HQLParser.JOIN, "join" );
drivingTable.addChild( join );
- if ( tables[i].useInnerJoin() ) {
+ if ( joinedTable.useInnerJoin() ) {
join.addChild( new HibernateTree( HQLParser.INNER, "inner" ) );
}
else {
@@ -78,7 +79,7 @@
drivingTableAlias,
drivingTableJoinColumns,
joinTableAlias,
- tables[i].getKeyColumns()
+ joinedTable.getKeyColumns()
);
on.addChild( joinCondition );
}
@@ -86,6 +87,57 @@
return drivingTable;
}
+ public static Table generateTableExpression(
+ QueryableCollection collectionPersister,
+ TableAliasGenerator.TableAliasRoot aliasRoot,
+ Table.CollectionTableSpace tableSpace) {
+ if ( collectionPersister.isOneToMany() ) {
+ Table table = generateTableExpression(
+ ( Queryable ) collectionPersister.getElementPersister(),
+ aliasRoot,
+ tableSpace.getEntityElementTableSpace()
+ );
+ tableSpace.setCollectionTable( table );
+ return table;
+ }
+ else {
+ Table associationTable = generateTableReference(
+ collectionPersister.getTableName(),
+ aliasRoot.generateCollectionTableAlias(),
+ tableSpace
+ );
+ tableSpace.setCollectionTable( associationTable );
+
+ if ( collectionPersister.isManyToMany() ) {
+ Queryable elementPersister = ( Queryable ) collectionPersister.getElementPersister();
+ Table drivingTable = generateTableExpression(
+ elementPersister,
+ aliasRoot,
+ tableSpace.getEntityElementTableSpace()
+ );
+
+ final HibernateTree join = new HibernateTree( HQLParser.JOIN );
+ associationTable.addChild( join );
+ join.addChild( new HibernateTree( HQLParser.LEFT, "left outer" ) );
+ join.addChild( drivingTable );
+
+ String[] entityFkColumnNames = collectionPersister.getElementColumnNames();
+ String[] entityPkColumnNames = elementPersister.getKeyColumnNames();
+
+ final HibernateTree on = new HibernateTree( HQLParser.ON );
+ join.addChild( on );
+ final HibernateTree joinCondition = generateJoinCorrelation(
+ associationTable.getAliasText(),
+ entityFkColumnNames,
+ drivingTable.getAliasText(),
+ entityPkColumnNames
+ );
+ on.addChild( joinCondition );
+ }
+ return associationTable;
+ }
+ }
+
private static Table generateTableReference(String tableName, String tableAlias, Table.TableSpace tableSpace) {
Table table = new Table( HQLParser.TABLE, tableSpace );
table.addChild( new HibernateTree( HQLParser.IDENTIFIER, tableName ) );
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/ResolutionContext.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/ResolutionContext.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/ResolutionContext.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -32,7 +32,7 @@
import org.antlr.runtime.tree.TreeAdaptor;
import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
+import org.hibernate.sql.ast.alias.TableAliasGenerator;
import org.hibernate.sql.ast.util.TreePrinter;
import org.hibernate.sql.ast.phase.hql.resolve.path.PathResolutionStrategy;
@@ -52,13 +52,6 @@
public TreeAdaptor getTreeAdaptor();
-// /**
-// * The alias builder available in this context.
-// *
-// * @return The alias builder.
-// */
-// public ImplicitAliasGenerator getAliasBuilder();
-
/**
* The current {@link PersisterSpaceContext} for this context. The {@link PersisterSpaceContext}
* can change in relation to subqueries and such. See {@link PersisterSpaceContext} docs for more info.
@@ -88,6 +81,8 @@
*/
public TreePrinter getTreePrinter();
+ public TableAliasGenerator getTableAliasGenerator();
+
/**
* Is this context currently processing a function?
*
@@ -97,7 +92,7 @@
public PathResolutionStrategy getCurrentPathResolutionStrategy();
-// public void registerAssociationFetch(Join join);
-//
-// public void registerPropertyFetch(PersisterReference persisterReference);
+ public void registerAssociationFetch(PersisterSpace persisterSpace);
+
+ public void registerPropertyFetch(PersisterSpace persisterSpace);
}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategy.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategy.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -30,7 +30,6 @@
package org.hibernate.sql.ast.phase.hql.resolve.path;
import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
-import org.hibernate.sql.ast.phase.hql.resolve.PropertyPathTerminus;
import org.hibernate.sql.ast.common.HibernateTree;
/**
@@ -67,7 +66,7 @@
*
* @return The terminal property reference indicated by the overall path.
*/
- public PropertyPathTerminus handleTerminalPathPart(PathedPropertyReferenceSource source, String pathPart);
+ public HibernateTree handleTerminalPathPart(PathedPropertyReferenceSource source, String pathPart);
/**
* Handle an index access operation (a.b[selector] for example). In this particular case the index access
@@ -91,5 +90,5 @@
*
* @return The terminal property reference indicated by the overall path.
*/
- public PropertyPathTerminus handleTerminalIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector);
+ public HibernateTree handleTerminalIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector);
}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategyStack.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategyStack.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathResolutionStrategyStack.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path;
+
+import java.util.LinkedList;
+
+/**
+ * Provides a stack of {@link PathResolutionStrategy} instances.
+ *
+ * @author Steve Ebersole
+ */
+public class PathResolutionStrategyStack {
+ private LinkedList<PathResolutionStrategy> stack = new LinkedList<PathResolutionStrategy>();
+
+ public void push(PathResolutionStrategy handler) {
+ stack.addFirst( handler );
+ }
+
+ public PathResolutionStrategy pop() {
+ return stack.removeFirst();
+ }
+
+ public PathResolutionStrategy getCurrent() {
+ return stack.getFirst();
+ }
+}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathedPropertyReferenceSource.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathedPropertyReferenceSource.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/PathedPropertyReferenceSource.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -26,13 +26,11 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-
package org.hibernate.sql.ast.phase.hql.resolve.path;
import org.antlr.runtime.tree.Tree;
import org.hibernate.sql.ast.common.HibernateTree;
-import org.hibernate.sql.ast.phase.hql.resolve.PropertyPathTerminus;
/**
* The contract for representing the non-terminal parts of a property path expression
@@ -66,7 +64,7 @@
*
* @return The property reference terminus.
*/
- public PropertyPathTerminus handleTerminalPathPart(String name);
+ public HibernateTree handleTerminalPathPart(String name);
/**
* Handle an index access operation (a.b[selector] for example). In this particular case the index access
@@ -88,5 +86,5 @@
*
* @return The property reference terminus.
*/
- public PropertyPathTerminus handleTerminalIndexAccess(String collectionPropertyName, HibernateTree selector);
+ public HibernateTree handleTerminalIndexAccess(String collectionPropertyName, HibernateTree selector);
}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractPathResolutionStrategy.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,595 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.antlr.runtime.Token;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.ast.alias.TableAliasGenerator;
+import org.hibernate.sql.ast.common.HibernateToken;
+import org.hibernate.sql.ast.common.HibernateTree;
+import org.hibernate.sql.ast.phase.hql.parse.HQLParser;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterTableExpressionGenerator;
+import org.hibernate.sql.ast.phase.hql.resolve.ResolutionContext;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathResolutionStrategy;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.tree.Table;
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.sql.ast.util.TreePrinter;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * Abstract implementation of {@link PathResolutionStrategy} providing convenience methods to actual
+ * {@link PathResolutionStrategy} implementors.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPathResolutionStrategy implements PathResolutionStrategy {
+ private static final Logger log = LoggerFactory.getLogger( AbstractPathResolutionStrategy.class );
+
+ private final ResolutionContext resolutionContext;
+ private String pathThusFar = null;
+
+ protected AbstractPathResolutionStrategy(ResolutionContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ // reolution context ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Getter for property 'resolutionContext'.
+ *
+ * @return Value for property 'resolutionContext'.
+ */
+ protected ResolutionContext resolutionContext() {
+ return resolutionContext;
+ }
+
+ protected final HibernateTree createNode(int type, String text) {
+ return ( HibernateTree ) resolutionContext().getTreeAdaptor().create( type, text );
+ }
+
+ /**
+ * Getter for property 'sessionFactoryImplementor'.
+ *
+ * @return Value for property 'sessionFactoryImplementor'.
+ */
+ protected final SessionFactoryImplementor getSessionFactoryImplementor() {
+ return resolutionContext().getSessionFactoryImplementor();
+ }
+
+ /**
+ * Getter for property 'ASTPrinter'.
+ *
+ * @return Value for property 'ASTPrinter'.
+ */
+ protected final TreePrinter getTreePrinter() {
+ return resolutionContext().getTreePrinter();
+ }
+
+
+ // path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void initializePathSoFar(String root) {
+ pathThusFar = root;
+ }
+
+ /**
+ * Getter for property 'pathThusFar'.
+ *
+ * @return Value for property 'pathThusFar'.
+ */
+ public String getPathThusFar() {
+ return pathThusFar;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource handleRoot(PersisterSpace persisterSpace) {
+ initializePathSoFar( persisterSpace.getSourceAlias() );
+ log.trace( "handling root path source [" + pathThusFar + "]" );
+ return internalHandleRoot( persisterSpace );
+ }
+
+ /**
+ * Hook for subclasses to process the path root.
+ *
+ * @param persisterSpace The persister defining the source root.
+ * @return The appropriate property path source implementation.
+ */
+ protected abstract PathedPropertyReferenceSource internalHandleRoot(PersisterSpace persisterSpace);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource handleIntermediatePathPart(PathedPropertyReferenceSource source, String pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart;
+ log.trace( "handling intermediate path source [" + pathThusFar + "]" );
+ return internalResolveIntermediatePathPart( source, pathPart );
+ }
+
+ /**
+ * Hook for subclasses to process an intermediate part of the path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return The appropriate property path source implementation.
+ */
+ protected PathedPropertyReferenceSource internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, String pathPart) {
+ return source.handleIntermediatePathPart( pathPart );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final HibernateTree handleTerminalPathPart(PathedPropertyReferenceSource source, String pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart;
+ log.trace( "handling terminal path part [" + pathThusFar + "]" );
+ try {
+ return internalResolveTerminalPathPart( source, pathPart );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process the terminal (or ending) part of a path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return a node representing the normalized property path.
+ */
+ protected HibernateTree internalResolveTerminalPathPart(PathedPropertyReferenceSource source, String pathPart) {
+ return source.handleTerminalPathPart( pathPart );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource handleIntermediateIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ pathThusFar = ( ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart ) + "[]";
+ log.trace( "handling intermediate index access [" + pathThusFar + "]" );
+ try {
+ return internalHandleIntermediateIndexAccess( source, pathPart, selector );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process an index access as an intermediate property path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @param selector The index selector to be appliedto the indexed collection
+ *
+ * @return The appropriate property path source implementation.
+ */
+ protected PathedPropertyReferenceSource internalHandleIntermediateIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ return source.handleIntermediateIndexAccess( pathPart, selector );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final HibernateTree handleTerminalIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ pathThusFar = ( ( pathThusFar == null ) ? pathPart : pathThusFar + "." + pathPart ) + "[]";
+ log.trace( "handling terminal index access [" + pathThusFar + "]" );
+ try {
+ return internalHandleTerminalIndexAccess( source, pathPart, selector );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process an index access as the terminus of a property path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @param selector The index selector to be appliedto the indexed collection
+ *
+ * @return a node representing the normalized property path.
+ */
+ protected HibernateTree internalHandleTerminalIndexAccess(PathedPropertyReferenceSource source, String pathPart, HibernateTree selector) {
+ return source.handleTerminalIndexAccess( pathPart, selector );
+ }
+
+ /**
+ * Convenience method to locate the index of a component sub-property. The returned index is relative to
+ * {@link ComponentType#getPropertyNames}.
+ *
+ * @param componentType The component type mapping.
+ * @param subPropertyName The sub-property name.
+ * @return The index.
+ */
+ protected static 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 + "]" );
+ }
+
+ /**
+ * Hook to allow subclasses to disallow implicit join.
+ *
+ * @param origin The persister-reference which is the origin of the property
+ * @param property The property resulting in a join.
+ */
+ protected void validateJoinCreation(PersisterSpace origin, String property) {
+ log.debug( "creating path expression implied join [" + origin.getSourceAlias() + "].[" + property + "]" );
+ }
+
+ /**
+ * Hook to allow subclasses to define the type of join to use for an implciit join.
+ * <p/>
+ * The default is to use an {@link HQLParser#INNER} join.
+ *
+ * @return The join type node.
+ */
+ protected HibernateTree buildJoinTypeNode() {
+ return createNode( HQLParser.INNER, "inner" );
+ }
+
+ /**
+ * Does this strategy allows property joins to be reused?
+ *
+ * @return True/false.
+ */
+ protected boolean areJoinsReusable() {
+ return true;
+ }
+
+ /**
+ * Locate (if property joins are reusable) or build an appropriate joined table.
+ *
+ * @param lhs The join lhs, which is the origin of the property.
+ * @param propertyName The name of the property
+ * @param alias The alias, if any, to apply to the generated RHS persister reference.
+ * @param propertyFetching Should property fetching be applied to the generated RHS?
+ * @param associationFetching Did this property join specify association fetching (join fetch)?
+ * @return The appropriate join.
+ */
+ protected final Table locateOrBuildPropertyJoinedTable(
+ PersisterSpace lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ Table joinedTable = null;
+ if ( areJoinsReusable() ) {
+ joinedTable = lhs.locateReusablePropertyJoinedTable( propertyName );
+ }
+
+ if ( joinedTable == null ) {
+ joinedTable = buildPropertyJoinedTable( lhs, propertyName, alias, propertyFetching, associationFetching );
+ if ( areJoinsReusable() ) {
+ lhs.registerReusablePropertyJoinedTable( propertyName, joinedTable );
+ }
+ }
+
+ return joinedTable;
+ }
+
+ /**
+ * Build a property joined table
+ *
+ * @param lhs The join's left-hand-side persister-reference
+ * @param propertyName The property name.
+ * @param alias The alias to apply to the rhs of the join
+ * @param propertyFetching should property fetching be applied to the joined persister?
+ * @param associationFetching Should the association making up the property join also be fetched?
+ *
+ * @return The right-hand-side persister-reference.
+ */
+ protected Table buildPropertyJoinedTable(
+ PersisterSpace lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetching) {
+ validateJoinCreation( lhs, propertyName );
+ Table joinedTable;
+ Type propertyType = lhs.getPropertyType( propertyName );
+ if ( propertyType.isEntityType() ) {
+ EntityType entityType = ( EntityType ) propertyType;
+ Queryable entityPersister = ( Queryable ) getSessionFactoryImplementor()
+ .getEntityPersister( entityType.getAssociatedEntityName( getSessionFactoryImplementor() ) );
+ joinedTable = createJoin( lhs, entityPersister, alias );
+ }
+ else if ( propertyType.isCollectionType() ) {
+ CollectionType collectionType = ( CollectionType ) propertyType;
+ QueryableCollection collectionPersister = ( QueryableCollection ) getSessionFactoryImplementor()
+ .getCollectionPersister( collectionType.getRole() );
+ joinedTable = createJoin( lhs, collectionPersister, alias, null );
+ }
+ else {
+ throw new InvalidPropertyJoinException( getPathThusFar(), lhs.getName(), propertyName );
+ }
+
+ if ( propertyFetching ) {
+ resolutionContext().registerPropertyFetch( joinedTable.getTableSpace().getPersisterSpace() );
+ }
+ if ( associationFetching ) {
+ resolutionContext.registerAssociationFetch( joinedTable.getTableSpace().getPersisterSpace() );
+ }
+
+ return joinedTable;
+ }
+
+ /**
+ * Generate a column list (tree w/ token type {@link HQLParser#COLUMN_LIST} for the columns making up the given
+ * property.
+ *
+ * @param origin The persister-space from which the property originates.
+ * @param propertyName The name of the property being referenced.
+ *
+ * @return The column list.
+ */
+ protected final HibernateTree generatePropertyColumnList(PersisterSpace origin, String propertyName) {
+ HibernateTree columnList = new HibernateTree( HQLParser.COLUMN_LIST );
+ Table containingTable = origin.getTableSpace().getContainingTable( propertyName );
+ for ( String columnName : origin.getTableSpace().getPropertyColumnNames( propertyName ) ) {
+ final HibernateTree column = new HibernateTree( HQLParser.COLUMN );
+ columnList.addChild( column );
+ column.addChild( new HibernateTree( HQLParser.ALIAS_REF, containingTable.getAliasText() ) );
+ column.addChild( new HibernateTree( HQLParser.IDENTIFIER, columnName ) );
+ }
+ return columnList;
+ }
+
+
+ // source impl support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public abstract class AbstractPathedPropertyReferenceSource
+ extends HibernateTree
+ implements PathedPropertyReferenceSource, DisplayableNode {
+ private final String originationPath;
+
+ /**
+ * Constructs a new AbstractPathedPropertyReferenceSource.
+ */
+ protected AbstractPathedPropertyReferenceSource() {
+ this( getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token) {
+ this( token, getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(String originationPath) {
+ super( new HibernateToken( HQLParser.IDENTIFIER, originationPath ) );
+ this.originationPath = originationPath;
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token, String originationPath) {
+ super( token );
+ this.originationPath = originationPath;
+ }
+
+ public HibernateTree handleTerminalIndexAccess(PersisterSpace lhs, String collectionPropertyName, HibernateTree selector) {
+ Table joinedCollectionTable = createIndexAccessJoin( lhs, collectionPropertyName, selector );
+
+ // in general we need the collection element column list
+ QueryableCollection collectionPersister = resolveCollectionPersister( lhs, collectionPropertyName );
+ HibernateTree columnList = new HibernateTree( HQLParser.COLUMN_LIST );
+ for ( String columnName : collectionPersister.getElementColumnNames() ) {
+ final HibernateTree column = new HibernateTree( HQLParser.COLUMN );
+ column.addChild( new HibernateTree( HQLParser.ALIAS_REF, joinedCollectionTable.getAliasText() ) );
+ column.addChild( new HibernateTree( HQLParser.IDENTIFIER, columnName ) );
+ }
+ return columnList;
+ }
+
+ protected Table createIndexAccessJoin(PersisterSpace lhs, String collectionPropertyName, HibernateTree selector) {
+ validateIndexedCollectionReference( lhs, collectionPropertyName );
+
+ QueryableCollection collectionPersister = resolveCollectionPersister( lhs, collectionPropertyName );
+ HibernateTree join = createJoin( lhs, collectionPersister, null, selector );
+
+ if ( log.isTraceEnabled() ) {
+ log.trace(
+ resolutionContext().getTreePrinter().renderAsString(
+ join,
+ "implicit join : " + lhs.getSourceAlias() + "." + collectionPropertyName + "[]"
+ )
+ );
+ }
+
+ return ( Table ) join.getChild( 1 );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getOriginationPath() {
+ return originationPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE!";
+ }
+ }
+
+ protected Table createJoin(PersisterSpace lhs, Queryable entityPersister, String alias) {
+ EntityType entityType = entityPersister.getEntityMetamodel().getEntityType();
+
+ Table.EntityTableSpace tableSpace = new Table.EntityTableSpace( entityPersister, alias );
+ TableAliasGenerator.TableAliasRoot tableAliasRoot = resolutionContext().getTableAliasGenerator()
+ .generateSqlAliasRoot( entityPersister, alias );
+
+ Table joinedTableExpression = PersisterTableExpressionGenerator.generateTableExpression(
+ entityPersister,
+ tableAliasRoot,
+ tableSpace
+ );
+
+ HibernateTree join = new HibernateTree( HQLParser.JOIN );
+ join.addChild( buildJoinTypeNode() );
+ join.addChild( joinedTableExpression );
+
+ HibernateTree joinCondition;
+ final String lhsJoinProperty = entityType.getLHSPropertyName();
+ if ( lhsJoinProperty == null ) {
+ // join using the lhs PK
+ joinCondition = PersisterTableExpressionGenerator.generateJoinCorrelation(
+ lhs.getTableSpace().getJoinIntoTable().getAliasText(),
+ lhs.getTableSpace().getJoinIntoColumns(),
+ joinedTableExpression.getAliasText(),
+ entityPersister.getKeyColumnNames()
+ );
+ }
+ else {
+ // join using the columns to which the given lhs property is mapped
+ joinCondition = PersisterTableExpressionGenerator.generateJoinCorrelation(
+ lhs.getTableSpace().getContainingTable( lhsJoinProperty ).getAliasText(),
+ lhs.getTableSpace().getPropertyColumnNames( lhsJoinProperty ),
+ joinedTableExpression.getAliasText(),
+ entityPersister.getKeyColumnNames()
+ );
+ }
+
+ HibernateTree on = new HibernateTree( HQLParser.ON );
+ join.addChild( on );
+ on.addChild( joinCondition );
+
+ return joinedTableExpression;
+ }
+
+ protected Table createJoin(PersisterSpace lhs, QueryableCollection collectionPersister, String sourceAlias, HibernateTree extraJoinConditions) {
+ CollectionType collectionType = collectionPersister.getCollectionType();
+
+ Table.CollectionTableSpace tableSpace = new Table.CollectionTableSpace( collectionPersister, sourceAlias );
+ TableAliasGenerator.TableAliasRoot tableAliasRoot = resolutionContext().getTableAliasGenerator()
+ .generateSqlAliasRoot( collectionPersister, sourceAlias );
+
+ Table collectionTableExpression = PersisterTableExpressionGenerator.generateTableExpression(
+ collectionPersister,
+ tableAliasRoot,
+ tableSpace
+ );
+
+ HibernateTree joinNode = new HibernateTree( HQLParser.JOIN );
+ joinNode.addChild( buildJoinTypeNode() );
+ joinNode.addChild( collectionTableExpression );
+
+ HibernateTree joinCondition;
+ final String lhsJoinProperty = collectionType.getLHSPropertyName();
+ if ( lhsJoinProperty == null ) {
+ // join using the lhs PK
+ joinCondition = PersisterTableExpressionGenerator.generateJoinCorrelation(
+ lhs.getTableSpace().getJoinIntoTable().getAliasText(),
+ lhs.getTableSpace().getJoinIntoColumns(),
+ collectionTableExpression.getAliasText(),
+ collectionPersister.getKeyColumnNames()
+ );
+ }
+ else {
+ // join using the columns to which the given lhs property is mapped
+ joinCondition = PersisterTableExpressionGenerator.generateJoinCorrelation(
+ lhs.getTableSpace().getContainingTable( lhsJoinProperty ).getAliasText(),
+ lhs.getTableSpace().getPropertyColumnNames( lhsJoinProperty ),
+ collectionTableExpression.getAliasText(),
+ collectionPersister.getKeyColumnNames()
+ );
+ }
+
+ if ( extraJoinConditions != null ) {
+ HibernateTree mappedJoinCondition = joinCondition;
+ joinCondition = new HibernateTree( HQLParser.AND );
+ joinCondition.addChild( mappedJoinCondition );
+ joinCondition.addChild( extraJoinConditions );
+ }
+
+ HibernateTree on = new HibernateTree( HQLParser.ON );
+ joinNode.addChild( on );
+ on.addChild( joinCondition );
+
+ return collectionTableExpression;
+ }
+
+ protected void validateCollectionReference(PersisterSpace lhs, String propertyName) {
+ if ( ! isCollectionReference( lhs.getPropertyType( propertyName ) ) ) {
+ throw new CollectionExpectedException( getPathThusFar(), lhs.getName(), propertyName );
+ }
+ }
+
+ private boolean isCollectionReference(Type propertyType) {
+ return propertyType.isCollectionType();
+ }
+
+ protected void validateIndexedCollectionReference(PersisterSpace lhs, String propertyName) {
+ if ( ! isIndexedCollectionReference( lhs.getPropertyType( propertyName ) ) ) {
+ throw new IndexedCollectionExectedException( getPathThusFar(), lhs.getName(), propertyName );
+ }
+ }
+
+ private boolean isIndexedCollectionReference(Type propertyType) {
+ return isCollectionReference( propertyType )
+ && resolveCollectionPersister( ( CollectionType ) propertyType ).hasIndex();
+ }
+
+ protected QueryableCollection resolveCollectionPersister(PersisterSpace lhs, String propertyName) {
+ return resolveCollectionPersister( ( CollectionType ) lhs.getPropertyType( propertyName ) );
+ }
+
+ protected QueryableCollection resolveCollectionPersister(CollectionType collectionType) {
+ return ( QueryableCollection ) getSessionFactoryImplementor().getCollectionPersister( collectionType.getRole() );
+ }
+
+ protected Queryable resolveEntityPersister(PersisterSpace lhs, String propertyName) {
+ return resolveEntityPersister( ( EntityType ) lhs.getPropertyType( propertyName ) );
+ }
+
+ protected Queryable resolveEntityPersister(EntityType entityType) {
+ return ( Queryable ) getSessionFactoryImplementor().getEntityPersister(
+ entityType.getAssociatedEntityName( getSessionFactoryImplementor() )
+ );
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractUnexpectedPropertyTypeException.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractUnexpectedPropertyTypeException.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/AbstractUnexpectedPropertyTypeException.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,71 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.hibernate.QueryException;
+
+/**
+ * todo : javadocs
+ *
+ * @author Steve Ebersole
+ */
+public class AbstractUnexpectedPropertyTypeException extends QueryException {
+ private final String path;
+ private final String persisterName;
+ private final String propertyName;
+
+ public AbstractUnexpectedPropertyTypeException(String path, String persisterName, String propertyName) {
+ super();
+ this.path = path;
+ this.persisterName = persisterName;
+ this.propertyName = propertyName;
+ }
+
+ @Override
+ protected String internalGetMessage() {
+ return "Referenced property [" + buildPropertyReferenceFragment() + "] was not of expected type";
+ }
+
+ protected String buildPropertyReferenceFragment() {
+ return path + " (" + persisterName + ")." + propertyName;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getPersisterName() {
+ return persisterName;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/BasicPathResolutionStrategySupport.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/BasicPathResolutionStrategySupport.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/BasicPathResolutionStrategySupport.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,334 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.sql.ast.common.HibernateTree;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
+import org.hibernate.sql.ast.phase.hql.resolve.PropertyPathTerminus;
+import org.hibernate.sql.ast.phase.hql.resolve.ResolutionContext;
+import org.hibernate.sql.ast.phase.hql.resolve.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.tree.Table;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * todo : javadocs
+ *
+ * @author Steve Ebersole
+ */
+public class BasicPathResolutionStrategySupport extends AbstractPathResolutionStrategy {
+ private static final Logger log = LoggerFactory.getLogger( BasicPathResolutionStrategySupport.class );
+
+
+ public BasicPathResolutionStrategySupport(ResolutionContext resolutionContext) {
+ super( resolutionContext );
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterSpace persisterSpace) {
+ return new RootSourceImpl( persisterSpace );
+ }
+
+ private PathedPropertyReferenceSource determineAppropriateIntermediateSourceType(PersisterSpace origin, String propertyName) {
+ final Type propertyType = origin.getPropertyType( propertyName );
+ if ( propertyType.isComponentType() ) {
+ return new ComponentIntermediatePathSource( origin, propertyName, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityIntermediatePathSource( origin, propertyName );
+ }
+ else if ( propertyType.isCollectionType() ) {
+ return new CollectionIntermediatePathSource( origin, propertyName );
+ }
+ else {
+ return new SimpleIntermediatePathSource();
+ }
+ }
+
+ /**
+ * 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) {
+ EntityPersister persister = getSessionFactoryImplementor().getEntityPersister(
+ owningType.getAssociatedEntityName( getSessionFactoryImplementor() )
+ );
+ 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( getSessionFactoryImplementor() );
+ return keyPropertyName != null && keyPropertyName.equals( propertyName ) && owningType.isReferenceToPrimaryKey();
+ }
+ }
+ }
+
+
+
+ // source impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private class RootSourceImpl extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace lhs;
+
+ public RootSourceImpl(PersisterSpace lhs) {
+ this.lhs = lhs;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ return determineAppropriateIntermediateSourceType( lhs, name );
+ }
+
+ public HibernateTree handleTerminalPathPart(String name) {
+ if ( lhs.getPropertyType( name ).isEntityType() ) {
+ if ( shouldTerminalEntityPropertyForceJoin() ) {
+ locateOrBuildPropertyJoinedTable( lhs, name, null, false, false );
+ }
+ }
+ return generatePropertyColumnList( lhs, name );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String collectionPropertyName, HibernateTree selector) {
+ validateIndexedCollectionReference( lhs, collectionPropertyName );
+ QueryableCollection collectionPersister = resolveCollectionPersister( lhs, collectionPropertyName );
+
+ Table joinedCollectionTable = createJoin( lhs, collectionPersister, null, selector );
+ return new IndexAccessIntermediatePathSource(joinedCollectionTable.getTableSpace().getPersisterSpace() );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String collectionPropertyName, HibernateTree selector) {
+ return handleTerminalIndexAccess( lhs, collectionPropertyName, selector );
+ }
+
+ public String getText() {
+ return "root-source {" + lhs.getSourceAlias() + "}";
+ }
+ }
+
+ protected class SimpleIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ throw new HibernateException( "cannot dereference simple value as part of path expression" );
+ }
+
+ public HibernateTree handleTerminalPathPart(String name) {
+ throw new HibernateException( "cannot dereference simple value as part of path expression" );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot apply index operation to simple value" );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot apply index operation to simple value" );
+ }
+ }
+
+ private class ComponentIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace lhs;
+ private final String propertyPath;
+ private final ComponentType componentType;
+
+ public ComponentIntermediatePathSource(PersisterSpace lhs, String propertyPath) {
+ this( lhs, propertyPath, ( ComponentType ) lhs.getPropertyType( propertyPath ) );
+ }
+
+ private ComponentIntermediatePathSource(PersisterSpace lhs, String propertyPath, ComponentType componentType) {
+ this.lhs = lhs;
+ this.propertyPath = propertyPath;
+ this.componentType = componentType;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String propertyName) {
+ final int index = locateComponentPropertyIndex( componentType, propertyName );
+ final String path = buildComponentDereferencePath( propertyName );
+ final Type propertyType = componentType.getSubtypes()[index];
+ if ( propertyType.isComponentType() ) {
+ return new ComponentIntermediatePathSource( lhs, path, ( ComponentType ) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityIntermediatePathSource( lhs, path );
+ }
+ else {
+ return new SimpleIntermediatePathSource();
+ }
+ }
+
+ public HibernateTree handleTerminalPathPart(String name) {
+ return generatePropertyColumnList( lhs, buildComponentDereferencePath( name ) );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot apply index operation to component value" );
+ }
+
+ public PropertyPathTerminus handleTerminalIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot apply index operation to component value" );
+ }
+
+ private String buildComponentDereferencePath(String subPropertyName) {
+ return propertyPath + "." + subPropertyName;
+ }
+ }
+
+ protected class EntityIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace lhs;
+ private final String lhsPropertyName;
+
+ public EntityIntermediatePathSource(PersisterSpace lhs, String lhsPropertyName) {
+ this.lhs = lhs;
+ this.lhsPropertyName = lhsPropertyName;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ Table joinedTable = locateOrBuildPropertyJoinedTable( lhs, lhsPropertyName, null, false, false );
+ return determineAppropriateIntermediateSourceType( joinedTable.getTableSpace().getPersisterSpace(), name );
+ }
+
+ public HibernateTree handleTerminalPathPart(String name) {
+ final EntityType type = ( EntityType ) lhs.getPropertyType( lhsPropertyName );
+ if ( isReferenceToPrimaryKey( type, lhsPropertyName ) ) {
+ // todo : create a column-list based on the FKs...
+ return null;
+ }
+ else {
+ Table joinedTable = locateOrBuildPropertyJoinedTable( lhs, lhsPropertyName, null, false, false );
+ PersisterSpace rhs = joinedTable.getTableSpace().getPersisterSpace();
+ if ( type.isEntityType() ) {
+ if ( shouldTerminalEntityPropertyForceJoin() ) {
+ locateOrBuildPropertyJoinedTable( rhs, name, null, false, false );
+ }
+ }
+ return generatePropertyColumnList( rhs, name );
+ }
+
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ Table lhsJoinedTable = locateOrBuildPropertyJoinedTable( lhs, lhsPropertyName, null, false, false );
+ PersisterSpace lhsJoinedPersisterSpace = lhsJoinedTable.getTableSpace().getPersisterSpace();
+
+ validateIndexedCollectionReference( lhs, name );
+ QueryableCollection collectionPersister = resolveCollectionPersister( lhsJoinedPersisterSpace, name );
+ Table joinedTable = createJoin( lhsJoinedPersisterSpace, collectionPersister, null, selector );
+
+ return new IndexAccessIntermediatePathSource( joinedTable.getTableSpace().getPersisterSpace() );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String collectionPropertyName, HibernateTree selector) {
+ return handleTerminalIndexAccess( lhs, collectionPropertyName, selector );
+ }
+ }
+
+ protected boolean shouldTerminalEntityPropertyForceJoin() {
+ return false;
+ }
+
+ protected class CollectionIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace lhs;
+ private final String propertyName;
+
+ public CollectionIntermediatePathSource(PersisterSpace lhs, String propertyName) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+
+ public HibernateTree handleTerminalPathPart(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???
+ if ( CollectionProperties.isAnyCollectionProperty( name ) ) {
+ Table joinedTable = locateOrBuildPropertyJoinedTable( lhs, propertyName, null, false, false );
+ return generatePropertyColumnList( joinedTable.getTableSpace().getPersisterSpace(), name );
+ }
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String name, HibernateTree selector) {
+ throw new HibernateException( "cannot implicit join across a collection association" );
+ }
+ }
+
+ protected class IndexAccessIntermediatePathSource extends AbstractPathedPropertyReferenceSource {
+ private final PersisterSpace persisterSpace;
+
+ public IndexAccessIntermediatePathSource(PersisterSpace persisterSpace) {
+ this.persisterSpace = persisterSpace;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(String name) {
+ return determineAppropriateIntermediateSourceType( persisterSpace, name );
+ }
+
+ public HibernateTree handleTerminalPathPart(String name) {
+ return generatePropertyColumnList( persisterSpace, name );
+ }
+
+ public PathedPropertyReferenceSource handleIntermediateIndexAccess(String name, HibernateTree selector) {
+ throw new IllegalStateException( "doubled up index operators" );
+ }
+
+ public HibernateTree handleTerminalIndexAccess(String name, HibernateTree selector) {
+ throw new IllegalStateException( "doubled up index operators" );
+ }
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/CollectionExpectedException.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/CollectionExpectedException.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/CollectionExpectedException.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+/**
+ * Indicates that we were expecting a property reference to identify a collection, but it did not.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionExpectedException extends AbstractUnexpectedPropertyTypeException {
+ public CollectionExpectedException(String path, String persisterName, String propertyName) {
+ super( path, persisterName, propertyName );
+ }
+
+ @Override
+ protected String internalGetMessage() {
+ return "Expected property reference [" + buildPropertyReferenceFragment() + "] to identify collection";
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/IndexedCollectionExectedException.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/IndexedCollectionExectedException.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/IndexedCollectionExectedException.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+/**
+ * Indicates that we were expecting a property reference to identify an indexed collection, but it did not.
+ *
+ * @author Steve Ebersole
+ */
+public class IndexedCollectionExectedException extends AbstractUnexpectedPropertyTypeException {
+ public IndexedCollectionExectedException(String path, String persisterName, String propertyName) {
+ super( path, persisterName, propertyName );
+ }
+
+ @Override
+ protected String internalGetMessage() {
+ return "Expected property reference [" + buildPropertyReferenceFragment() + "] to identify indexed collection";
+ }
+}
Added: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/InvalidPropertyJoinException.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/InvalidPropertyJoinException.java (rev 0)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/resolve/path/impl/InvalidPropertyJoinException.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party
+ * contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+
+package org.hibernate.sql.ast.phase.hql.resolve.path.impl;
+
+/**
+ * Indicates an attempt to define an implicit or explicit property join based on a non-association property.
+ *
+ * @author Steve Ebersole
+ */
+public class InvalidPropertyJoinException extends AbstractUnexpectedPropertyTypeException {
+ public InvalidPropertyJoinException(String path, String persisterName, String propertyName) {
+ super( path, persisterName, propertyName );
+ }
+
+ @Override
+ protected String internalGetMessage() {
+ return "Referenced property [" + buildPropertyReferenceFragment() + "] not valid for join";
+ }
+}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java 2009-04-21 18:19:38 UTC (rev 16387)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/Table.java 2009-04-21 18:29:41 UTC (rev 16388)
@@ -26,12 +26,11 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-
package org.hibernate.sql.ast.tree;
-import java.util.List;
import java.util.ArrayList;
import java.util.LinkedHashSet;
+import java.util.HashMap;
import org.antlr.runtime.Token;
@@ -41,6 +40,7 @@
import org.hibernate.sql.ast.common.HibernateToken;
import org.hibernate.sql.ast.util.DisplayableNode;
import org.hibernate.sql.ast.phase.hql.parse.HQLParser;
+import org.hibernate.sql.ast.phase.hql.resolve.PersisterSpace;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.util.StringHelper;
@@ -95,7 +95,13 @@
return "[source-alias=" + tableSpace.getSourceAlias() + "]";
}
+ /**
+ * Represents a grouping of related tables (i.e. all tables for a given persister).
+ */
public static interface TableSpace {
+
+ public void addTable(Table table);
+
/**
* Used as a unique identification since each table space originates from a single source alias (persister reference).
*
@@ -104,6 +110,13 @@
public String getSourceAlias();
/**
+ * PersisterSpace and TableSpace are related one-to-one...
+ *
+ * @return The persister space corresponding to this table space.
+ */
+ public PersisterSpace getPersisterSpace();
+
+ /**
* Get the table reference that should act as the RHS for this table space whenever we join to into it.
*
* @return The RHS table for joining into this table space structure.
@@ -112,9 +125,8 @@
public String[] getJoinIntoColumns();
- public void addTable(Table table);
+ public Type getPropertyType(String propertyName);
-
/**
* Get the table reference that contains the columns to which the given property is mapped.
*
@@ -124,23 +136,23 @@
*/
public Table getContainingTable(String propertyName);
- public Type getPropertyType(String propertyName);
-
public String[] getPropertyColumnNames(String propertyName);
- public List buildIdentifierColumnReferences();
+ public HibernateTree buildIdentifierColumnReferences();
- public List buildCompleteColumnReferences();
+ public HibernateTree buildCompleteColumnReferences();
}
public static abstract class AbstractTableSpace implements Table.TableSpace {
private final String sourceAlias;
- private final String sqlAliasBaseRoot;
+ private final boolean implicitSourceAlias;
protected final LinkedHashSet<Table> tables = new LinkedHashSet<Table>();
+ protected final HashMap<String,Table> aliasToTableMap = new HashMap<String,Table>();
+ protected final HashMap<String,Table> nameToTableMap = new HashMap<String,Table>();
- private AbstractTableSpace(String sourceAlias, String persisterName) {
+ private AbstractTableSpace(String sourceAlias) {
this.sourceAlias = sourceAlias;
- this.sqlAliasBaseRoot = ImplicitAliasGenerator.isImplicitAlias( sourceAlias ) ? persisterName : sourceAlias;
+ this.implicitSourceAlias = ImplicitAliasGenerator.isImplicitAlias( sourceAlias );
}
public String getSourceAlias() {
@@ -148,32 +160,46 @@
}
public String getSqlAliasBaseRoot() {
- return sqlAliasBaseRoot;
+ return implicitSourceAlias ? getPersisterSpace().getShortName() : sourceAlias;
}
public void addTable(Table table) {
tables.add( table );
+ aliasToTableMap.put( table.getAliasText(), table );
+ nameToTableMap.put( table.getTableNameText(), table );
}
}
+ public static abstract class AbstractPersisterSpace implements PersisterSpace {
+ private final HashMap<String,Table> propertyToJoinedTableMap = new HashMap<String,Table>();
+
+ public Table locateReusablePropertyJoinedTable(String propertyName) {
+ return propertyToJoinedTableMap.get( propertyName );
+ }
+
+ public void registerReusablePropertyJoinedTable(String propertyName, Table table) {
+ propertyToJoinedTableMap.put( propertyName, table );
+ }
+ }
+
public static class EntityTableSpace extends AbstractTableSpace {
- private final Queryable entityPersister;
+ private final EntityPersisterSpace persisterSpace;
private final ArrayList tables;
public EntityTableSpace(Queryable entityPersister, String sourecAlias) {
- super( sourecAlias, StringHelper.unqualifyEntityName( entityPersister.getEntityName() ) );
- this.entityPersister = entityPersister;
+ super( sourecAlias );
+ this.persisterSpace = new EntityPersisterSpace( this, entityPersister );
int numberOfTables = entityPersister.getMappedTableMetadata().getJoinedTables().length + 1;
int listSize = numberOfTables + (int) ( numberOfTables * .75 ) + 1;
this.tables = new ArrayList( listSize );
}
- public Queryable getEntityPersister() {
- return entityPersister;
+ public PersisterSpace getPersisterSpace() {
+ return persisterSpace;
}
- public void addTable(Table table) {
- tables.add( table );
+ public Queryable getEntityPersister() {
+ return persisterSpace.getEntityPersister();
}
public Table getDrivingTable() {
@@ -185,69 +211,98 @@
}
public String[] getJoinIntoColumns() {
- return entityPersister.getIdentifierColumnNames();
+ return getEntityPersister().getIdentifierColumnNames();
}
public Table getContainingTable(String propertyName) {
- return ( Table ) tables.get( entityPersister.getSubclassPropertyTableNumber( propertyName ) );
+ // todo : probably a better solution here is to iterate the internal collection of tables...
+ return ( Table ) tables.get( getEntityPersister().getSubclassPropertyTableNumber( propertyName ) );
}
public Type getPropertyType(String propertyName) {
- return entityPersister.getPropertyType( propertyName );
+ return getEntityPersister().getPropertyType( propertyName );
}
public String[] getPropertyColumnNames(String propertyName) {
- int index = entityPersister.getEntityMetamodel().getPropertyIndex( propertyName );
- return entityPersister.getPropertyColumnNames( index );
+ int index = getEntityPersister().getEntityMetamodel().getPropertyIndex( propertyName );
+ return getEntityPersister().getPropertyColumnNames( index );
}
- public List buildIdentifierColumnReferences() {
- String[] identifierColumnsNames = entityPersister.getIdentifierColumnNames();
- ArrayList columnsReferences = new ArrayList( collectionSizeWithoutRehashing( identifierColumnsNames.length ) );
- for ( int i = 0; i < identifierColumnsNames.length; i++ ) {
+ public HibernateTree buildIdentifierColumnReferences() {
+ HibernateTree columnList = new HibernateTree( HQLParser.COLUMN_LIST );
+ for ( String columnName : getEntityPersister().getIdentifierColumnNames() ) {
HibernateTree columnNode = new HibernateTree( HQLParser.COLUMN );
columnNode.addChild( new HibernateTree( HQLParser.ALIAS_REF, getDrivingTable().getAliasText() ) );
- columnNode.addChild( new HibernateTree( HQLParser.IDENTIFIER, identifierColumnsNames[i] ) );
- columnsReferences.add( columnNode );
+ columnNode.addChild( new HibernateTree( HQLParser.IDENTIFIER, columnName ) );
+ columnList.addChild( columnNode );
}
- return columnsReferences;
+ return columnList;
}
- public List buildCompleteColumnReferences() {
+ public HibernateTree buildCompleteColumnReferences() {
// todo : implement
return null;
}
}
- private static int collectionSizeWithoutRehashing(int elements) {
- // usually collection load factors are .75
- return collectionSizeWithoutRehashing( elements, .75 );
- }
+ private static class EntityPersisterSpace extends AbstractPersisterSpace {
+ private final EntityTableSpace correspondingTableSpace;
+ private final Queryable entityPersister;
+ private final String shortName;
- private static int collectionSizeWithoutRehashing(int elements, double factor) {
- return elements + ( (int) ( elements * factor ) + 1 );
+ private EntityPersisterSpace(EntityTableSpace correspondingTableSpace, Queryable entityPersister) {
+ this.correspondingTableSpace = correspondingTableSpace;
+ this.entityPersister = entityPersister;
+ this.shortName = StringHelper.unqualifyEntityName( entityPersister.getEntityName() );
+ }
+
+ public Queryable getEntityPersister() {
+ return entityPersister;
+ }
+
+ public String getSourceAlias() {
+ return correspondingTableSpace.getSourceAlias();
+ }
+
+ public String getName() {
+ return entityPersister.getName();
+ }
+
+ public String getShortName() {
+ return shortName;
+ }
+
+ public TableSpace getTableSpace() {
+ return correspondingTableSpace;
+ }
+
+ public Type getPropertyType(String propertyName) {
+ return entityPersister.getPropertyType( propertyName );
+ }
}
public static class CollectionTableSpace extends AbstractTableSpace {
- private final QueryableCollection persister;
- private final boolean areElementsEntities;
+ private final CollectionPersisterSpace persisterSpace;
private Table collectionTable;
private EntityTableSpace entityElementTableSpace;
public CollectionTableSpace(QueryableCollection persister, String sourceAlias) {
- super( sourceAlias, StringHelper.unqualify( persister.getRole() ) );
- this.persister = persister;
- this.areElementsEntities = persister.getElementType().isEntityType();
- if ( areElementsEntities ) {
+ super( sourceAlias );
+ this.persisterSpace = new CollectionPersisterSpace( this, persister );
+ if ( persisterSpace.areElementsEntities ) {
entityElementTableSpace = new EntityTableSpace( ( Queryable ) persister.getElementPersister(), sourceAlias );
}
}
- public QueryableCollection getPersister() {
- return persister;
+ public QueryableCollection getCollectionPersister() {
+ return persisterSpace.getCollectionPersister();
}
+ public PersisterSpace getPersisterSpace() {
+ return persisterSpace;
+ }
+
public void setCollectionTable(Table collectionTable) {
this.collectionTable = collectionTable;
}
@@ -261,7 +316,7 @@
}
public String[] getJoinIntoColumns() {
- return persister.getKeyColumnNames();
+ return getCollectionPersister().getKeyColumnNames();
}
public Table getContainingTable(String propertyName) {
@@ -277,14 +332,55 @@
return getEntityElementTableSpace().getPropertyColumnNames( propertyName );
}
- public List buildIdentifierColumnReferences() {
+ public HibernateTree buildIdentifierColumnReferences() {
// todo : implement
return null;
}
- public List buildCompleteColumnReferences() {
+ public HibernateTree buildCompleteColumnReferences() {
// todo : implement
return null;
}
}
+
+ public static class CollectionPersisterSpace extends AbstractPersisterSpace {
+ private final CollectionTableSpace correspondingTableSpace;
+ private final QueryableCollection collectionPersister;
+
+ private final String shortName;
+ private final boolean areElementsEntities;
+
+ public CollectionPersisterSpace(CollectionTableSpace correspondingTableSpace, QueryableCollection collectionPersister) {
+ this.correspondingTableSpace = correspondingTableSpace;
+ this.collectionPersister = collectionPersister;
+ this.shortName = StringHelper.unqualify( collectionPersister.getRole() );
+ this.areElementsEntities = collectionPersister.getElementType().isEntityType();
+ }
+
+ public String getSourceAlias() {
+ return correspondingTableSpace.getSourceAlias();
+ }
+
+ public QueryableCollection getCollectionPersister() {
+ return collectionPersister;
+ }
+
+ public String getName() {
+ return collectionPersister.getRole();
+ }
+
+ public String getShortName() {
+ return shortName;
+ }
+
+ public TableSpace getTableSpace() {
+ return correspondingTableSpace;
+ }
+
+ public Type getPropertyType(String propertyName) {
+ return areElementsEntities
+ ? correspondingTableSpace.entityElementTableSpace.getPersisterSpace().getPropertyType( propertyName )
+ : null;
+ }
+ }
}
15 years, 7 months
Hibernate SVN: r16387 - core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse.
by hibernate-commits@lists.jboss.org
Author: porcelli
Date: 2009-04-21 14:19:38 -0400 (Tue, 21 Apr 2009)
New Revision: 16387
Modified:
core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g
core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
Log:
hql parser updates:
- member_of an is empty does not generate subqueries anymore (this will be handled by 2nd phase)
- selectClause is forced to occur
Modified: core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g
===================================================================
--- core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g 2009-04-21 17:47:46 UTC (rev 16386)
+++ core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g 2009-04-21 18:19:38 UTC (rev 16387)
@@ -35,6 +35,7 @@
NOT_BETWEEN;
NOT_IN;
NOT_LIKE;
+ NOT_MEMBER_OF;
PATH;
PERSISTER_JOIN;
PERSISTER_SPACE;
@@ -776,8 +777,8 @@
( is_key (not_key {isNegated = true;})? (NULL {isNull = true;}|empty_key)
-> {isNull && isNegated}? ^(IS_NOT_NULL[$not_key.start, "is not null"] $equalityExpression)
-> {isNull && !isNegated}? ^(IS_NULL[$NULL, "is null"] $equalityExpression)
- -> {!isNull && isNegated}? ^(NOT ^(EXISTS ^(SUB_QUERY ^(QUERY ^(QUERY_SPEC ^(SELECT_FROM ^(FROM $equalityExpression)))))))
- -> ^(EXISTS ^(SUB_QUERY ^(QUERY ^(QUERY_SPEC ^(SELECT_FROM ^(FROM $equalityExpression))))))
+ -> {!isNull && isNegated}? ^(IS_NOT_EMPTY $equalityExpression)
+ -> ^(IS_EMPTY $equalityExpression)
| ( op=EQUALS | op=NOT_EQUAL ) relationalExpression
-> ^($op $equalityExpression relationalExpression)
)*
@@ -801,8 +802,8 @@
-> {isNegated}? ^(NOT_LIKE[$not_key.start, "not like"] $relationalExpression concatenation likeEscape?)
-> ^(like_key $relationalExpression concatenation likeEscape?)
| member_of_key path
- -> {isNegated}? ^(NOT_IN[$not_key.start, "not in"] $relationalExpression ^(IN_LIST ^(SUB_QUERY ^(QUERY ^(QUERY_SPEC ^(SELECT_FROM ^(FROM ^(PATH path))))))))
- -> ^(IN[$member_of_key.start, "in"] $relationalExpression ^(IN_LIST ^(SUB_QUERY ^(QUERY ^(QUERY_SPEC ^(SELECT_FROM ^(FROM ^(PATH path))))))))
+ -> {isNegated}? ^(NOT_MEMBER_OF[$not_key.start, "not member of"] $relationalExpression ^(PATH path))
+ -> ^(member_of_key $relationalExpression ^(PATH path))
)
)?
;
Modified: core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
===================================================================
--- core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 17:47:46 UTC (rev 16386)
+++ core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 18:19:38 UTC (rev 16387)
@@ -122,7 +122,7 @@
;
selectFrom
- : ^(SELECT_FROM fromClause selectClause?)
+ : ^(SELECT_FROM fromClause selectClause)
;
fromClause
@@ -131,7 +131,6 @@
persisterSpaces
: ^(PERSISTER_SPACE persisterSpace)
- | ^(PATH identPrimary)
;
persisterSpace
@@ -203,6 +202,10 @@
| ^( NOT_BETWEEN rowValueConstructor betweenList )
| ^( IN rowValueConstructor inPredicateValue )
| ^( NOT_IN rowValueConstructor inPredicateValue )
+ | ^( MEMBER_OF rowValueConstructor rowValueConstructor )
+ | ^( NOT_MEMBER_OF rowValueConstructor rowValueConstructor )
+ | ^( IS_EMPTY rowValueConstructor )
+ | ^( IS_NOT_EMPTY rowValueConstructor )
| rowValueConstructor
;
15 years, 7 months
Hibernate SVN: r16386 - core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse.
by hibernate-commits@lists.jboss.org
Author: porcelli
Date: 2009-04-21 13:47:46 -0400 (Tue, 21 Apr 2009)
New Revision: 16386
Modified:
core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
Log:
fixing TreeWalker to work with "new" aproach to collectionExpression
Modified: core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
===================================================================
--- core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 17:33:51 UTC (rev 16385)
+++ core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 17:47:46 UTC (rev 16386)
@@ -143,7 +143,7 @@
;
joins
- : ^(PROPERTY_JOIN joinType FETCH? ALIAS_NAME PROP_FETCH? collectionExpression withClause?)
+ : ^(PROPERTY_JOIN joinType FETCH? ALIAS_NAME PROP_FETCH? (collectionExpression|propertyReference) withClause?)
| ^(PERSISTER_JOIN joinType persisterSpaceRoot onClause?)
;
@@ -258,7 +258,7 @@
: caseExpression
| function
| collectionFunction
- | collectionExpressionSimple
+ | collectionExpression
| constant
| parameter
| propertyReference
@@ -434,7 +434,7 @@
;
countFunctionArguments
- : collectionExpressionSimple
+ : collectionExpression
| propertyReference
| numeric_literal
;
@@ -448,15 +448,9 @@
: propertyReference
;
-collectionExpressionSimple
- : ^(ELEMENTS propertyReference) //it will generate a SELECT m.column form Table xxx -> it is realted to Hibernate mappings to Table->Map
- | ^(INDICES propertyReference)
- ;
-
collectionExpression
: ^(ELEMENTS propertyReference) //it will generate a SELECT m.column form Table xxx -> it is realted to Hibernate mappings to Table->Map
| ^(INDICES propertyReference)
- | propertyReference
;
parameter
15 years, 7 months
Hibernate SVN: r16385 - in core/branches/antlr3/src: main/java/org/hibernate/sql/ast/common and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: porcelli
Date: 2009-04-21 13:33:51 -0400 (Tue, 21 Apr 2009)
New Revision: 16385
Modified:
core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g
core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/common/HibernateTree.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContext.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContextDefaultImpl.java
core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/EntityNameTree.java
core/branches/antlr3/src/test/gunit/org/hibernate/sql/ast/phase/hql/parse/TempgUnitHQLGrammar.testsuite
Log:
hql parser updates:
- now generating aliases for all persisterSpaces
- now generating the select clause (implicit)
- .indices and .elements are not supported (forces users use function)
Modified: core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g
===================================================================
--- core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQL.g 2009-04-21 17:33:51 UTC (rev 16385)
@@ -8,6 +8,7 @@
//GENERIC SQL TOKENS
TABLE;
COLUMN;
+ COLUMN_LIST;
//VIRTUAL TOKENS
ALIAS_NAME;
@@ -189,6 +190,7 @@
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
+import org.hibernate.sql.ast.tree.EntityNameTree;
}
@lexer::header {
@@ -349,7 +351,7 @@
return implementors;
}
- private Object generatePersisterSpacesTree(List persistenceSpaces) {
+ private Tree generatePersisterSpacesTree(List persistenceSpaces) {
List persisterSpaceList = new ArrayList();
for (Iterator iterator = persistenceSpaces.iterator(); iterator
.hasNext();) {
@@ -372,54 +374,77 @@
return resultTree;
}
-
- private Object generateUpdateStatementTree(Object updateKey, Object entityName,
- Object aliasClause, Object setClause, Object whereClause) {
- Object result = (Object)adaptor.nil();
- EntityNameTree entityNameTree = (EntityNameTree) entityName;
- for (int i = 0; i < entityNameTree.getEntityCount(); i++) {
- Object root_1 = (Object)adaptor.nil();
- root_1 = (Object)adaptor.becomeRoot(new CommonTree((CommonTree)updateKey), root_1);
- adaptor.addChild(root_1, new EntityNameTree(entityNameTree, entityNameTree.getEntityName(i)));
+ private Tree generateUpdateStatementTree(Object updateKey,
+ Object entityName, Object aliasClause, Object setClause,
+ Object whereClause) {
+ Tree result = new CommonTree();
+ EntityNameTree entityNameTree = (EntityNameTree) entityName;
+ for (int i = 0; i < entityNameTree.getEntityCount(); i++) {
+ Tree updateRoot = new CommonTree((CommonTree) updateKey);
- if ( aliasClause != null ) {
- adaptor.addChild(root_1, aliasClause);
- }
- adaptor.addChild(root_1, setClause);
+ updateRoot.addChild(new EntityNameTree(entityNameTree,
+ entityNameTree.getEntityName(i)));
- if ( whereClause != null ) {
- adaptor.addChild(root_1, whereClause);
- }
+ if (aliasClause != null) {
+ updateRoot.addChild((Tree) aliasClause);
+ }
+ updateRoot.addChild((Tree) setClause);
- adaptor.addChild(result, root_1);
+ if (whereClause != null) {
+ updateRoot.addChild((Tree) whereClause);
+ }
+
+ result.addChild(updateRoot);
}
return result;
}
-
- private Object generateDeleteStatementTree(Object deleteKey, Object entityName,
- Object aliasClause, Object whereClause) {
- Object result = (Object)adaptor.nil();
- EntityNameTree entityNameTree = (EntityNameTree) entityName;
- for (int i = 0; i < entityNameTree.getEntityCount(); i++) {
- Object root_1 = (Object)adaptor.nil();
- root_1 = (Object)adaptor.becomeRoot(new CommonTree((CommonTree)deleteKey), root_1);
- adaptor.addChild(root_1, new EntityNameTree(entityNameTree, entityNameTree.getEntityName(i)));
+ private Tree generateDeleteStatementTree(Object deleteKey,
+ Object entityName, Object aliasClause, Object whereClause) {
+ Tree result = new CommonTree();
+ EntityNameTree entityNameTree = (EntityNameTree) entityName;
+ for (int i = 0; i < entityNameTree.getEntityCount(); i++) {
+ Tree deleteRoot = new CommonTree((CommonTree) deleteKey);
- if ( aliasClause != null ) {
- adaptor.addChild(root_1, aliasClause);
- }
+ deleteRoot.addChild(new EntityNameTree(entityNameTree,
+ entityNameTree.getEntityName(i)));
- if ( whereClause != null ) {
- adaptor.addChild(root_1, whereClause);
- }
+ if (aliasClause != null) {
+ deleteRoot.addChild((Tree) aliasClause);
+ }
- adaptor.addChild(result, root_1);
+ if (whereClause != null) {
+ deleteRoot.addChild((Tree) whereClause);
+ }
+
+ result.addChild(deleteRoot);
}
return result;
}
+ private Tree generateSelecFromTree(Object selectClause, Object fromClause, List aliasList){
+ Tree result = new CommonTree(new CommonToken(SELECT_FROM, "SELECT_FROM"));
+ Tree selectTree = null;
+ result.addChild((Tree) fromClause);
+ if (selectClause == null && aliasList != null && aliasList.size() > 0) {
+ selectTree = new CommonTree(new CommonToken(SELECT, "SELECT"));
+ Tree selectList = new CommonTree(new CommonToken(SELECT_LIST, "SELECT_LIST"));
+ for (Iterator iterator = aliasList.iterator(); iterator
+ .hasNext();) {
+ String aliasName = (String) iterator.next();
+ Tree selectElement = new CommonTree(new CommonToken(SELECT_ITEM, "SELECT_ITEM"));
+ Tree aliasElement = new CommonTree(new CommonToken(ALIAS_REF, aliasName));
+ selectElement.addChild(aliasElement);
+ selectList.addChild(selectElement);
+ }
+ selectTree.addChild(selectList);
+ } else {
+ selectTree = (Tree) selectClause;
+ }
+ result.addChild(selectTree);
+ return result;
+ }
}
filterStatement[String collectionRole]
@@ -446,7 +471,7 @@
}
: udpate_key
(versioned_key {$updateStatement::generateVersionedField = true;})?
- from_key? entityName aliasClause setClause whereClause?
+ from_key? entityName aliasClause[true] setClause whereClause?
-> { generateUpdateStatementTree($udpate_key.tree, $entityName.tree, $aliasClause.tree, $setClause.tree, $whereClause.tree ) }
;
@@ -465,7 +490,7 @@
;
deleteStatement
- : delete_key from_key? entityName aliasClause whereClause?
+ : delete_key from_key? entityName aliasClause[true] whereClause?
-> { generateDeleteStatementTree($delete_key.tree, $entityName.tree, $aliasClause.tree, $whereClause.tree ) }
;
@@ -476,7 +501,8 @@
//TODO: Generate an exception when try to use a polimorfic entity at INTO clause
intoClause
- : into_key^ entityName insertabilitySpecification
+ : into_key entityName insertabilitySpecification
+ -> ^(into_key entityName ALIAS_NAME[context.buildUniqueImplicitAlias()] insertabilitySpecification)
;
insertabilitySpecification
@@ -525,8 +551,8 @@
;
selectFrom
- : selectClause? fromClause
- -> ^(SELECT_FROM fromClause selectClause?)
+ : sc=selectClause? fc=fromClause
+ -> { generateSelecFromTree($sc.tree, $fc.tree, $fc.aliasList)}
;
subQuery
@@ -536,7 +562,12 @@
-> ^(SUB_QUERY ^(QUERY queryExpression))
;
-fromClause
+fromClause returns [List aliasList]
+scope{
+ List aliases;
+}
+@init { $fromClause::aliases = new ArrayList(); }
+@after { $aliasList = $fromClause::aliases; }
: from_key^
persisterSpaces
;
@@ -556,8 +587,9 @@
;
qualifiedJoin
-@init { boolean isEntityReference = false; List entityNames = null; }
- : nonCrossJoinType join_key fetch_key? path aliasClause
+@init { boolean isEntityReference = false; boolean hasFetch = false; List entityNames = null; }
+@after { if (!hasFetch) $fromClause::aliases.add(((Tree)$ac.tree).getText()); }
+ : nonCrossJoinType join_key (fetch_key {hasFetch = true;})? path ac=aliasClause[true]
( on_key
{ isEntityReference = true;
entityNames = extractEntityNames($path.text); }
@@ -593,7 +625,8 @@
;
mainEntityPersisterReference
- : entityName aliasClause propertyFetch?
+@after { $fromClause::aliases.add(((Tree)$ac.tree).getText()); }
+ : entityName ac=aliasClause[true] propertyFetch?
-> ^(ENTITY_PERSISTER_REF entityName aliasClause? propertyFetch?)
;
@@ -604,14 +637,16 @@
hibernateLegacySyntax returns [boolean isPropertyJoin]
@init {$isPropertyJoin = false;}
- : aliasDeclaration in_key
+@after { $fromClause::aliases.add(((Tree)$ad.tree).getText()); }
+ : ad=aliasDeclaration in_key
( class_key entityName -> ^(ENTITY_PERSISTER_REF entityName aliasDeclaration)
| collectionExpression {$isPropertyJoin = true;} -> ^(PROPERTY_JOIN INNER[$in_key.start, "inner legacy"] aliasDeclaration collectionExpression)
)
;
jpaCollectionReference
- : in_key LEFT_PAREN propertyReference RIGHT_PAREN aliasClause
+@after { $fromClause::aliases.add(((Tree)$ac.tree).getText()); }
+ : in_key LEFT_PAREN propertyReference RIGHT_PAREN ac=aliasClause[true]
-> ^(PROPERTY_JOIN INNER[$in_key.start, "inner"] aliasClause? propertyReference)
;
@@ -638,14 +673,15 @@
@init { if (state.backtracking == 0) enableParameterUsage.push(Boolean.FALSE); }
@after { enableParameterUsage.pop(); }
//PARAMETERS CAN'T BE USED -> This verification should be scoped
- : expression aliasClause
+ : expression aliasClause[false]
-> ^(SELECT_ITEM expression aliasClause?)
;
-aliasClause
+aliasClause[boolean generateAlias]
options{
k=2;
-} :
+} : -> {$generateAlias}? ALIAS_NAME[context.buildUniqueImplicitAlias()]
+ ->
| aliasDeclaration
| as_key! aliasDeclaration
;
@@ -807,7 +843,7 @@
| standardFunction
| setFunction
| collectionFunction
- | collectionExpressionSimple
+ | collectionExpression
| atom
;
@@ -854,8 +890,8 @@
quantifiedExpression
: ( some_key^ | exists_key^ | all_key^ | any_key^ )
- ( aliasReference
- | collectionExpression
+ ( collectionExpression
+ | aliasReference
| LEFT_PAREN! subQuery RIGHT_PAREN!
)
;
@@ -1024,14 +1060,8 @@
countFunctionArguments
@init { int type = -1;}
- : path
- -> {type == 1}? ^(ELEMENTS ^(PROPERTY_REFERENCE path))
- -> {type == 2}? ^(INDICES ^(PROPERTY_REFERENCE path))
- -> ^(PROPERTY_REFERENCE path)
- //TODO if ends with:
- // .elements or .indices -> it is a collectionExpression
- //if not -> it is a property reference
- | collectionExpressionSimple
+ : propertyReference
+ | collectionExpression
| numeric_literal
;
@@ -1043,25 +1073,17 @@
collectionExpression
: (elements_key^|indices_key^) LEFT_PAREN! propertyReference RIGHT_PAREN!
- | propertyReference DOT! (elements_key^|indices_key^)
;
-collectionExpressionSimple
- : (elements_key^|indices_key^) LEFT_PAREN! propertyReference RIGHT_PAREN!
- ;
-
atom
@init { int type = -1;}
: identPrimary
//TODO if ends with:
// .class -> class type
- // .elements or .indices -> it is a collectionExpression
// if contains "()" it is a function call
// if it is constantReference (using context)
// otherwise it will be a generic element to be resolved on the next phase (1st tree walker)
-> {type == 0}? ^(DOT_CLASS identPrimary)
- -> {type == 1}? ^(ELEMENTS ^(PROPERTY_REFERENCE identPrimary))
- -> {type == 2}? ^(INDICES ^(PROPERTY_REFERENCE identPrimary))
-> {type == 3}? ^(GENERAL_FUNCTION_CALL identPrimary)
-> {type == 4}? ^(JAVA_CONSTANT identPrimary) //-> here will have 2 strutctures element and the constant
-> ^(PATH identPrimary)
@@ -1826,4 +1848,4 @@
AMPERSAND
: '&'
- ;
\ No newline at end of file
+ ;
Modified: core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g
===================================================================
--- core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/antlr3/org/hibernate/sql/ast/phase/hql/parse/HQLTreeWalker.g 2009-04-21 17:33:51 UTC (rev 16385)
@@ -138,8 +138,12 @@
: persisterSpaceRoot joins*
;
+persisterSpaceRoot
+ : ^(ENTITY_PERSISTER_REF entityName PROP_FETCH?)
+ ;
+
joins
- : ^(PROPERTY_JOIN joinType FETCH? ALIAS_NAME? PROP_FETCH? (propertyReference|collectionExpression) withClause?)
+ : ^(PROPERTY_JOIN joinType FETCH? ALIAS_NAME PROP_FETCH? collectionExpression withClause?)
| ^(PERSISTER_JOIN joinType persisterSpaceRoot onClause?)
;
@@ -157,10 +161,6 @@
| (LEFT | RIGHT | FULL) OUTER?
;
-persisterSpaceRoot
- : ^(ENTITY_PERSISTER_REF entityName PROP_FETCH?)
- ;
-
selectClause
: ^(SELECT DISTINCT? rootSelectExpression)
;
@@ -258,7 +258,7 @@
: caseExpression
| function
| collectionFunction
- | collectionExpression
+ | collectionExpressionSimple
| constant
| parameter
| propertyReference
@@ -434,7 +434,7 @@
;
countFunctionArguments
- : collectionExpression
+ : collectionExpressionSimple
| propertyReference
| numeric_literal
;
@@ -448,9 +448,15 @@
: propertyReference
;
+collectionExpressionSimple
+ : ^(ELEMENTS propertyReference) //it will generate a SELECT m.column form Table xxx -> it is realted to Hibernate mappings to Table->Map
+ | ^(INDICES propertyReference)
+ ;
+
collectionExpression
: ^(ELEMENTS propertyReference) //it will generate a SELECT m.column form Table xxx -> it is realted to Hibernate mappings to Table->Map
| ^(INDICES propertyReference)
+ | propertyReference
;
parameter
@@ -481,7 +487,7 @@
;
entityName
- : ENTITY_NAME ALIAS_NAME?
+ : ENTITY_NAME ALIAS_NAME
;
propertyReference
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/common/HibernateTree.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/common/HibernateTree.java 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/common/HibernateTree.java 2009-04-21 17:33:51 UTC (rev 16385)
@@ -34,7 +34,7 @@
/**
* todo : javadocs
- *
+ *
* @author Steve Ebersole
*/
public class HibernateTree extends CommonTree {
@@ -48,30 +48,33 @@
*/
int endCharOffset = -1;
+ public HibernateTree() {
+ }
+
public HibernateTree(HibernateTree node) {
- super( node );
+ super(node);
this.token = node.token;
}
public HibernateTree(Token token) {
- super( token );
+ super(token);
}
public HibernateTree(int type, String text) {
- this( new HibernateToken( type, text ) );
+ this(new HibernateToken(type, text));
}
public HibernateTree(int type) {
- this( new HibernateToken( type ) );
+ this(new HibernateToken(type));
}
public Tree dupNode() {
- return new HibernateTree( this );
+ return new HibernateTree(this);
}
/**
* getter for start char offset
- *
+ *
* @return start char offset
*/
public int getStartCharOffset() {
@@ -80,8 +83,9 @@
/**
* setter for start char offset
- *
- * @param startCharOffset start char offset
+ *
+ * @param startCharOffset
+ * start char offset
*/
public void setStartCharOffset(int startCharOffset) {
this.startCharOffset = startCharOffset;
@@ -89,7 +93,7 @@
/**
* getter of end char offset
- *
+ *
* @return end char offset
*/
public int getEndCharOffset() {
@@ -98,8 +102,9 @@
/**
* setter of end char offset
- *
- * @param endCharOffset end char offset
+ *
+ * @param endCharOffset
+ * end char offset
*/
public void setEndCharOffset(int endCharOffset) {
this.endCharOffset = endCharOffset;
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContext.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContext.java 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContext.java 2009-04-21 17:33:51 UTC (rev 16385)
@@ -9,4 +9,6 @@
public boolean isEntityName(String text);
public List getEntityImplementors(String text);
+
+ public String buildUniqueImplicitAlias();
}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContextDefaultImpl.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContextDefaultImpl.java 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/phase/hql/parse/ParserContextDefaultImpl.java 2009-04-21 17:33:51 UTC (rev 16385)
@@ -3,8 +3,12 @@
import java.util.ArrayList;
import java.util.List;
+import org.hibernate.sql.ast.alias.ImplicitAliasGenerator;
+
public class ParserContextDefaultImpl implements ParserContext {
+ private ImplicitAliasGenerator implicitAliasGenerator = new ImplicitAliasGenerator();
+
public List getEntityImplementors(String text) {
List implementors = new ArrayList();
implementors.add(text);
@@ -19,4 +23,8 @@
return false;
}
+ public String buildUniqueImplicitAlias() {
+ return implicitAliasGenerator.buildUniqueImplicitAlias();
+ }
+
}
Modified: core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/EntityNameTree.java
===================================================================
--- core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/EntityNameTree.java 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/main/java/org/hibernate/sql/ast/tree/EntityNameTree.java 2009-04-21 17:33:51 UTC (rev 16385)
@@ -4,20 +4,21 @@
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.Token;
-import org.antlr.runtime.tree.CommonTree;
+import org.hibernate.sql.ast.common.HibernateTree;
-public class EntityNameTree extends CommonTree {
+public class EntityNameTree extends HibernateTree {
private List entityNames = null;
private String outputText = null;
public EntityNameTree(EntityNameTree entityNameTree, String outputText) {
- this.token = entityNameTree.getToken();
+ super(entityNameTree.getToken());
this.outputText = outputText;
}
public EntityNameTree(int tokenType, Token token, String tokenText,
List entityNames) {
+ super(token);
Token newToken = createToken(token);
newToken.setType(tokenType);
newToken.setText(tokenText);
@@ -28,7 +29,15 @@
private Token createToken(Token fromToken) {
return new CommonToken(fromToken);
}
-
+
+ public int getEntityCount() {
+ return entityNames.size();
+ }
+
+ public String getEntityName(int index) {
+ return (String) entityNames.get(index);
+ }
+
public String toString() {
if (outputText == null) {
outputText = entityNames.get(0).toString();
Modified: core/branches/antlr3/src/test/gunit/org/hibernate/sql/ast/phase/hql/parse/TempgUnitHQLGrammar.testsuite
===================================================================
--- core/branches/antlr3/src/test/gunit/org/hibernate/sql/ast/phase/hql/parse/TempgUnitHQLGrammar.testsuite 2009-04-21 15:40:24 UTC (rev 16384)
+++ core/branches/antlr3/src/test/gunit/org/hibernate/sql/ast/phase/hql/parse/TempgUnitHQLGrammar.testsuite 2009-04-21 17:33:51 UTC (rev 16385)
@@ -26,6 +26,9 @@
"from org.hibernate.test.Inner i where i.outer.inner.middle = 'xyz'" OK
//testDynamicInstantiation
"select new list(a, mate) from Animal a join a.mate as mate" OK
+"from Animal join a.mate" OK
+"from Animal, aaa , dddd" OK
+"from Animal, aaa join fetch dddd" OK
//testListOrMapKeywordReference
"select p from eg.NameList nl, eg.Person p where p.name = some elements(nl.names)" OK
"select p from eg.NameList list, eg.Person p where p.name = some elements(list.names)" OK
@@ -1526,7 +1529,7 @@
//ASTParserLoadingTest.testDynamicInstantiationQueries
"select new list(an.description, an.bodyWeight) from Animal an" OK
"select new map(an.description, an.bodyWeight) from Animal an" OK
-"select new map(an.description as descr, an.bodyWeight as bw) from Animal an" -> (AAA)
+"select new map(an.description as descr, an.bodyWeight as bw) from Animal an" OK
//ASTParserLoadingTest.testResultTransformerScalarQueries
"select an.description as description, an.bodyWeight as bodyWeight from Animal an order by bodyWeight desc" OK
"select a from Animal a, Animal b order by a.id" OK
15 years, 7 months
Hibernate SVN: r16384 - validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine and 4 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-04-21 11:40:24 -0400 (Tue, 21 Apr 2009)
New Revision: 16384
Added:
validator/trunk/hibernate-validator-tck-runner/src/jboss-as/
validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.properties
validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.xml
validator/trunk/hibernate-validator-tck-runner/src/test/resources/jndi.properties
Modified:
beanvalidation/trunk/validation-tck/impl/src/main/java/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/ValidationXmlBootstrapTest.java
validator/trunk/hibernate-validator-tck-runner/pom.xml
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java
Log:
Setting up the framework for the TCK
Modified: beanvalidation/trunk/validation-tck/impl/src/main/java/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/ValidationXmlBootstrapTest.java
===================================================================
--- beanvalidation/trunk/validation-tck/impl/src/main/java/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/ValidationXmlBootstrapTest.java 2009-04-21 14:02:32 UTC (rev 16383)
+++ beanvalidation/trunk/validation-tck/impl/src/main/java/org/hibernate/jsr303/tck/tests/bootstrap/validationxml/ValidationXmlBootstrapTest.java 2009-04-21 15:40:24 UTC (rev 16384)
@@ -28,6 +28,7 @@
import org.jboss.testharness.impl.packaging.Classes;
import org.jboss.testharness.impl.packaging.Resource;
import org.jboss.testharness.impl.packaging.Resources;
+import org.jboss.testharness.impl.packaging.IntegrationTest;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.testng.annotations.Test;
@@ -38,6 +39,7 @@
* @author Hardy Ferentschik
*/
@Artifact
+@IntegrationTest
@Resources({
@Resource(destination = "WEB-INF/classes/META-INF/validation.xml", source = "validation.xml")
})
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java 2009-04-21 14:02:32 UTC (rev 16383)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConfigurationImpl.java 2009-04-21 15:40:24 UTC (rev 16384)
@@ -65,7 +65,7 @@
}
private static final Logger log = LoggerFactory.make();
- private static final String VALIDATION_XML_FILE = "/META-INF/validation.xml";
+ private static final String VALIDATION_XML_FILE = "META-INF/validation.xml";
private static final String VALIDATION_CONFIGURATION_XSD = "META-INF/validation-configuration-1.0.xsd";
private final MessageInterpolator defaultMessageInterpolator = new ResourceBundleMessageInterpolator();
Modified: validator/trunk/hibernate-validator-tck-runner/pom.xml
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/pom.xml 2009-04-21 14:02:32 UTC (rev 16383)
+++ validator/trunk/hibernate-validator-tck-runner/pom.xml 2009-04-21 15:40:24 UTC (rev 16384)
@@ -75,7 +75,7 @@
</suiteXmlFiles>
<argLine>-Xmx128m</argLine>
<forkMode>pertest</forkMode>
- <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ <!--redirectTestOutputToFile>true</redirectTestOutputToFile-->
</configuration>
</plugin>
<plugin>
@@ -167,7 +167,7 @@
</property>
<property>
<name>org.jboss.testharness.container.extraConfigurationDir</name>
- <value>../jboss-as</value>
+ <value>src/jboss-as</value>
</property>
<property>
<name>org.jboss.testharness.container.forceRestart</name>
Added: validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.properties
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.properties (rev 0)
+++ validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.properties 2009-04-21 15:40:24 UTC (rev 16384)
@@ -0,0 +1,13 @@
+# Container a number of properties associated with installing Web Beans into JBoss AS and running the TCK in JBoss AS
+jboss.home=/opt/java/jboss-5
+org.jboss.testharness.container.javaOpts=-Xms128m -Xmx384m -XX:MaxPermSize=128m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
+
+# time to allow before attempting to restart JBoss AS
+# org.jboss.testharness.container.shutdownDelay=15000
+
+# maximum number of TCK tests to deploy before restarting JBoss AS
+# jboss.deployments.restart = 25
+webbeans-ri-int.version=5.2.0.Beta2
+webbeans.version=1.0.0.PREVIEW1
+jboss-ejb3.version=1.0.0
+
Added: validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.xml
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.xml (rev 0)
+++ validator/trunk/hibernate-validator-tck-runner/src/jboss-as/build.xml 2009-04-21 15:40:24 UTC (rev 16384)
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<project name="JBoss5DeployerInstall" default="update" basedir="." xmlns:artifact="urn:maven-artifact-ant">
+
+ <path id="maven-ant-tasks.classpath" path="../lib/maven-ant-tasks.jar" />
+ <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
+
+ <property name="maven.dir" location="${basedir}/lib/maven" />
+
+ <property file="build.properties" />
+ <property file="local.build.properties" />
+
+ <target name="clean" description="Clean up after the JBoss updater">
+ <delete dir="target" failonerror="false" />
+ </target>
+
+ <target name="update" depends="install-webbeans.deployer" description="Update JBoss 5 for the Web Beans RI" />
+
+ <target name="install-webbeans.deployer">
+
+ <fail unless="jboss.home" message="Please pass in -Djboss.home=..." />
+
+ <delete dir="${jboss.home}/server/default/deployers/webbeans.deployer" failonerror="false" />
+ <delete dir="target" failonerror="false" />
+
+ <artifact:dependencies filesetId="webbeans.deployer.fileset" versionsId="webbeans.deployer.versions" >
+ <dependency groupId="org.jboss.webbeans.integration" artifactId="webbeans-jboss-int-deployer" version="${webbeans-ri-int.version}" type="zip" />
+ <dependency groupId="org.jboss.webbeans" artifactId="webbeans-core" version="${webbeans.version}" />
+ <remoteRepository id="repository.jboss.org" url="http://repository.jboss.org/maven2" />
+ <remoteRepository id="snapshots.jboss.org" url="http://snapshots.jboss.org/maven2" />
+ </artifact:dependencies>
+
+ <mkdir dir="target/dependency/lib" />
+ <copy todir="target/dependency/lib">
+ <fileset refid="webbeans.deployer.fileset" />
+ <chainedmapper>
+ <flattenmapper />
+ <mapper classpathref="maven-ant-tasks.classpath" classname="org.apache.maven.artifact.ant.VersionMapper" from="${webbeans.deployer.versions}" to="flatten" />
+ </chainedmapper>
+ </copy>
+
+ <unzip dest="target" src="target/dependency/lib/webbeans-jboss-int-deployer.zip" />
+
+ <copy todir="target/webbeans.deployer/lib-int/" overwrite="true">
+ <fileset dir="target/dependency/lib">
+ <include name="webbeans-core.jar" />
+ </fileset>
+ </copy>
+
+ <delete dir="target/dependency" />
+
+ <copy todir="${jboss.home}/server/default/deployers/webbeans.deployer">
+ <fileset dir="target/webbeans.deployer">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+
+
+ </target>
+
+ <target name="install-jboss-ejb3-update">
+
+ <fail unless="jboss.home" message="Please pass in -Djboss.home=..." />
+
+ <artifact:dependencies filesetId="jboss.ejb3.plugin.fileset" versionsId="jboss.ejb3.plugin.versions">
+ <dependency groupId="org.jboss.ejb3" artifactId="jboss-ejb3-plugin" version="${jboss-ejb3.version}" classifier="installer" />
+ <remoteRepository id="repository.jboss.org" url="http://repository.jboss.org/maven2" />
+ </artifact:dependencies>
+
+ <mkdir dir="target/ejb3.plugin" />
+ <copy todir="target/ejb3.plugin">
+ <fileset refid="jboss.ejb3.plugin.fileset" />
+ <chainedmapper>
+ <flattenmapper />
+ <mapper classpathref="maven-ant-tasks.classpath" classname="org.apache.maven.artifact.ant.VersionMapper" from="${jboss.ejb3.plugin.versions}" to="flatten" />
+ </chainedmapper>
+ </copy>
+ <java jar="target/ejb3.plugin/jboss-ejb3-plugin-installer.jar" fork="true" failonerror="true">
+ <arg line="${jboss.home}" />
+ </java>
+ </target>
+
+ <macrodef name="maven">
+ <attribute name="target" />
+ <attribute name="basedir" />
+ <element name="args" implicit="true" optional="true" />
+ <sequential>
+ <java classname="org.codehaus.classworlds.Launcher" fork="true" dir="@{basedir}" failonerror="true">
+ <classpath>
+ <fileset dir="${maven.dir}/boot">
+ <include name="*.jar" />
+ </fileset>
+ <fileset dir="${maven.dir}/bin">
+ <include name="*.*" />
+ </fileset>
+ </classpath>
+ <sysproperty key="classworlds.conf" value="${maven.dir}/bin/m2.conf" />
+ <sysproperty key="maven.home" value="${maven.dir}" />
+ <args />
+ <arg line="@{target}" />
+ </java>
+ </sequential>
+ </macrodef>
+
+</project>
Added: validator/trunk/hibernate-validator-tck-runner/src/test/resources/jndi.properties
===================================================================
--- validator/trunk/hibernate-validator-tck-runner/src/test/resources/jndi.properties (rev 0)
+++ validator/trunk/hibernate-validator-tck-runner/src/test/resources/jndi.properties 2009-04-21 15:40:24 UTC (rev 16384)
@@ -0,0 +1,4 @@
+#jboss JNDI properties
+java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
+java.naming.provider.url=jnp://localhost:1099
+java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
\ No newline at end of file
15 years, 7 months
Hibernate SVN: r16383 - in core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test: cascade and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: jcosta(a)redhat.com
Date: 2009-04-21 10:02:32 -0400 (Tue, 21 Apr 2009)
New Revision: 16383
Added:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Address.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Article.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Employee.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Light.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Lighter.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlAttributeOverrideTest.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlTest.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm.xml
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm2.xml
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm3.xml
Modified:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Author.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Song.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/orm.xml
Log:
JBPAPP-1078 EJB-413 - Removed a dependency on sequences for XMLTests and added a specific package with sequences, to be used only on databases which supports it. For trunk
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java 2009-04-21 14:01:06 UTC (rev 16382)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -15,6 +15,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.Dialect;
import org.hibernate.ejb.HibernatePersistence;
@@ -146,4 +147,33 @@
}
return config;
}
+
+ @Override
+ public void runBare() throws Throwable {
+
+ if (!appliesTo(Dialect.getDialect()))
+ return;
+
+ Throwable exception = null;
+ setUp();
+ try {
+ runTest();
+ } catch (Throwable running) {
+ exception = running;
+ } finally {
+ try {
+ tearDown();
+ } catch (Throwable tearingDown) {
+ if (exception == null)
+ exception = tearingDown;
+ }
+ }
+ if (exception != null)
+ throw exception;
+ }
+
+ public boolean appliesTo(Dialect dialect) {
+ return true;
+ }
+
}
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Author.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Author.java 2009-04-21 14:01:06 UTC (rev 16382)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Author.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -2,18 +2,15 @@
package org.hibernate.ejb.test.cascade;
import javax.persistence.Entity;
-import javax.persistence.Id;
import javax.persistence.GeneratedValue;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.GenerationType;
+import javax.persistence.Id;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Author {
- @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ENTITY2_SEQ")
- @SequenceGenerator(name = "ENTITY2_SEQ")
+ @Id @GeneratedValue
private Long id;
}
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Song.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Song.java 2009-04-21 14:01:06 UTC (rev 16382)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/cascade/Song.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -2,20 +2,18 @@
package org.hibernate.ejb.test.cascade;
import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
import javax.persistence.ManyToOne;
-import javax.persistence.GenerationType;
-import javax.persistence.SequenceGenerator;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Song {
- @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ENTITY1_SEQ")
- @SequenceGenerator(name = "ENTITY1_SEQ") private Long id;
+ @Id @GeneratedValue
+ private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Author author;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/orm.xml 2009-04-21 14:01:06 UTC (rev 16382)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/orm.xml 2009-04-21 14:02:32 UTC (rev 16383)
@@ -26,7 +26,7 @@
metadata-complete="false">
<attributes>
<id name="id">
- <generated-value strategy="SEQUENCE"/>
+ <generated-value strategy="AUTO"/>
</id>
</attributes>
</entity>
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Address.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Address.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Address.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,54 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Address {
+ private String street;
+ private String city;
+ private String state;
+ private String zip;
+
+ public Address() {
+ }
+
+ public Address(String street, String city, String state, String zip) {
+ this.street = street;
+ this.city = city;
+ this.state = state;
+ this.zip = zip;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getZip() {
+ return zip;
+ }
+
+ public void setZip(String zip) {
+ this.zip = zip;
+ }
+}
\ No newline at end of file
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Article.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Article.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Article.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,49 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.GeneratedValue;
+import javax.persistence.CascadeType;
+import javax.persistence.ManyToOne;
+import javax.persistence.JoinColumn;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+@Table(name = "ITEM")
+(a)org.hibernate.annotations.BatchSize(size = 10)
+public class Article {
+ private Integer id;
+ private String name;
+
+ private Article nextArticle;
+
+ @Id @GeneratedValue public Integer getId() {
+ return id;
+ }
+ public void setId(Integer id) {
+ this.id = id;
+ }
+ @Column(name="poopoo")
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ @ManyToOne(cascade = CascadeType.ALL)
+ @JoinColumn(name = "NEXT_MESSAGE_ID")
+ public Article getNextArticle() {
+ return nextArticle;
+ }
+
+ public void setNextArticle(Article nextArticle) {
+ this.nextArticle = nextArticle;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Employee.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Employee.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Employee.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,66 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Employee {
+ @Id
+ Long id;
+ String name;
+/*
+ @Embedded
+ @AttributeOverrides({
+ @AttributeOverride(name = "street", column = @Column(name = "HA_street")),
+ @AttributeOverride(name = "city", column = @Column(name = "HA_city")),
+ @AttributeOverride(name = "state", column = @Column(name = "HA_state")),
+ @AttributeOverride(name = "zip", column = @Column(name = "HA_zip")) })
+*/
+ Address homeAddress;
+
+/*
+ @Embedded
+ @AttributeOverrides({
+ @AttributeOverride(name = "street", column = @Column(name = "MA_street")),
+ @AttributeOverride(name = "city", column = @Column(name = "MA_city")),
+ @AttributeOverride(name = "state", column = @Column(name = "MA_state")),
+ @AttributeOverride(name = "zip", column = @Column(name = "MA_zip")) })
+*/
+ Address mailAddress;
+
+ 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 Address getHomeAddress() {
+ return homeAddress;
+ }
+
+ public void setHomeAddress(Address homeAddress) {
+ this.homeAddress = homeAddress;
+ }
+
+ public Address getMailAddress() {
+ return mailAddress;
+ }
+
+ public void setMailAddress(Address mailAddress) {
+ this.mailAddress = mailAddress;
+ }
+}
\ No newline at end of file
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Light.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Light.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Light.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,10 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Light {
+ public String name;
+ public String power;
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Lighter.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Lighter.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/Lighter.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,10 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class Lighter {
+ public String name;
+ public String power;
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlAttributeOverrideTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlAttributeOverrideTest.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlAttributeOverrideTest.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,41 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.ejb.test.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class XmlAttributeOverrideTest extends TestCase {
+
+ public void testAttributeOverriding() throws Exception {
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+
+ Employee e = new Employee();
+ e.setId(Long.valueOf(100));
+ e.setName("Bubba");
+ e.setHomeAddress(new Address("123 Main St", "New York", "NY", "11111"));
+ e.setMailAddress(new Address("P.O. Box 123", "New York", "NY", "11111"));
+
+ em.persist(e);
+
+ em.flush();
+
+ em.getTransaction().rollback();
+ em.close();
+ }
+
+ public Class[] getAnnotatedClasses() {
+ return new Class[0];
+ }
+
+ @Override
+ public String[] getEjb3DD() {
+ return new String[] {
+ "org/hibernate/ejb/test/xml/sequences/orm3.xml"
+ };
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlTest.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/XmlTest.java 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,34 @@
+//$Id: $
+package org.hibernate.ejb.test.xml.sequences;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.ejb.test.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class XmlTest extends TestCase {
+ public void testXmlMappingCorrectness() throws Exception {
+ EntityManager em = getOrCreateEntityManager();
+ em.close();
+ }
+
+ public Class[] getAnnotatedClasses() {
+ return new Class[0];
+ }
+
+ @Override
+ public boolean appliesTo(Dialect dialect) {
+ return dialect.supportsSequences();
+ }
+
+ @Override
+ public String[] getEjb3DD() {
+ return new String[] {
+ "org/hibernate/ejb/test/xml/sequences/orm.xml",
+ "org/hibernate/ejb/test/xml/sequences/orm2.xml",
+ };
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm.xml (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm.xml 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+ version="1.0"
+ >
+ <persistence-unit-metadata>
+ <persistence-unit-defaults>
+ <schema>MY_SCHEMA</schema>
+ <catalog>MY_CATALOG</catalog>
+ <access>PROPERTY</access>
+ <cascade-persist/>
+ </persistence-unit-defaults>
+ </persistence-unit-metadata>
+ <package>org.hibernate.ejb.test.xml.sequences</package>
+ <entity class="Light" metadata-complete="true" access="FIELD">
+ <attributes>
+ <id name="name">
+ <column name="fld_id"/>
+ </id>
+ <basic name="power"></basic>
+ </attributes>
+ </entity>
+ <entity class="Article"
+ metadata-complete="false">
+ <attributes>
+ <id name="id">
+ <generated-value strategy="SEQUENCE"/>
+ </id>
+ </attributes>
+ </entity>
+</entity-mappings>
\ No newline at end of file
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm2.xml
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm2.xml (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm2.xml 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
+ version="1.0"
+ >
+ <entity class="org.hibernate.ejb.test.xml.sequences.Lighter" name="ALighter" access="FIELD" metadata-complete="true">
+ <attributes>
+ <id name="name">
+ <column name="fld_id"/>
+ </id>
+ <basic name="power"></basic>
+ </attributes>
+ </entity>
+ <!-- entity class="NoPackageEntity" name="ALighter" access="FIELD" metadata-complete="true">
+ <attributes>
+ <id name="id"/>
+ <basic name="name"/>
+ </attributes>
+ </entity -->
+ <embeddable class="NoPackageEntity" access="FIELD">
+ <attributes>
+ <basic name="name"/>
+ </attributes>
+ </embeddable>
+</entity-mappings>
\ No newline at end of file
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm3.xml
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm3.xml (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/xml/sequences/orm3.xml 2009-04-21 14:02:32 UTC (rev 16383)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
+ version="1.0">
+
+ <entity class="org.hibernate.ejb.test.xml.sequences.Employee" metadata-complete="false" access="FIELD">
+ <attributes>
+ <id name="id"/>
+ <basic name="name"/>
+
+ <embedded name="homeAddress">
+ <attribute-override name="street">
+ <column name="home_street"/>
+ </attribute-override>
+ <attribute-override name="city">
+ <column name="home_city"/>
+ </attribute-override>
+ <attribute-override name="state">
+ <column name="home_state"/>
+ </attribute-override>
+ <attribute-override name="zip">
+ <column name="home_zip"/>
+ </attribute-override>
+ </embedded>
+
+ <embedded name="mailAddress">
+ <attribute-override name="street">
+ <column name="mail_street"/>
+ </attribute-override>
+ <attribute-override name="city">
+ <column name="mail_city"/>
+ </attribute-override>
+ <attribute-override name="state">
+ <column name="mail_state"/>
+ </attribute-override>
+ <attribute-override name="zip">
+ <column name="mail_zip"/>
+ </attribute-override>
+ </embedded>
+
+ </attributes>
+ </entity>
+
+ <embeddable class="org.hibernate.ejb.test.xml.sequences.Address">
+ <attributes>
+ <basic name="street"/>
+ <basic name="city"/>
+ <basic name="state"/>
+ <basic name="zip"/>
+ </attributes>
+ </embeddable>
+
+</entity-mappings>
\ No newline at end of file
15 years, 7 months