Hibernate SVN: r16189 - in core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2: access and 5 other directories.
by hibernate-commits@lists.jboss.org
Author: bstansberry(a)jboss.com
Date: 2009-03-19 15:51:15 -0400 (Thu, 19 Mar 2009)
New Revision: 16189
Modified:
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java
Log:
[HHH-3817] Don't cache stale data via putFromLoad
[HHH-3818] Handle evictAll "without regard for transactions"
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/BasicRegionAdapter.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -23,9 +23,13 @@
*/
package org.hibernate.cache.jbc2;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
@@ -42,7 +46,12 @@
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Option;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
-import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeInvalidated;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.ViewChanged;
+import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.ViewChangedEvent;
import org.jboss.cache.optimistic.DataVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,30 +62,52 @@
*
* @author Steve Ebersole
*/
-@CacheListener
public abstract class BasicRegionAdapter implements Region {
+ private enum InvalidateState { INVALID, CLEARING, VALID };
public static final String ITEM = CacheHelper.ITEM;
protected final Cache jbcCache;
protected final String regionName;
protected final Fqn regionFqn;
+ protected final Fqn internalFqn;
protected Node regionRoot;
protected final boolean optimistic;
protected final TransactionManager transactionManager;
protected final Logger log;
protected final Object regionRootMutex = new Object();
+ protected final Object memberId;
+ protected final boolean replication;
+ protected final Object invalidationMutex = new Object();
+ protected final AtomicReference<InvalidateState> invalidateState =
+ new AtomicReference<InvalidateState>(InvalidateState.VALID);
+ protected final Set<Object> currentView = new HashSet<Object>();
// protected RegionRootListener listener;
public BasicRegionAdapter(Cache jbcCache, String regionName, String regionPrefix) {
+
+ this.log = LoggerFactory.getLogger(getClass());
+
this.jbcCache = jbcCache;
this.transactionManager = jbcCache.getConfiguration().getRuntimeConfig().getTransactionManager();
this.regionName = regionName;
this.regionFqn = createRegionFqn(regionName, regionPrefix);
- optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
- log = LoggerFactory.getLogger(getClass());
+ this.internalFqn = CacheHelper.getInternalFqn(regionFqn);
+ this.optimistic = jbcCache.getConfiguration().getNodeLockingScheme() == NodeLockingScheme.OPTIMISTIC;
+ this.memberId = jbcCache.getLocalAddress();
+ this.replication = CacheHelper.isClusteredReplication(jbcCache);
+
+ this.jbcCache.addCacheListener(this);
+
+ synchronized (currentView) {
+ List view = jbcCache.getMembers();
+ if (view != null) {
+ currentView.addAll(view);
+ }
+ }
+
activateLocalClusterNode();
log.debug("Created Region for " + regionName + " -- regionPrefix is " + regionPrefix);
@@ -129,13 +160,13 @@
if (!regionRoot.isResident()) {
regionRoot.setResident(true);
}
+ establishInternalNodes();
}
catch (Exception e) {
throw new CacheException(e.getMessage(), e);
}
finally {
- if (tx != null)
- resume(tx);
+ resume(tx);
}
}
@@ -154,6 +185,7 @@
// For pessimistic locking, we just want to toss out our ref
// to any old invalid root node and get the latest (may be null)
if (!optimistic) {
+ establishInternalNodes();
regionRoot = jbcCache.getRoot().getChild( regionFqn );
return;
}
@@ -181,6 +213,7 @@
}
// Never evict this node
newRoot.setResident(true);
+ establishInternalNodes();
}
finally {
resume(tx);
@@ -189,6 +222,24 @@
}
}
+ private void establishInternalNodes()
+ {
+ synchronized (currentView) {
+ Transaction tx = suspend();
+ try {
+ for (Object member : currentView) {
+ DataVersion version = optimistic ? NonLockingDataVersion.INSTANCE : null;
+ Fqn f = Fqn.fromRelativeElements(internalFqn, member);
+ CacheHelper.addNode(jbcCache, f, true, false, version);
+ }
+ }
+ finally {
+ resume(tx);
+ }
+ }
+
+ }
+
public String getName() {
return regionName;
}
@@ -201,6 +252,11 @@
return regionFqn;
}
+ public Object getMemberId()
+ {
+ return this.memberId;
+ }
+
/**
* Checks for the validity of the root cache node for this region,
* creating a new one if it does not exist or is invalid, and also
@@ -219,6 +275,37 @@
if (regionRoot != null && regionRoot.isValid() && !regionRoot.isResident())
regionRoot.setResident(true);
}
+
+ public boolean checkValid()
+ {
+ boolean valid = invalidateState.get() == InvalidateState.VALID;
+
+ if (!valid) {
+ synchronized (invalidationMutex) {
+ if (invalidateState.compareAndSet(InvalidateState.INVALID, InvalidateState.CLEARING)) {
+ Transaction tx = suspend();
+ try {
+ Option opt = new Option();
+ opt.setLockAcquisitionTimeout(1);
+ opt.setCacheModeLocal(true);
+ CacheHelper.removeAll(jbcCache, regionFqn, opt);
+ invalidateState.compareAndSet(InvalidateState.CLEARING, InvalidateState.VALID);
+ }
+ catch (Exception e) {
+ if (log.isTraceEnabled()) {
+ log.trace("Could not invalidate region: " + e.getLocalizedMessage());
+ }
+ }
+ finally {
+ resume(tx);
+ }
+ }
+ }
+ valid = invalidateState.get() == InvalidateState.VALID;
+ }
+
+ return valid;
+ }
public void destroy() throws CacheException {
try {
@@ -242,10 +329,9 @@
} catch (Exception e) {
throw new CacheException(e);
}
-// finally {
-// if (listener != null)
-// jbcCache.removeCacheListener(listener);
-// }
+ finally {
+ jbcCache.removeCacheListener(this);
+ }
}
protected void deactivateLocalNode() {
@@ -262,12 +348,21 @@
}
public long getElementCountInMemory() {
- try {
- Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
- return childrenNames.size();
- } catch (Exception e) {
- throw new CacheException(e);
+ if (checkValid()) {
+ try {
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ int size = childrenNames.size();
+ if (childrenNames.contains(CacheHelper.Internal.NODE)) {
+ size--;
+ }
+ return size;
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
}
+ else {
+ return 0;
+ }
}
public long getElementCountOnDisk() {
@@ -275,18 +370,25 @@
}
public Map toMap() {
- try {
- Map result = new HashMap();
- Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
- for (Object childName : childrenNames) {
- result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
- }
- return result;
- } catch (CacheException e) {
- throw e;
- } catch (Exception e) {
- throw new CacheException(e);
+ if (checkValid()) {
+ try {
+ Map result = new HashMap();
+ Set childrenNames = CacheHelper.getChildrenNames(jbcCache, regionFqn);
+ for (Object childName : childrenNames) {
+ if (CacheHelper.Internal.NODE != childName) {
+ result.put(childName, CacheHelper.get(jbcCache,regionFqn, childName));
+ }
+ }
+ return result;
+ } catch (CacheException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new CacheException(e);
+ }
}
+ else {
+ return Collections.emptyMap();
+ }
}
public long nextTimestamp() {
@@ -320,6 +422,20 @@
resume(tx);
}
}
+
+ public Object getOwnerForPut()
+ {
+ Transaction tx = null;
+ try {
+ if (transactionManager != null) {
+ tx = transactionManager.getTransaction();
+ }
+ } catch (SystemException se) {
+ throw new CacheException("Could not obtain transaction", se);
+ }
+ return tx == null ? Thread.currentThread() : tx;
+
+ }
/**
* Tell the TransactionManager to suspend any ongoing transaction.
@@ -327,7 +443,7 @@
* @return the transaction that was suspended, or <code>null</code> if
* there wasn't one
*/
- protected Transaction suspend() {
+ public Transaction suspend() {
Transaction tx = null;
try {
if (transactionManager != null) {
@@ -345,7 +461,7 @@
* @param tx
* the transaction to suspend. May be <code>null</code>.
*/
- protected void resume(Transaction tx) {
+ public void resume(Transaction tx) {
try {
if (tx != null)
transactionManager.resume(tx);
@@ -404,17 +520,52 @@
return escaped;
}
-// @CacheListener
-// public class RegionRootListener {
-//
-// @NodeCreated
-// public void nodeCreated(NodeCreatedEvent event) {
-// if (!event.isPre() && event.getFqn().equals(getRegionFqn())) {
-// log.debug("Node created for " + getRegionFqn());
-// Node regionRoot = jbcCache.getRoot().getChild(getRegionFqn());
-// regionRoot.setResident(true);
-// }
-// }
-//
-// }
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent event)
+ {
+ handleEvictAllModification(event);
+ }
+
+ protected boolean handleEvictAllModification(NodeModifiedEvent event) {
+
+ if (!event.isPre() && (replication || event.isOriginLocal()) && event.getData().containsKey(ITEM))
+ {
+ if (event.getFqn().isChildOf(internalFqn))
+ {
+ invalidateState.set(InvalidateState.INVALID);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @NodeInvalidated
+ public void nodeInvalidated(NodeInvalidatedEvent event)
+ {
+ handleEvictAllInvalidation(event);
+ }
+
+ protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
+ {
+ if (!event.isPre() && event.getFqn().isChildOf(internalFqn))
+ {
+ invalidateState.set(InvalidateState.INVALID);
+ return true;
+ }
+ return false;
+ }
+
+ @ViewChanged
+ public void viewChanged(ViewChangedEvent event) {
+
+ synchronized (currentView) {
+ List view = event.getNewView().getMembers();
+ if (view != null) {
+ currentView.addAll(view);
+ establishInternalNodes();
+ }
+ }
+
+ }
+
}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/OptimisticTransactionalAccessDelegate.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -23,11 +23,12 @@
*/
package org.hibernate.cache.jbc2.access;
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.jbc2.BasicRegionAdapter;
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
import org.hibernate.cache.jbc2.util.CacheHelper;
import org.hibernate.cache.jbc2.util.DataVersionAdapter;
@@ -63,44 +64,43 @@
*/
@Override
public void evict(Object key) throws CacheException {
-
+ pendingPuts.remove(key);
region.ensureRegionRootExists();
Option opt = NonLockingDataVersion.getInvocationOption();
CacheHelper.remove(cache, regionFqn, key, opt);
- }
+ }
+
+
- /**
- * Overrides the {@link TransactionalAccessDelegate#evictAll() superclass}
- * by adding a {@link NonLockingDataVersion} to the invocation.
- */
@Override
- public void evictAll() throws CacheException {
-
- evictOrRemoveAll();
- }
-
- /**
- * Overrides the {@link TransactionalAccessDelegate#get(Object, long) superclass}
- * by {@link BasicRegionAdapter#ensureRegionRootExists() ensuring the root
- * node for the region exists} before making the call.
- */
- @Override
- public Object get(Object key, long txTimestamp) throws CacheException
+ public void evictAll() throws CacheException
{
- region.ensureRegionRootExists();
-
- return CacheHelper.get(cache, regionFqn, key);
+ pendingPuts.clear();
+ Transaction tx = region.suspend();
+ try {
+ region.ensureRegionRootExists();
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), opt);
+ }
+ finally {
+ region.resume(tx);
+ }
}
- /**
+ /**
* Overrides the
* {@link TransactionalAccessDelegate#insert(Object, Object, Object) superclass}
* by adding a {@link DataVersion} to the invocation.
*/
@Override
public boolean insert(Object key, Object value, Object version) throws CacheException {
+
+ pendingPuts.remove(key);
+ if (!region.checkValid())
+ return false;
+
region.ensureRegionRootExists();
Option opt = getDataVersionOption(version, null);
@@ -111,7 +111,13 @@
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
+
+ if (!region.checkValid())
+ return false;
+ if (!isPutValid(key))
+ return false;
+
region.ensureRegionRootExists();
// We ignore minimalPutOverride. JBossCache putForExternalRead is
@@ -123,7 +129,13 @@
@Override
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+
+ if (!region.checkValid())
+ return false;
+ if (!isPutValid(key))
+ return false;
+
region.ensureRegionRootExists();
Option opt = getDataVersionOption(version, version);
@@ -132,7 +144,13 @@
@Override
public void remove(Object key) throws CacheException {
+
+ pendingPuts.remove(key);
+ // We remove whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
Option opt = NonLockingDataVersion.getInvocationOption();
@@ -141,14 +159,21 @@
@Override
public void removeAll() throws CacheException {
-
- evictOrRemoveAll();
+ pendingPuts.clear();
+ Option opt = NonLockingDataVersion.getInvocationOption();
+ CacheHelper.removeAll(cache, regionFqn, opt);
}
@Override
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
+
+ pendingPuts.remove(key);
+ // We update whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
Option opt = getDataVersionOption(currentVersion, previousVersion);
@@ -166,10 +191,4 @@
return opt;
}
- private void evictOrRemoveAll() {
-
- Option opt = NonLockingDataVersion.getInvocationOption();
- CacheHelper.removeAll(cache, regionFqn, opt);
- }
-
}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/access/TransactionalAccessDelegate.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -23,6 +23,13 @@
*/
package org.hibernate.cache.jbc2.access;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
import org.hibernate.cache.access.EntityRegionAccessStrategy;
@@ -44,10 +51,12 @@
* @author Brian Stansberry
*/
public class TransactionalAccessDelegate {
-
+
protected final Cache cache;
protected final Fqn regionFqn;
protected final BasicRegionAdapter region;
+ protected final ConcurrentMap<Object, Set<Object>> pendingPuts =
+ new ConcurrentHashMap<Object, Set<Object>>();
public TransactionalAccessDelegate(BasicRegionAdapter adapter) {
this.region = adapter;
@@ -56,22 +65,43 @@
}
public Object get(Object key, long txTimestamp) throws CacheException {
-
+
+ if (!region.checkValid())
+ return null;
+
region.ensureRegionRootExists();
- return CacheHelper.get(cache, regionFqn, key);
+ Object val = CacheHelper.get(cache, regionFqn, key);
+
+ if (val == null) {
+ registerPendingPut(key);
+ }
+
+ return val;
}
- public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+ if (!region.checkValid())
+ return false;
+
+ if (!isPutValid(key))
+ return false;
+
region.ensureRegionRootExists();
return CacheHelper.putForExternalRead(cache, regionFqn, key, value);
}
- public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
+ public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
+ if (!region.checkValid())
+ return false;
+
+ if (!isPutValid(key))
+ return false;
+
region.ensureRegionRootExists();
// We ignore minimalPutOverride. JBossCache putForExternalRead is
@@ -96,6 +126,11 @@
public boolean insert(Object key, Object value, Object version) throws CacheException {
+ pendingPuts.remove(key);
+
+ if (!region.checkValid())
+ return false;
+
region.ensureRegionRootExists();
CacheHelper.put(cache, regionFqn, key, value);
@@ -109,6 +144,12 @@
public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
throws CacheException {
+ pendingPuts.remove(key);
+
+ // We update whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
CacheHelper.put(cache, regionFqn, key, value);
@@ -122,27 +163,74 @@
public void remove(Object key) throws CacheException {
+ pendingPuts.remove(key);
+
+ // We remove whether or not the region is valid. Other nodes
+ // may have already restored the region so they need to
+ // be informed of the change.
+
region.ensureRegionRootExists();
CacheHelper.remove(cache, regionFqn, key);
}
public void removeAll() throws CacheException {
- evictOrRemoveAll();
+ pendingPuts.clear();
+ CacheHelper.removeAll(cache, regionFqn);
}
public void evict(Object key) throws CacheException {
+ pendingPuts.remove(key);
+
region.ensureRegionRootExists();
CacheHelper.remove(cache, regionFqn, key);
}
public void evictAll() throws CacheException {
- evictOrRemoveAll();
+ pendingPuts.clear();
+ Transaction tx = region.suspend();
+ try {
+ region.ensureRegionRootExists();
+
+ CacheHelper.sendEvictAllNotification(cache, regionFqn, region.getMemberId(), null);
+ }
+ finally {
+ region.resume(tx);
+ }
}
-
- private void evictOrRemoveAll() throws CacheException {
- CacheHelper.removeAll(cache, regionFqn);
+
+ protected void registerPendingPut(Object key)
+ {
+ Set<Object> pending = pendingPuts.get(key);
+ if (pending == null) {
+ pending = new HashSet<Object>();
+ }
+
+ synchronized (pending) {
+ Object owner = region.getOwnerForPut();
+ pending.add(owner);
+ Set<Object> existing = pendingPuts.putIfAbsent(key, pending);
+ if (existing != pending) {
+ // try again
+ registerPendingPut(key);
+ }
+ }
}
+
+ protected boolean isPutValid(Object key)
+ {
+ boolean valid = false;
+ Set<Object> pending = pendingPuts.get(key);
+ if (pending != null) {
+ synchronized (pending) {
+ valid = pending.remove(region.getOwnerForPut());
+ if (valid && pending.size() == 0) {
+ pendingPuts.remove(key);
+ }
+ }
+ }
+ return valid;
+ }
}
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/collection/CollectionRegionImpl.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -26,6 +26,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.notifications.annotation.CacheListener;
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
@@ -39,6 +40,7 @@
*
* @author Steve Ebersole
*/
+@CacheListener
public class CollectionRegionImpl extends TransactionalDataRegionAdapter implements CollectionRegion {
public static final String TYPE = "COLL";
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/entity/EntityRegionImpl.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -26,6 +26,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.notifications.annotation.CacheListener;
import org.hibernate.cache.CacheDataDescription;
import org.hibernate.cache.CacheException;
@@ -39,6 +40,7 @@
*
* @author Steve Ebersole
*/
+@CacheListener
public class EntityRegionImpl extends TransactionalDataRegionAdapter implements EntityRegion {
public static final String TYPE = "ENTITY";
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/query/QueryResultsRegionImpl.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -25,6 +25,8 @@
import java.util.Properties;
+import javax.transaction.Transaction;
+
import org.hibernate.cache.CacheException;
import org.hibernate.cache.QueryResultsRegion;
import org.hibernate.cache.jbc2.TransactionalDataRegionAdapter;
@@ -33,6 +35,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Option;
+import org.jboss.cache.notifications.annotation.CacheListener;
/**
* Defines the behavior of the query cache regions for JBossCache 2.x.
@@ -40,6 +43,7 @@
* @author Brian Stansberry
* @version $Revision$
*/
+@CacheListener
public class QueryResultsRegionImpl extends TransactionalDataRegionAdapter implements QueryResultsRegion {
public static final String QUERY_CACHE_LOCAL_ONLY_PROP = "hibernate.cache.region.jbc2.query.localonly";
@@ -85,14 +89,22 @@
}
public void evictAll() throws CacheException {
- Option opt = getNonLockingDataVersionOption(false);
- if (localOnly)
- opt.setCacheModeLocal(true);
- CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
+ Transaction tx = suspend();
+ try {
+ ensureRegionRootExists();
+ Option opt = getNonLockingDataVersionOption(true);
+ CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
+ }
+ finally {
+ resume(tx);
+ }
}
public Object get(Object key) throws CacheException {
+ if (!checkValid())
+ return null;
+
ensureRegionRootExists();
// Don't hold the JBC node lock throughout the tx, as that
@@ -106,28 +118,30 @@
public void put(Object key, Object value) throws CacheException {
- ensureRegionRootExists();
-
- // Here we don't want to suspend the tx. If we do:
- // 1) We might be caching query results that reflect uncommitted
- // changes. No tx == no WL on cache node, so other threads
- // can prematurely see those query results
- // 2) No tx == immediate replication. More overhead, plus we
- // spread issue #1 above around the cluster
-
- // Add a zero (or quite low) timeout option so we don't block.
- // Ignore any TimeoutException. Basically we forego caching the
- // query result in order to avoid blocking.
- // Reads are done with suspended tx, so they should not hold the
- // lock for long. Not caching the query result is OK, since
- // any subsequent read will just see the old result with its
- // out-of-date timestamp; that result will be discarded and the
- // db query performed again.
- Option opt = getNonLockingDataVersionOption(false);
- opt.setLockAcquisitionTimeout(2);
- if (localOnly)
- opt.setCacheModeLocal(true);
- CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
+ if (checkValid()) {
+ ensureRegionRootExists();
+
+ // Here we don't want to suspend the tx. If we do:
+ // 1) We might be caching query results that reflect uncommitted
+ // changes. No tx == no WL on cache node, so other threads
+ // can prematurely see those query results
+ // 2) No tx == immediate replication. More overhead, plus we
+ // spread issue #1 above around the cluster
+
+ // Add a zero (or quite low) timeout option so we don't block.
+ // Ignore any TimeoutException. Basically we forego caching the
+ // query result in order to avoid blocking.
+ // Reads are done with suspended tx, so they should not hold the
+ // lock for long. Not caching the query result is OK, since
+ // any subsequent read will just see the old result with its
+ // out-of-date timestamp; that result will be discarded and the
+ // db query performed again.
+ Option opt = getNonLockingDataVersionOption(false);
+ opt.setLockAcquisitionTimeout(2);
+ if (localOnly)
+ opt.setCacheModeLocal(true);
+ CacheHelper.putAllowingTimeout(getCacheInstance(), getRegionFqn(), key, value, opt);
+ }
}
@Override
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -41,6 +41,7 @@
import org.jboss.cache.notifications.annotation.CacheListener;
import org.jboss.cache.notifications.annotation.NodeModified;
import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.event.NodeInvalidatedEvent;
import org.jboss.cache.notifications.event.NodeModifiedEvent;
import org.jboss.cache.notifications.event.NodeRemovedEvent;
@@ -95,14 +96,21 @@
public void evictAll() throws CacheException {
// TODO Is this a valid operation on a timestamps cache?
- Option opt = getNonLockingDataVersionOption(true);
- CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
+ Transaction tx = suspend();
+ try {
+ ensureRegionRootExists();
+ Option opt = getNonLockingDataVersionOption(true);
+ CacheHelper.sendEvictAllNotification(jbcCache, regionFqn, getMemberId(), opt);
+ }
+ finally {
+ resume(tx);
+ }
}
public Object get(Object key) throws CacheException {
Object value = localCache.get(key);
- if (value == null) {
+ if (value == null && checkValid()) {
ensureRegionRootExists();
@@ -147,14 +155,15 @@
*/
@NodeModified
public void nodeModified(NodeModifiedEvent event) {
- if (event.isPre())
- return;
-
- Fqn fqn = event.getFqn();
- Fqn regFqn = getRegionFqn();
- if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
- Object key = fqn.get(regFqn.size());
- localCache.put(key, event.getData().get(ITEM));
+
+ if (!handleEvictAllModification(event) && !event.isPre()) {
+
+ Fqn fqn = event.getFqn();
+ Fqn regFqn = getRegionFqn();
+ if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
+ Object key = fqn.get(regFqn.size());
+ localCache.put(key, event.getData().get(ITEM));
+ }
}
}
@@ -178,8 +187,30 @@
localCache.clear();
}
}
+
+
- /**
+ @Override
+ protected boolean handleEvictAllInvalidation(NodeInvalidatedEvent event)
+ {
+ boolean result = super.handleEvictAllInvalidation(event);
+ if (result) {
+ localCache.clear();
+ }
+ return result;
+ }
+
+ @Override
+ protected boolean handleEvictAllModification(NodeModifiedEvent event)
+ {
+ boolean result = super.handleEvictAllModification(event);
+ if (result) {
+ localCache.clear();
+ }
+ return result;
+ }
+
+ /**
* Brings all data from the distributed cache into our local cache.
*/
private void populateLocalCache() {
Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java 2009-03-19 16:07:46 UTC (rev 16188)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/util/CacheHelper.java 2009-03-19 19:51:15 UTC (rev 16189)
@@ -46,6 +46,8 @@
*/
public class CacheHelper {
+ public static enum Internal { NODE, LOCAL };
+
/** Key under which items are cached */
public static final String ITEM = "item";
/** Key and value used in a hack to create region root nodes */
@@ -467,4 +469,23 @@
option.setDataVersion(version);
setInvocationOption(cache, option);
}
+
+ public static Fqn getInternalFqn(Fqn region)
+ {
+ return Fqn.fromRelativeElements(region, Internal.NODE);
+ }
+
+ public static void sendEvictNotification(Cache cache, Fqn region, Object member, Object key, Option option)
+ {
+ setInvocationOption(cache, option);
+ Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member, key);
+ cache.put(f, ITEM, DUMMY);
+ }
+
+ public static void sendEvictAllNotification(Cache cache, Fqn region, Object member, Option option)
+ {
+ setInvocationOption(cache, option);
+ Fqn f = Fqn.fromRelativeElements(region, Internal.NODE, member == null ? Internal.LOCAL : member);
+ cache.put(f, ITEM, DUMMY);
+ }
}
15 years, 9 months
Hibernate SVN: r16188 - in validator/trunk: hibernate-validator/src/main/java/org/hibernate/validation/engine/groups and 7 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-19 12:07:46 -0400 (Thu, 19 Mar 2009)
New Revision: 16188
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/groups/GroupChainGenerator.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/ValidationMessages.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/CreditCard.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/ZipCodeCoherenceValidator.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/PostCodeListValidatorForNumber.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/PostCodeListValidatorForString.java
validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertion.java
validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertions.java
validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecVersion.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/EnumerationIterable.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/EnumerationIterator.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/ResourceLoadingException.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/RuntimeProperties.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/SimpleResourceLoader.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/Strings.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/AuditAssertion.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/AuditParser.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/SpecReference.java
Log:
Enabled keyword substitution
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/DefaultValidationProviderResolver.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MessageInterpolatorContext.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/groups/GroupChainGenerator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/ValidationMessages.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/CreditCard.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/ZipCodeCoherenceValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java 2009-03-19 16:00:24 UTC (rev 16187)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java 2009-03-19 16:07:46 UTC (rev 16188)
@@ -1,4 +1,4 @@
-// $Id: ElementDescriptorTest.java 16185 2009-03-19 13:55:43Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/PostCodeListValidatorForNumber.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/PostCodeListValidatorForString.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertion.java
===================================================================
--- validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertion.java 2009-03-19 16:00:24 UTC (rev 16187)
+++ validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertion.java 2009-03-19 16:07:46 UTC (rev 16188)
@@ -1,4 +1,4 @@
-// $Id: SpecAssertion.java 15909 2009-02-06 10:26:41Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertion.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertions.java
===================================================================
--- validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertions.java 2009-03-19 16:00:24 UTC (rev 16187)
+++ validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertions.java 2009-03-19 16:07:46 UTC (rev 16188)
@@ -1,4 +1,4 @@
-// $Id: SpecAssertion.java 15705 2008-12-18 16:21:24Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecAssertions.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecVersion.java
===================================================================
--- validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecVersion.java 2009-03-19 16:00:24 UTC (rev 16187)
+++ validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecVersion.java 2009-03-19 16:07:46 UTC (rev 16188)
@@ -1,4 +1,4 @@
-// $Id: SpecVersion.java 15705 2008-12-18 16:21:24Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/tck-utils/api/src/main/java/org/hibernate/tck/annotations/SpecVersion.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/EnumerationIterable.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/EnumerationIterator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/ResourceLoadingException.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/RuntimeProperties.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/SimpleResourceLoader.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/config/Strings.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/AuditAssertion.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/AuditParser.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageProcessor.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/CoverageReport.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/tck-utils/impl/src/main/java/org/hibernate/tck/report/SpecReference.java
___________________________________________________________________
Name: svn:keywords
+ Id
15 years, 9 months
Hibernate SVN: r16187 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validation/engine/metadata and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-19 12:00:24 -0400 (Thu, 19 Mar 2009)
New Revision: 16187
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ConstraintDescriptorTest.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
Log:
HV-116
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java 2009-03-19 14:16:07 UTC (rev 16186)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java 2009-03-19 16:00:24 UTC (rev 16187)
@@ -137,44 +137,26 @@
}
}
- /**
- * {@inheritDoc}
- */
public T getAnnotation() {
return annotation;
}
- /**
- * {@inheritDoc}
- */
public Set<Class<?>> getGroups() {
return Collections.unmodifiableSet( groups );
}
- /**
- * {@inheritDoc}
- */
public List<Class<? extends ConstraintValidator<T, ?>>> getConstraintValidatorClasses() {
return Collections.unmodifiableList( constraintValidatorDefinitonClasses );
}
- /**
- * {@inheritDoc}
- */
public Map<String, Object> getAttributes() {
return Collections.unmodifiableMap( attributes );
}
- /**
- * {@inheritDoc}
- */
public Set<ConstraintDescriptor<?>> getComposingConstraints() {
return Collections.unmodifiableSet( composingConstraints );
}
- /**
- * {@inheritDoc}
- */
public boolean isReportAsSingleViolation() {
return isReportAsSingleInvalidConstraint;
}
Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ConstraintDescriptorTest.java (from rev 16186, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ConstraintDescriptorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ConstraintDescriptorTest.java 2009-03-19 16:00:24 UTC (rev 16187)
@@ -0,0 +1,136 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.constraints.NotNull;
+import javax.validation.groups.Default;
+
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.hibernate.validation.constraints.NotNullValidator;
+import org.hibernate.validation.engine.Order;
+import org.hibernate.validation.engine.constraintcomposition.GermanAddress;
+import org.hibernate.validation.util.TestUtil;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ConstraintDescriptorTest {
+ @Test
+ public void testConstraintDescriptorImmutable() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+
+ try {
+ descriptor.getGroups().add( Default.class );
+ fail( "Should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ descriptor.getAttributes().put( "foo", "bar" );
+ fail( "Should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ descriptor.getConstraintValidatorClasses().add( null );
+ fail( "Should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ descriptor.getComposingConstraints().add( null );
+ fail( "Should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+ }
+
+ @Test
+ public void testReportAsSingleViolation() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ assertFalse( descriptor.isReportAsSingleViolation() );
+
+ descriptor = TestUtil.getSingleConstraintDescriptorFor( GermanAddress.class, "zipCode" );
+ assertTrue( descriptor.isReportAsSingleViolation() );
+ }
+
+ @Test
+ public void testComposingConstraints() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ assertTrue( descriptor.getComposingConstraints().isEmpty() );
+ }
+
+ /**
+ * @todo Is getComposingConstraints() recursive and hence the result should be 4?
+ */
+ @Test
+ public void testEmptyComposingConstraints() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor(
+ GermanAddress.class, "zipCode"
+ );
+ assertEquals( "Wrong number of composing constraints", 1, descriptor.getComposingConstraints().size() );
+ }
+
+ @Test
+ public void testGetAnnotation() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ Annotation annotation = descriptor.getAnnotation();
+ assertNotNull( annotation );
+ assertTrue( annotation instanceof NotNull );
+ }
+
+ @Test
+ public void testDefaultGroupIsReturned() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ Set<Class<?>> groups = descriptor.getGroups();
+ assertTrue( groups.size() == 1 );
+ assertEquals( "Wrong group", Default.class, groups.iterator().next() );
+ }
+
+ @Test
+ public void testGetConstraintValidatorClasses() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ assertEquals( "Wrong classes", NotNullValidator.class, descriptor.getConstraintValidatorClasses().get( 0 ) );
+ }
+
+ @Test
+ public void testGetAttributes() {
+ ConstraintDescriptor<?> descriptor = TestUtil.getSingleConstraintDescriptorFor( Order.class, "orderNumber" );
+ Map<String, Object> attributes = descriptor.getAttributes();
+ assertTrue( attributes.containsKey( "message" ) );
+ assertTrue( attributes.containsKey( "groups" ) );
+ }
+}
\ No newline at end of file
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ConstraintDescriptorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java 2009-03-19 14:16:07 UTC (rev 16186)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java 2009-03-19 16:00:24 UTC (rev 16187)
@@ -46,9 +46,7 @@
@Test
public void testGetTypeForConstrainedProperty() {
- Validator validator = TestUtil.getValidator();
- ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
+ ElementDescriptor elementDescriptor = TestUtil.getPropertyDescriptor( Order.class, "orderNumber" );
assertEquals( "Wrong type.", Integer.class, elementDescriptor.getType() );
}
@@ -57,9 +55,7 @@
*/
@Test
public void testElementDescriptorForProperty() {
- Validator validator = TestUtil.getValidator();
- ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
+ ElementDescriptor elementDescriptor = TestUtil.getPropertyDescriptor( Order.class, "orderNumber" );
Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
assertTrue( "There should be a descriptor", constraintDescriptors.size() == 1 );
}
@@ -69,14 +65,11 @@
*/
@Test
public void testElementDescriptorImmutable() {
- Validator validator = TestUtil.getValidator();
- ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
+ ElementDescriptor elementDescriptor = TestUtil.getPropertyDescriptor( Order.class, "orderNumber" );
Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
- ConstraintDescriptor<?> descriptor = constraintDescriptors.iterator().next();
try {
- constraintDescriptors.add( descriptor );
+ constraintDescriptors.add( null );
fail( "Set should be immutable" );
}
catch ( UnsupportedOperationException e ) {
@@ -84,7 +77,7 @@
}
try {
- constraintDescriptors.remove( descriptor );
+ constraintDescriptors.remove( null );
fail( "Set should be immutable" );
}
catch ( UnsupportedOperationException e ) {
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java 2009-03-19 14:16:07 UTC (rev 16186)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java 2009-03-19 16:00:24 UTC (rev 16187)
@@ -18,7 +18,6 @@
package org.hibernate.validation.engine.metadata;
import javax.validation.PropertyDescriptor;
-import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -35,26 +34,20 @@
public class PropertyDescriptorTest {
@Test
public void testIsNotCascaded() {
- Validator validator = TestUtil.getValidator();
- PropertyDescriptor descriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
+ PropertyDescriptor descriptor = TestUtil.getPropertyDescriptor( Order.class, "orderNumber" );
assertFalse( "Should not be cascaded", descriptor.isCascaded() );
}
@Test
public void testIsCascaded() {
- Validator validator = TestUtil.getValidator();
- PropertyDescriptor descriptor = validator.getConstraintsForClass( Customer.class )
- .getConstraintsForProperty( "orderList" );
+ PropertyDescriptor descriptor = TestUtil.getPropertyDescriptor( Customer.class, "orderList" );
assertTrue( "Should be cascaded", descriptor.isCascaded() );
}
@Test
public void testPropertyName() {
- Validator validator = TestUtil.getValidator();
String propertyName = "orderList";
- PropertyDescriptor descriptor = validator.getConstraintsForClass( Customer.class )
- .getConstraintsForProperty( propertyName );
+ PropertyDescriptor descriptor = TestUtil.getPropertyDescriptor( Customer.class, propertyName );
assertEquals( "Wrong property name", propertyName, descriptor.getPropertyName() );
}
}
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java 2009-03-19 14:16:07 UTC (rev 16186)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java 2009-03-19 16:00:24 UTC (rev 16187)
@@ -18,11 +18,15 @@
package org.hibernate.validation.util;
import java.util.Set;
+import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintViolation;
+import javax.validation.ElementDescriptor;
import javax.validation.Validation;
import javax.validation.Validator;
+import javax.validation.PropertyDescriptor;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.hibernate.validation.engine.HibernateValidatorConfiguration;
@@ -48,7 +52,25 @@
return hibernateValidator;
}
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
+ public static ConstraintDescriptor<?> getSingleConstraintDescriptorFor(Class<?> clazz, String property) {
+ Set<ConstraintDescriptor<?>> constraintDescriptors = getConstraintDescriptorsFor( clazz, property );
+ assertTrue(
+ "This method should only be used when there is a single constraint", constraintDescriptors.size() == 1
+ );
+ return constraintDescriptors.iterator().next();
+ }
+
+ public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String property) {
+ Validator validator = getValidator();
+ return validator.getConstraintsForClass( clazz ).getConstraintsForProperty( property );
+ }
+
+ public static Set<ConstraintDescriptor<?>> getConstraintDescriptorsFor(Class<?> clazz, String property) {
+ ElementDescriptor elementDescriptor = getPropertyDescriptor( clazz, property );
+ return elementDescriptor.getConstraintDescriptors();
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
assertEquals(
"Wrong leaf bean type",
leafBean,
15 years, 9 months
Hibernate SVN: r16186 - validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-19 10:16:07 -0400 (Thu, 19 Mar 2009)
New Revision: 16186
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
Removed:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java
Log:
HV-116
Deleted: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java 2009-03-19 13:55:43 UTC (rev 16185)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java 2009-03-19 14:16:07 UTC (rev 16186)
@@ -1,165 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.engine.metadata;
-
-import java.util.Set;
-import javax.validation.BeanDescriptor;
-import javax.validation.PropertyDescriptor;
-import javax.validation.Validator;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.fail;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import org.junit.Test;
-
-import org.hibernate.validation.engine.Order;
-import org.hibernate.validation.util.TestUtil;
-
-
-/**
- * @author Hardy Ferentschik
- */
-public class BeanDescriptorImplTest {
-
- @Test
- public void testIsBeanConstrained() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
-
- // constraint via @Valid
- assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
- assertTrue( "Bean should be constrainted due to @valid ", beanDescriptor.isBeanConstrained() );
-
- // constraint hosted on bean itself
- beanDescriptor = validator.getConstraintsForClass( Account.class );
- assertTrue( "There should be direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
- assertTrue( "Bean should be constrainted due to @valid", beanDescriptor.isBeanConstrained() );
-
- // constraint on bean property
- beanDescriptor = validator.getConstraintsForClass( Order.class );
- assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
- assertTrue( "Bean should be constrainted due to @NotNull", beanDescriptor.isBeanConstrained() );
- }
-
- @Test
- public void testUnconstraintClass() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
- assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
- assertFalse( "Bean should be unconstrainted.", beanDescriptor.isBeanConstrained() );
- }
-
- @Test
- public void testGetConstraintForExistingConstrainedProperty() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
- PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderNumber" );
- assertEquals(
- "There should be one constraint descriptor", 1, propertyDescriptor.getConstraintDescriptors().size()
- );
-
- beanDescriptor = validator.getConstraintsForClass( Customer.class );
- propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
- assertEquals(
- "There should be no constraint descriptors", 0, propertyDescriptor.getConstraintDescriptors().size()
- );
- assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
- }
-
- @Test
- public void testGetConstraintForUnConstrainedProperty() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
- PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
- assertEquals(
- "There should be no constraint descriptors", 0, propertyDescriptor.getConstraintDescriptors().size()
- );
- assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
- }
-
- @Test
- public void testGetConstraintsForNonExistingProperty() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
- assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( "foobar" ) );
- }
-
- /**
- * @todo Is this corect or should we get a IllegalArgumentException
- */
- @Test
- public void testGetConstraintsForNullProperty() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
- assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( null ) );
- }
-
- /**
- * HV-95
- */
- @Test
- public void testGetConstrainedProperties() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
- Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
- assertEquals( "There should be only one property", 1, constraintProperties.size() );
- boolean hasOrderNumber = false;
- for ( PropertyDescriptor pd : constraintProperties ) {
- hasOrderNumber |= pd.getPropertyName().equals( "orderNumber" );
- }
- assertTrue( "Wrong property", hasOrderNumber );
- }
-
- /**
- * HV-95
- */
- @Test
- public void testGetConstrainedPropertiesImmutable() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
- Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
- try {
- constraintProperties.add( null );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
-
- try {
- constraintProperties.remove( constraintProperties.iterator().next() );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
- }
-
- /**
- * HV-95
- */
- @Test
- public void testGetConstrainedPropertiesForUnconstraintEntity() {
- Validator validator = TestUtil.getValidator();
- BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
- Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
- assertEquals( "We should get the empty set.", 0, constraintProperties.size() );
- }
-}
Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorTest.java (from rev 16185, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorTest.java 2009-03-19 14:16:07 UTC (rev 16186)
@@ -0,0 +1,165 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import java.util.Set;
+import javax.validation.BeanDescriptor;
+import javax.validation.PropertyDescriptor;
+import javax.validation.Validator;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.hibernate.validation.engine.Order;
+import org.hibernate.validation.util.TestUtil;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class BeanDescriptorTest {
+
+ @Test
+ public void testIsBeanConstrained() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
+
+ // constraint via @Valid
+ assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertTrue( "Bean should be constrainted due to @valid ", beanDescriptor.isBeanConstrained() );
+
+ // constraint hosted on bean itself
+ beanDescriptor = validator.getConstraintsForClass( Account.class );
+ assertTrue( "There should be direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertTrue( "Bean should be constrainted due to @valid", beanDescriptor.isBeanConstrained() );
+
+ // constraint on bean property
+ beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertTrue( "Bean should be constrainted due to @NotNull", beanDescriptor.isBeanConstrained() );
+ }
+
+ @Test
+ public void testUnconstraintClass() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
+ assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertFalse( "Bean should be unconstrainted.", beanDescriptor.isBeanConstrained() );
+ }
+
+ @Test
+ public void testGetConstraintForExistingConstrainedProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderNumber" );
+ assertEquals(
+ "There should be one constraint descriptor", 1, propertyDescriptor.getConstraintDescriptors().size()
+ );
+
+ beanDescriptor = validator.getConstraintsForClass( Customer.class );
+ propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
+ assertEquals(
+ "There should be no constraint descriptors", 0, propertyDescriptor.getConstraintDescriptors().size()
+ );
+ assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
+ }
+
+ @Test
+ public void testGetConstraintForUnConstrainedProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
+ PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
+ assertEquals(
+ "There should be no constraint descriptors", 0, propertyDescriptor.getConstraintDescriptors().size()
+ );
+ assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
+ }
+
+ @Test
+ public void testGetConstraintsForNonExistingProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( "foobar" ) );
+ }
+
+ /**
+ * @todo Is this corect or should we get a IllegalArgumentException
+ */
+ @Test
+ public void testGetConstraintsForNullProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( null ) );
+ }
+
+ /**
+ * HV-95
+ */
+ @Test
+ public void testGetConstrainedProperties() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
+ assertEquals( "There should be only one property", 1, constraintProperties.size() );
+ boolean hasOrderNumber = false;
+ for ( PropertyDescriptor pd : constraintProperties ) {
+ hasOrderNumber |= pd.getPropertyName().equals( "orderNumber" );
+ }
+ assertTrue( "Wrong property", hasOrderNumber );
+ }
+
+ /**
+ * HV-95
+ */
+ @Test
+ public void testGetConstrainedPropertiesImmutable() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
+ try {
+ constraintProperties.add( null );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ constraintProperties.remove( constraintProperties.iterator().next() );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+ }
+
+ /**
+ * HV-95
+ */
+ @Test
+ public void testGetConstrainedPropertiesForUnconstraintEntity() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
+ Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
+ assertEquals( "We should get the empty set.", 0, constraintProperties.size() );
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Deleted: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java 2009-03-19 13:55:43 UTC (rev 16185)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java 2009-03-19 14:16:07 UTC (rev 16186)
@@ -1,65 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-* http://www.apache.org/licenses/LICENSE-2.0
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.hibernate.validation.engine.metadata;
-
-import java.util.Set;
-import javax.validation.ConstraintDescriptor;
-import javax.validation.ElementDescriptor;
-import javax.validation.Validator;
-
-import static junit.framework.Assert.fail;
-import static org.junit.Assert.assertTrue;
-import org.junit.Test;
-
-import org.hibernate.validation.engine.Order;
-import org.hibernate.validation.util.TestUtil;
-
-
-/**
- * @author Hardy Ferentschik
- */
-public class ElementDescriptorImplTest {
- /**
- * HV-95
- */
- @Test
- public void testElementDescriptorImmutable() {
- Validator validator = TestUtil.getValidator();
- ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
- Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
- assertTrue( "There should be a ConstraintDescriptor", constraintDescriptors.size() == 1 );
- ConstraintDescriptor<?> descriptor = constraintDescriptors.iterator().next();
-
- try {
- constraintDescriptors.add( descriptor );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
-
- try {
- constraintDescriptors.remove( descriptor );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
- }
-}
\ No newline at end of file
Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java (from rev 16185, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java 2009-03-19 14:16:07 UTC (rev 16186)
@@ -0,0 +1,94 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import java.util.Set;
+import javax.validation.BeanDescriptor;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ElementDescriptor;
+import javax.validation.Validator;
+
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.hibernate.validation.engine.Order;
+import org.hibernate.validation.util.TestUtil;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ElementDescriptorTest {
+
+ @Test
+ public void testGetTypeForConstrainedBean() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
+ assertEquals( "Wrong type.", Customer.class, beanDescriptor.getType() );
+ }
+
+ @Test
+ public void testGetTypeForConstrainedProperty() {
+ Validator validator = TestUtil.getValidator();
+ ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
+ .getConstraintsForProperty( "orderNumber" );
+ assertEquals( "Wrong type.", Integer.class, elementDescriptor.getType() );
+ }
+
+ /**
+ * HV-95
+ */
+ @Test
+ public void testElementDescriptorForProperty() {
+ Validator validator = TestUtil.getValidator();
+ ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
+ .getConstraintsForProperty( "orderNumber" );
+ Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
+ assertTrue( "There should be a descriptor", constraintDescriptors.size() == 1 );
+ }
+
+ /**
+ * HV-95
+ */
+ @Test
+ public void testElementDescriptorImmutable() {
+ Validator validator = TestUtil.getValidator();
+ ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
+ .getConstraintsForProperty( "orderNumber" );
+ Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
+ ConstraintDescriptor<?> descriptor = constraintDescriptors.iterator().next();
+
+ try {
+ constraintDescriptors.add( descriptor );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ constraintDescriptors.remove( descriptor );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+ }
+}
\ No newline at end of file
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorTest.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/PropertyDescriptorTest.java 2009-03-19 14:16:07 UTC (rev 16186)
@@ -0,0 +1,60 @@
+// $Id: ElementDescriptorTest.java 16185 2009-03-19 13:55:43Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import javax.validation.PropertyDescriptor;
+import javax.validation.Validator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.hibernate.validation.engine.Order;
+import org.hibernate.validation.util.TestUtil;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class PropertyDescriptorTest {
+ @Test
+ public void testIsNotCascaded() {
+ Validator validator = TestUtil.getValidator();
+ PropertyDescriptor descriptor = validator.getConstraintsForClass( Order.class )
+ .getConstraintsForProperty( "orderNumber" );
+ assertFalse( "Should not be cascaded", descriptor.isCascaded() );
+ }
+
+ @Test
+ public void testIsCascaded() {
+ Validator validator = TestUtil.getValidator();
+ PropertyDescriptor descriptor = validator.getConstraintsForClass( Customer.class )
+ .getConstraintsForProperty( "orderList" );
+ assertTrue( "Should be cascaded", descriptor.isCascaded() );
+ }
+
+ @Test
+ public void testPropertyName() {
+ Validator validator = TestUtil.getValidator();
+ String propertyName = "orderList";
+ PropertyDescriptor descriptor = validator.getConstraintsForClass( Customer.class )
+ .getConstraintsForProperty( propertyName );
+ assertEquals( "Wrong property name", propertyName, descriptor.getPropertyName() );
+ }
+}
\ No newline at end of file
15 years, 9 months
Hibernate SVN: r16185 - validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-19 09:55:43 -0400 (Thu, 19 Mar 2009)
New Revision: 16185
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountChecker.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountValidator.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/Account.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java
Log:
HV-116
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/Account.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/Account.java 2009-03-19 11:58:06 UTC (rev 16184)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/Account.java 2009-03-19 13:55:43 UTC (rev 16185)
@@ -18,12 +18,14 @@
package org.hibernate.validation.engine.metadata;
import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
import org.hibernate.validation.engine.metadata.Customer;
/**
* Class with no constraints but with a cascade @Valid annotation
*/
+@AccountChecker
public class Account {
private String accountLogin;
private Customer customer;
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountChecker.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountChecker.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountChecker.java 2009-03-19 13:55:43 UTC (rev 16185)
@@ -0,0 +1,43 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Constraint(validatedBy = AccountValidator.class)
+@Documented
+@Target({ METHOD, FIELD, TYPE })
+@Retention(RUNTIME)
+public @interface AccountChecker {
+
+ public abstract String message() default "Account information inconsistent.";
+
+ public abstract Class<?>[] groups() default { };
+}
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountChecker.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountValidator.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountValidator.java 2009-03-19 13:55:43 UTC (rev 16185)
@@ -0,0 +1,34 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class AccountValidator implements ConstraintValidator<AccountChecker, Account> {
+
+ public void initialize(AccountChecker parameters) {
+ }
+
+ public boolean isValid(Account account, ConstraintValidatorContext constraintValidatorContext) {
+ return false;
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/AccountValidator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java 2009-03-19 11:58:06 UTC (rev 16184)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java 2009-03-19 13:55:43 UTC (rev 16185)
@@ -19,8 +19,6 @@
import java.util.Set;
import javax.validation.BeanDescriptor;
-import javax.validation.ConstraintDescriptor;
-import javax.validation.ElementDescriptor;
import javax.validation.PropertyDescriptor;
import javax.validation.Validator;
@@ -31,10 +29,7 @@
import static org.junit.Assert.assertTrue;
import org.junit.Test;
-import org.hibernate.validation.engine.metadata.Account;
-import org.hibernate.validation.engine.metadata.Customer;
import org.hibernate.validation.engine.Order;
-import org.hibernate.validation.engine.metadata.UnconstraintEntity;
import org.hibernate.validation.util.TestUtil;
@@ -44,30 +39,35 @@
public class BeanDescriptorImplTest {
@Test
- public void testHasConstraintsAndIsBeanConstrained() {
+ public void testIsBeanConstrained() {
Validator validator = TestUtil.getValidator();
BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
+ // constraint via @Valid
assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
assertTrue( "Bean should be constrainted due to @valid ", beanDescriptor.isBeanConstrained() );
+ // constraint hosted on bean itself
beanDescriptor = validator.getConstraintsForClass( Account.class );
- assertTrue(
- "Bean should be constrainted due to @valid", beanDescriptor.isBeanConstrained()
- );
+ assertTrue( "There should be direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertTrue( "Bean should be constrainted due to @valid", beanDescriptor.isBeanConstrained() );
+
+ // constraint on bean property
+ beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertTrue( "Bean should be constrainted due to @NotNull", beanDescriptor.isBeanConstrained() );
}
@Test
public void testUnconstraintClass() {
Validator validator = TestUtil.getValidator();
- assertFalse(
- "There should be no constraints",
- validator.getConstraintsForClass( UnconstraintEntity.class ).hasConstraints()
- );
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
+ assertFalse( "There should be no direct constraints on the specified bean.", beanDescriptor.hasConstraints() );
+ assertFalse( "Bean should be unconstrainted.", beanDescriptor.isBeanConstrained() );
}
@Test
- public void testGetConstraintsForProperty() {
+ public void testGetConstraintForExistingConstrainedProperty() {
Validator validator = TestUtil.getValidator();
BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderNumber" );
@@ -75,11 +75,6 @@
"There should be one constraint descriptor", 1, propertyDescriptor.getConstraintDescriptors().size()
);
- assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( "foobar" ) );
-
- // TODO Is this corect or should we get a IllegalArgumentException
- assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( null ) );
-
beanDescriptor = validator.getConstraintsForClass( Customer.class );
propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
assertEquals(
@@ -88,7 +83,35 @@
assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
}
+ @Test
+ public void testGetConstraintForUnConstrainedProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Customer.class );
+ PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( "orderList" );
+ assertEquals(
+ "There should be no constraint descriptors", 0, propertyDescriptor.getConstraintDescriptors().size()
+ );
+ assertTrue( "The property should be cascaded", propertyDescriptor.isCascaded() );
+ }
+
+ @Test
+ public void testGetConstraintsForNonExistingProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( "foobar" ) );
+ }
+
/**
+ * @todo Is this corect or should we get a IllegalArgumentException
+ */
+ @Test
+ public void testGetConstraintsForNullProperty() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ assertNull( "There should be no descriptor", beanDescriptor.getConstraintsForProperty( null ) );
+ }
+
+ /**
* HV-95
*/
@Test
@@ -98,12 +121,20 @@
Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
assertEquals( "There should be only one property", 1, constraintProperties.size() );
boolean hasOrderNumber = false;
- for(PropertyDescriptor pd : constraintProperties) {
+ for ( PropertyDescriptor pd : constraintProperties ) {
hasOrderNumber |= pd.getPropertyName().equals( "orderNumber" );
}
assertTrue( "Wrong property", hasOrderNumber );
+ }
-
+ /**
+ * HV-95
+ */
+ @Test
+ public void testGetConstrainedPropertiesImmutable() {
+ Validator validator = TestUtil.getValidator();
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+ Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
try {
constraintProperties.add( null );
fail( "Set should be immutable" );
@@ -113,7 +144,7 @@
}
try {
- constraintProperties.remove( "orderNumber" );
+ constraintProperties.remove( constraintProperties.iterator().next() );
fail( "Set should be immutable" );
}
catch ( UnsupportedOperationException e ) {
@@ -125,28 +156,10 @@
* HV-95
*/
@Test
- public void testElementDescriptorImmutable() {
+ public void testGetConstrainedPropertiesForUnconstraintEntity() {
Validator validator = TestUtil.getValidator();
- ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
- .getConstraintsForProperty( "orderNumber" );
- Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
- assertTrue( "There should be a ConstraintDescriptor", constraintDescriptors.size() == 1 );
- ConstraintDescriptor<?> descriptor = constraintDescriptors.iterator().next();
-
- try {
- constraintDescriptors.add( descriptor );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
-
- try {
- constraintDescriptors.remove( descriptor );
- fail( "Set should be immutable" );
- }
- catch ( UnsupportedOperationException e ) {
-
- }
+ BeanDescriptor beanDescriptor = validator.getConstraintsForClass( UnconstraintEntity.class );
+ Set<PropertyDescriptor> constraintProperties = beanDescriptor.getConstrainedProperties();
+ assertEquals( "We should get the empty set.", 0, constraintProperties.size() );
}
}
Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java (from rev 16165, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/BeanDescriptorImplTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/metadata/ElementDescriptorImplTest.java 2009-03-19 13:55:43 UTC (rev 16185)
@@ -0,0 +1,65 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine.metadata;
+
+import java.util.Set;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ElementDescriptor;
+import javax.validation.Validator;
+
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.hibernate.validation.engine.Order;
+import org.hibernate.validation.util.TestUtil;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ElementDescriptorImplTest {
+ /**
+ * HV-95
+ */
+ @Test
+ public void testElementDescriptorImmutable() {
+ Validator validator = TestUtil.getValidator();
+ ElementDescriptor elementDescriptor = validator.getConstraintsForClass( Order.class )
+ .getConstraintsForProperty( "orderNumber" );
+ Set<ConstraintDescriptor<?>> constraintDescriptors = elementDescriptor.getConstraintDescriptors();
+ assertTrue( "There should be a ConstraintDescriptor", constraintDescriptors.size() == 1 );
+ ConstraintDescriptor<?> descriptor = constraintDescriptors.iterator().next();
+
+ try {
+ constraintDescriptors.add( descriptor );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+
+ try {
+ constraintDescriptors.remove( descriptor );
+ fail( "Set should be immutable" );
+ }
+ catch ( UnsupportedOperationException e ) {
+
+ }
+ }
+}
\ No newline at end of file
15 years, 9 months
Hibernate SVN: r16184 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validation/util and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-19 07:58:06 -0400 (Thu, 19 Mar 2009)
New Revision: 16184
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
Log:
HV-128 Added support for Iterable and resolved ambiguity with Maps
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-18 16:00:44 UTC (rev 16183)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-19 11:58:06 UTC (rev 16184)
@@ -99,24 +99,6 @@
return constraintTree.getDescriptor().getGroups();
}
- /**
- * @return Returns <code>true</code> in case the constraint is defined on a collection, <code>false</code>
- * otherwise.
- */
- public boolean isCollection() {
- Type t = typeOfAnnoatedElement();
- return ReflectionHelper.isCollection( t );
- }
-
- /**
- * @return Returns <code>true</code> in case the constraint is defined on an array, <code>false</code>
- * otherwise.
- */
- public boolean isArray() {
- Type t = typeOfAnnoatedElement();
- return ReflectionHelper.isArray( t );
- }
-
public ConstraintDescriptor getDescriptor() {
return constraintTree.getDescriptor();
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-03-18 16:00:44 UTC (rev 16183)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-03-19 11:58:06 UTC (rev 16184)
@@ -36,6 +36,7 @@
import javax.validation.Validator;
import javax.validation.groups.Default;
+import com.googlecode.jtype.TypeUtils;
import org.slf4j.Logger;
import org.hibernate.validation.engine.groups.Group;
@@ -300,16 +301,16 @@
*/
private <T> Iterator<?> createIteratorForCascadedValue(ExecutionContext<T> context, Type type, Object value) {
Iterator<?> iter;
- if ( ReflectionHelper.isCollection( type ) ) {
- boolean isIterable = value instanceof Iterable;
- Map<?, ?> map = !isIterable ? ( Map<?, ?> ) value : null;
- Iterable<?> elements = isIterable ?
- ( Iterable<?> ) value :
- map.entrySet();
- iter = elements.iterator();
+ if ( ReflectionHelper.isIterable( type ) ) {
+ iter = ( ( Iterable<?> ) value ).iterator();
context.markCurrentPropertyAsIndexed();
}
- else if ( ReflectionHelper.isArray( type ) ) {
+ else if ( ReflectionHelper.isMap( type ) ) {
+ Map<?, ?> map = ( Map<?, ?> ) value;
+ iter = map.values().iterator();
+ context.markCurrentPropertyAsIndexed();
+ }
+ else if ( TypeUtils.isArray( type ) ) {
List<?> arrayList = Arrays.asList( value );
iter = arrayList.iterator();
context.markCurrentPropertyAsIndexed();
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-03-18 16:00:44 UTC (rev 16183)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-03-19 11:58:06 UTC (rev 16184)
@@ -21,7 +21,6 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
-import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -29,13 +28,15 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.validation.ValidationException;
+import com.googlecode.jtype.TypeUtils;
+
/**
* Some reflection utility methods.
*
@@ -213,7 +214,7 @@
}
}
- public static Class<?> loadClass(String name, Class caller) throws ClassNotFoundException {
+ public static Class<?> loadClass(String name, Class<?> caller) throws ClassNotFoundException {
try {
//try context classloader, if fails try caller classloader
ClassLoader loader = Thread.currentThread().getContextClassLoader();
@@ -231,107 +232,70 @@
}
/**
- * Determines the type of elements of a generic collection or array.
+ * Determines the type of elements of an <code>Iterable</code>, array or the value of a <code>Map</code>.
*
- * @param type the collection or array type.
+ * @param type the type to inspect
*
- * @return the element type of the generic collection/array or <code>null</code> in case the specified type is not a collection/array or the
- * element type cannot be determined.
- *
- * @todo Verify algorithm. Does this hold up in most cases?
+ * @return Returns the type of elements of an <code>Iterable</code>, array or the value of a <code>Map</code>. <code>
+ * null</code> is returned in case the type is not indexable (in the context of JSR 303).
*/
public static Type getIndexedType(Type type) {
Type indexedType = null;
- if ( isCollection( type ) && type instanceof ParameterizedType ) {
+ if ( isIterable( type ) && type instanceof ParameterizedType ) {
ParameterizedType paramType = ( ParameterizedType ) type;
- Class collectionClass = getCollectionClass( type );
- if ( collectionClass == Collection.class || collectionClass == java.util.List.class || collectionClass == java.util.Set.class || collectionClass == java.util.SortedSet.class ) {
- indexedType = paramType.getActualTypeArguments()[0];
- }
- else if ( collectionClass == Map.class || collectionClass == java.util.SortedMap.class ) {
- indexedType = paramType.getActualTypeArguments()[1];
- }
+ indexedType = paramType.getActualTypeArguments()[0];
}
- else if ( ReflectionHelper.isArray( type ) && type instanceof GenericArrayType ) {
- GenericArrayType arrayTye = ( GenericArrayType ) type;
- indexedType = arrayTye.getGenericComponentType();
+ else if ( isMap( type ) && type instanceof ParameterizedType ) {
+ ParameterizedType paramType = ( ParameterizedType ) type;
+ indexedType = paramType.getActualTypeArguments()[1];
}
+ else if ( TypeUtils.isArray( type ) ) {
+ indexedType = TypeUtils.getComponentType( type );
+ }
return indexedType;
}
-
/**
* @param type the type to check.
*
- * @return Returns <code>true</code> if <code>type</code> is an array type or <code>false</code> otherwise.
+ * @return Returns <code>true</code> if <code>type</code> is a iterable type, <code>false</code> otherwise.
*/
- public static boolean isArray(Type type) {
- if ( type instanceof Class ) {
- return ( ( Class ) type ).isArray();
+ public static boolean isIterable(Type type) {
+ if ( type instanceof Class && isIterableClass( ( Class ) type ) ) {
+ return true;
}
- return type instanceof GenericArrayType;
+ if ( type instanceof ParameterizedType ) {
+ return isIterable( ( ( ParameterizedType ) type ).getRawType() );
+ }
+ if ( type instanceof WildcardType ) {
+ Type[] upperBounds = ( ( WildcardType ) type ).getUpperBounds();
+ if ( upperBounds.length == 0 ) {
+ return false;
+ }
+ return isIterable( upperBounds[0] );
+ }
+ return false;
}
-
/**
* @param type the type to check.
*
- * @return Returns <code>true</code> if <code>type</code> is a collection type or <code>false</code> otherwise.
+ * @return Returns <code>true</code> if <code>type</code> is implementing <code>Map</code>, <code>false</code> otherwise.
*/
- public static boolean isCollection(Type type) {
- return getCollectionClass( type ) != null;
- }
-
-
- /**
- * Returns the collection class for the specified type provided it is a collection.
- * <p>
- * This is a simplified version of commons annotations </code>TypeUtils.getCollectionClass()</code>.
- * </p>
- *
- * @param type the <code>Type</code> to check.
- *
- * @return the collection class, or <code>null</code> if type is not a collection class.
- */
- @SuppressWarnings("unchecked")
- public static Class<? extends Collection> getCollectionClass(Type type) {
- if ( type instanceof Class && isCollectionClass( ( Class ) type ) ) {
- return ( Class<? extends Collection> ) type;
+ public static boolean isMap(Type type) {
+ if ( type instanceof Class && isMapClass( ( Class ) type ) ) {
+ return true;
}
if ( type instanceof ParameterizedType ) {
- return getCollectionClass( ( ( ParameterizedType ) type ).getRawType() );
+ return isMap( ( ( ParameterizedType ) type ).getRawType() );
}
if ( type instanceof WildcardType ) {
Type[] upperBounds = ( ( WildcardType ) type ).getUpperBounds();
if ( upperBounds.length == 0 ) {
- return null;
+ return false;
}
- return getCollectionClass( upperBounds[0] );
+ return isMap( upperBounds[0] );
}
- return null;
- }
-
- /**
- * Checks whether the specified class parameter is an instance of a collection class.
- *
- * @param clazz <code>Class</code> to check.
- *
- * @return <code>true</code> is <code>clazz</code> is instance of a collection class, <code>false</code> otherwise.
- */
- private static boolean isCollectionClass(Class<?> clazz) {
- Class[] interfaces = clazz.getInterfaces();
-
- for ( Class interfaceClass : interfaces ) {
- if ( interfaceClass == Collection.class
- || interfaceClass == java.util.List.class
- || interfaceClass == java.util.Set.class
- || interfaceClass == java.util.Map.class
- || interfaceClass == java.util.SortedSet.class // extension to the specs
- || interfaceClass == java.util.SortedMap.class ) { // extension to the specs)
- return true;
- }
- }
-
return false;
}
@@ -368,16 +332,14 @@
Iterator<?> iter = null;
Type type = value.getClass();
- if ( isCollection( type ) ) {
- boolean isIterable = value instanceof Iterable;
- Map<?, ?> map = !isIterable ? ( Map<?, ?> ) value : null;
- Iterable<?> elements = isIterable ?
- ( Iterable<?> ) value :
- map.values();
- iter = elements.iterator();
-
+ if ( isIterable( type ) ) {
+ iter = ( ( Iterable<?> ) value ).iterator();
}
- else if ( isArray( type ) ) {
+ else if ( isMap( type ) ) {
+ Map<?, ?> map = ( Map<?, ?> ) value;
+ iter = map.values().iterator();
+ }
+ else if ( TypeUtils.isArray( type ) ) {
List<?> arrayList = Arrays.asList( value );
iter = arrayList.iterator();
}
@@ -403,7 +365,7 @@
* @return Returns <code>true</code> if the cass contains a field or member for the specified property, <code>
* false</code> otherwise.
*/
- public static boolean containsMember(Class clazz, String property) {
+ public static boolean containsMember(Class<?> clazz, String property) {
try {
clazz.getField( property );
return true;
@@ -435,5 +397,47 @@
return Class.forName( name, true, caller.getClassLoader() );
}
+ /**
+ * Get all superclasses and interfaces recursively.
+ *
+ * @param clazz The class to start the search with.
+ * @param classes List of classes to which to add all found super classes and interfaces.
+ */
+ private static void computeClassHierarchy(Class<?> clazz, List<Class<?>> classes) {
+ for ( Class current = clazz; current != null; current = current.getSuperclass() ) {
+ if ( classes.contains( current ) ) {
+ return;
+ }
+ classes.add( current );
+ for ( Class currentInterface : current.getInterfaces() ) {
+ computeClassHierarchy( currentInterface, classes );
+ }
+ }
+ }
+ /**
+ * Checks whether the specified class parameter is an instance of a collection class.
+ *
+ * @param clazz <code>Class</code> to check.
+ *
+ * @return <code>true</code> is <code>clazz</code> is instance of a collection class, <code>false</code> otherwise.
+ */
+ private static boolean isIterableClass(Class<?> clazz) {
+ List<Class<?>> classes = new ArrayList<Class<?>>();
+ computeClassHierarchy( clazz, classes );
+ return classes.contains( Iterable.class );
+ }
+
+ /**
+ * Checks whether the specified class parameter is an instance of a collection class.
+ *
+ * @param clazz <code>Class</code> to check.
+ *
+ * @return <code>true</code> is <code>clazz</code> is instance of a collection class, <code>false</code> otherwise.
+ */
+ private static boolean isMapClass(Class<?> clazz) {
+ List<Class<?>> classes = new ArrayList<Class<?>>();
+ computeClassHierarchy( clazz, classes );
+ return classes.contains( Map.class );
+ }
}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java 2009-03-18 16:00:44 UTC (rev 16183)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java 2009-03-19 11:58:06 UTC (rev 16184)
@@ -18,15 +18,21 @@
package org.hibernate.validation.util;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeSet;
import javax.validation.ValidationException;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -38,7 +44,48 @@
* @author Hardy Ferentschik
*/
public class ReflectionHelperTest {
+
@Test
+ public void testIsIterable() throws Exception {
+ Type type = TestTypes.class.getField( "stringList" ).getGenericType();
+ assertTrue( ReflectionHelper.isIterable( type ) );
+
+ assertTrue( ReflectionHelper.isIterable( new TreeSet<Object>().getClass() ) );
+
+ assertTrue( ReflectionHelper.isIterable( List.class ) );
+ assertTrue( ReflectionHelper.isIterable( HashSet.class ) );
+ assertTrue( ReflectionHelper.isIterable( Iterable.class ) );
+ assertTrue( ReflectionHelper.isIterable( Collection.class ) );
+
+ assertFalse( ReflectionHelper.isIterable( null ) );
+ assertFalse( ReflectionHelper.isIterable( Object.class ) );
+ }
+
+ @Test
+ public void testIsMap() throws Exception {
+ assertTrue( ReflectionHelper.isMap( Map.class ) );
+ assertTrue( ReflectionHelper.isMap( SortedMap.class ) );
+
+ Type type = TestTypes.class.getField( "objectMap" ).getGenericType();
+ assertTrue( ReflectionHelper.isMap( type ) );
+
+ assertFalse( ReflectionHelper.isMap( null ) );
+ assertFalse( ReflectionHelper.isMap( Object.class ) );
+ }
+
+ @Test
+ public void testGetIndexedType() throws Exception {
+ Type type = TestTypes.class.getField( "stringList" ).getGenericType();
+ assertEquals( String.class, ReflectionHelper.getIndexedType( type ) );
+
+ type = TestTypes.class.getField( "objectMap" ).getGenericType();
+ assertEquals( Object.class, ReflectionHelper.getIndexedType( type ) );
+
+ type = TestTypes.class.getField( "stringArray" ).getGenericType();
+ assertEquals( String.class, ReflectionHelper.getIndexedType( type ) );
+ }
+
+ @Test
public void testGetIndexedValueForMap() {
Map<String, Object> map = new HashMap<String, Object>();
Object testObject = new Object();
@@ -118,4 +165,10 @@
);
}
}
+
+ public class TestTypes {
+ public List<String> stringList;
+ public Map<String, Object> objectMap;
+ public String[] stringArray;
+ }
}
15 years, 9 months
Hibernate SVN: r16183 - validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-18 12:00:44 -0400 (Wed, 18 Mar 2009)
New Revision: 16183
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
Log:
Import cleanup
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java 2009-03-18 13:45:24 UTC (rev 16182)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java 2009-03-18 16:00:44 UTC (rev 16183)
@@ -22,7 +22,6 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.ArrayList;
import javax.validation.constraints.Size;
/**
15 years, 9 months
Hibernate SVN: r16182 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validation/engine/graphnavigation and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-18 09:45:24 -0400 (Wed, 18 Mar 2009)
New Revision: 16182
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java
Log:
HV-126 Code refactoring and some more tests.
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -29,6 +29,7 @@
import javax.validation.ConstraintValidatorFactory;
import javax.validation.UnexpectedTypeException;
import javax.validation.ValidationException;
+import javax.validation.ConstraintViolation;
import com.googlecode.jtype.TypeUtils;
import org.slf4j.Logger;
@@ -101,7 +102,7 @@
* @param <T> Type of the root bean for the current validation.
* @param <V> Type of the value to be validated.
*/
- public <T, V> void validateConstraints(V value, Type type, ExecutionContext<T> executionContext, List<ConstraintViolationImpl<T>> constraintViolations) {
+ public <T, V> void validateConstraints(V value, Type type, ExecutionContext<T> executionContext, List<ConstraintViolation<T>> constraintViolations) {
for ( ConstraintTree<?> tree : getChildren() ) {
tree.validateConstraints( value, type, executionContext, constraintViolations );
}
@@ -112,16 +113,18 @@
ConstraintValidator<A, V> validator = getInitalizedValidator(
value, type, executionContext.getConstraintValidatorFactory()
);
- executionContext.setCurrentConstraintDescriptor( descriptor );
- if ( !validator.isValid( value, executionContext ) ) {
- constraintViolations.addAll( executionContext.createConstraintViolations( value ) );
+ ConstraintValidatorContextImpl constraintValidatorContext = new ConstraintValidatorContextImpl(
+ executionContext.peekParentPath(), executionContext.peekProperty(), descriptor
+ );
+ if ( !validator.isValid( value, constraintValidatorContext ) ) {
+ constraintViolations.addAll( executionContext.createConstraintViolations( value, constraintValidatorContext ) );
}
if ( reportAsSingleViolation() && constraintViolations.size() > 0 ) {
constraintViolations.clear();
final String message = ( String ) getParent().getDescriptor().getAttributes().get( "message" );
final String property = executionContext.peekPropertyPath();
- ExecutionContext<T>.ErrorMessage error = executionContext.new ErrorMessage( message, property );
- constraintViolations.add( executionContext.createConstraintViolation( value, error ) );
+ ConstraintValidatorContextImpl.ErrorMessage error = constraintValidatorContext.new ErrorMessage( message, property );
+ constraintViolations.add( executionContext.createConstraintViolation( value, error, descriptor ) );
}
}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -0,0 +1,106 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validation.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ConstraintValidatorContextImpl implements ConstraintValidatorContext {
+
+ private final List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>( 3 );
+ private final String property;
+ private final String propertyParent;
+ private final ConstraintDescriptor<?> constraintDescriptor;
+ private boolean defaultDisabled;
+
+
+ public ConstraintValidatorContextImpl(String propertyParent, String property, ConstraintDescriptor<?> constraintDescriptor) {
+ this.property = property;
+ this.propertyParent = propertyParent;
+ this.constraintDescriptor = constraintDescriptor;
+ }
+
+ public void disableDefaultError() {
+ defaultDisabled = true;
+ }
+
+ public String getDefaultErrorMessage() {
+ return ( String ) constraintDescriptor.getAttributes().get( "message" );
+ }
+
+ public void addError(String message) {
+ errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent, property ) ) );
+ }
+
+ public void addError(String message, String property) {
+ errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent, property ) ) );
+ }
+
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return constraintDescriptor;
+ }
+
+ public boolean isDefaultErrorDisabled() {
+ return defaultDisabled;
+ }
+
+ public List<ErrorMessage> getErrorMessages() {
+ List<ErrorMessage> returnedErrorMessages = new ArrayList<ErrorMessage>( errorMessages );
+ if ( !defaultDisabled ) {
+ returnedErrorMessages.add(
+ new ErrorMessage( getDefaultErrorMessage(), buildPropertyPath( propertyParent, property ) )
+ );
+ }
+ return returnedErrorMessages;
+ }
+
+ private String buildPropertyPath(String parent, String leaf) {
+ if ( ExecutionContext.PROPERTY_ROOT.equals( parent ) ) {
+ return leaf;
+ }
+ else {
+ return new StringBuilder().append( parent )
+ .append( ExecutionContext.PROPERTY_PATH_SEPERATOR )
+ .append( leaf )
+ .toString();
+ }
+ }
+
+ public class ErrorMessage {
+ private final String message;
+ private final String property;
+
+ public ErrorMessage(String message, String property) {
+ this.message = message;
+ this.property = property;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -26,10 +26,10 @@
import java.util.Set;
import java.util.Stack;
import javax.validation.ConstraintDescriptor;
-import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
+import javax.validation.ConstraintViolation;
import org.hibernate.validation.util.IdentitySet;
@@ -42,11 +42,11 @@
* @todo Look for ways to improve this data structure. It is quite fragile and depends on the right oder of calls
* in order to work.
*/
-public class ExecutionContext<T> implements ConstraintValidatorContext {
+public class ExecutionContext<T> {
- private static final String PROPERTY_ROOT = "";
+ public static final String PROPERTY_ROOT = "";
- private static final String PROPERTY_PATH_SEPERATOR = ".";
+ public static final String PROPERTY_PATH_SEPERATOR = ".";
/**
* The root bean of the validation.
@@ -67,7 +67,7 @@
/**
* A list of all failing constraints so far.
*/
- private final List<ConstraintViolationImpl<T>> failingConstraintViolations;
+ private final List<ConstraintViolation<T>> failingConstraintViolations;
/**
* The current property based based from the root bean.
@@ -80,12 +80,6 @@
private Class<?> currentGroup;
/**
- * Reference to a <code>ValidatedProperty</code> keeping track of the property we are currently validating,
- * together with required meta data.
- */
- private ValidatedProperty currentValidatedProperty;
-
- /**
* Stack for keeping track of the currently validated bean.
*/
private Stack<Object> beanStack = new Stack<Object>();
@@ -126,38 +120,13 @@
processedObjects = new HashMap<Class<?>, IdentitySet>();
processedPaths = new IdentityHashMap<Object, Set<String>>();
propertyPath = new ArrayList<String>();
- failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ failingConstraintViolations = new ArrayList<ConstraintViolation<T>>();
}
public ConstraintValidatorFactory getConstraintValidatorFactory() {
return constraintValidatorFactory;
}
- public void disableDefaultError() {
- assert currentValidatedProperty != null;
- currentValidatedProperty.disableDefaultError();
- }
-
- public String getDefaultErrorMessage() {
- assert currentValidatedProperty != null;
- return currentValidatedProperty.getDefaultErrorMessage();
- }
-
- public void addError(String message) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.addError( message );
- }
-
- public void addError(String message, String property) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.addError( message, property );
- }
-
- public void setCurrentConstraintDescriptor(ConstraintDescriptor constraintDescriptor) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.setConstraintDescriptor( constraintDescriptor );
- }
-
public Object peekCurrentBean() {
return beanStack.peek();
}
@@ -220,13 +189,13 @@
return objectsProcessedInCurrentGroups != null && objectsProcessedInCurrentGroups.contains( value );
}
- public void addConstraintFailures(List<ConstraintViolationImpl<T>> failingConstraintViolations) {
- for ( ConstraintViolationImpl<T> violation : failingConstraintViolations ) {
+ public void addConstraintFailures(List<ConstraintViolation<T>> failingConstraintViolations) {
+ for ( ConstraintViolation<T> violation : failingConstraintViolations ) {
addConstraintFailure( violation );
}
}
- public List<ConstraintViolationImpl<T>> getFailingConstraints() {
+ public List<ConstraintViolation<T>> getFailingConstraints() {
return failingConstraintViolations;
}
@@ -236,7 +205,6 @@
* @param property the new property to add to the current path.
*/
public void pushProperty(String property) {
- currentValidatedProperty = new ValidatedProperty( peekPropertyPath(), property );
propertyPath.add( property );
}
@@ -246,7 +214,6 @@
public void popProperty() {
if ( propertyPath.size() > 0 ) {
propertyPath.remove( propertyPath.size() - 1 );
- currentValidatedProperty = null;
}
}
@@ -267,14 +234,7 @@
}
public String peekPropertyPath() {
- StringBuilder builder = new StringBuilder();
- for ( int i = 0; i <= propertyPath.size() - 1; i++ ) {
- builder.append( propertyPath.get( i ) );
- if ( i < propertyPath.size() - 1 ) {
- builder.append( PROPERTY_PATH_SEPERATOR );
- }
- }
- return builder.toString();
+ return buildPath( propertyPath.size() - 1 );
}
public String peekProperty() {
@@ -284,6 +244,10 @@
return propertyPath.get( propertyPath.size() - 1 );
}
+ public String peekParentPath() {
+ return buildPath( propertyPath.size() - 2 );
+ }
+
public boolean isValidationRequired(MetaConstraint metaConstraint) {
if ( !metaConstraint.getGroupList().contains( currentGroup ) ) {
return false;
@@ -299,16 +263,18 @@
);
}
- public List<ConstraintViolationImpl<T>> createConstraintViolations(Object value) {
+ public List<ConstraintViolationImpl<T>> createConstraintViolations(Object value, ConstraintValidatorContextImpl constraintValidatorContext) {
List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
- for ( ErrorMessage error : currentValidatedProperty.getErrorMessages() ) {
- constraintViolations.add( createConstraintViolation( value, error ) );
+ for ( ConstraintValidatorContextImpl.ErrorMessage error : constraintValidatorContext.getErrorMessages() ) {
+ ConstraintViolationImpl<T> violation = createConstraintViolation(
+ value, error, constraintValidatorContext.getConstraintDescriptor()
+ );
+ constraintViolations.add( violation );
}
return constraintViolations;
}
- public ConstraintViolationImpl<T> createConstraintViolation(Object value, ErrorMessage error) {
- ConstraintDescriptor descriptor = currentValidatedProperty.getConstraintDescriptor();
+ public ConstraintViolationImpl<T> createConstraintViolation(Object value, ConstraintValidatorContextImpl.ErrorMessage error, ConstraintDescriptor<?> descriptor) {
String messageTemplate = error.getMessage();
String interpolatedMessage = messageInterpolator.interpolate(
messageTemplate,
@@ -325,6 +291,17 @@
);
}
+ private String buildPath(int index) {
+ StringBuilder builder = new StringBuilder();
+ for ( int i = 0; i <= index; i++ ) {
+ builder.append( propertyPath.get( i ) );
+ if ( i < index ) {
+ builder.append( PROPERTY_PATH_SEPERATOR );
+ }
+ }
+ return builder.toString();
+ }
+
private void markProcessed() {
markProcessForCurrentGroup();
if ( allowOneValidationPerPath ) {
@@ -354,90 +331,10 @@
}
}
- private void addConstraintFailure(ConstraintViolationImpl<T> failingConstraintViolation) {
+ private void addConstraintFailure(ConstraintViolation<T> failingConstraintViolation) {
int i = failingConstraintViolations.indexOf( failingConstraintViolation );
if ( i == -1 ) {
failingConstraintViolations.add( failingConstraintViolation );
}
}
-
- class ValidatedProperty {
-
- private final List<ErrorMessage> errorMessages = new ArrayList<ErrorMessage>( 3 );
- private final String property;
- private final String propertyParent;
- private ConstraintDescriptor<?> constraintDescriptor;
- private boolean defaultDisabled;
-
-
- private ValidatedProperty(String propertyParent, String property) {
- this.property = property;
- this.propertyParent = propertyParent;
- }
-
- public void setConstraintDescriptor(ConstraintDescriptor<?> constraintDescriptor) {
- this.constraintDescriptor = constraintDescriptor;
- }
-
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return constraintDescriptor;
- }
-
- void disableDefaultError() {
- defaultDisabled = true;
- }
-
- public boolean isDefaultErrorDisabled() {
- return defaultDisabled;
- }
-
- public String getDefaultErrorMessage() {
- return ( String ) constraintDescriptor.getAttributes().get( "message" );
- }
-
- public void addError(String message) {
- errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent, property ) ) );
- }
-
- public void addError(String message, String property) {
- errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent, property ) ) );
- }
-
- public List<ErrorMessage> getErrorMessages() {
- List<ErrorMessage> returnedErrorMessages = new ArrayList<ErrorMessage>( errorMessages );
- if ( !defaultDisabled ) {
- returnedErrorMessages.add(
- new ErrorMessage( getDefaultErrorMessage(), buildPropertyPath( propertyParent, property ) )
- );
- }
- return returnedErrorMessages;
- }
-
- private String buildPropertyPath(String parent, String leaf) {
- if ( PROPERTY_ROOT.equals( parent ) ) {
- return leaf;
- }
- else {
- return new StringBuilder().append( parent ).append( PROPERTY_PATH_SEPERATOR ).append( leaf ).toString();
- }
- }
- }
-
- public class ErrorMessage {
- private final String message;
- private final String property;
-
- public ErrorMessage(String message, String property) {
- this.message = message;
- this.property = property;
- }
-
- public String getMessage() {
- return message;
- }
-
- public String getProperty() {
- return property;
- }
- }
}
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintViolation;
import org.hibernate.validation.util.ReflectionHelper;
@@ -139,7 +140,7 @@
public <T> boolean validateConstraint(ExecutionContext<T> executionContext) {
final Object leafBeanInstance = executionContext.peekCurrentBean();
Object value = getValue( leafBeanInstance );
- List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> constraintViolations = new ArrayList<ConstraintViolation<T>>();
constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext, constraintViolations );
if ( constraintViolations.size() > 0 ) {
executionContext.addConstraintFailures( constraintViolations );
@@ -149,7 +150,7 @@
}
public <T> boolean validateConstraint(Object value, ExecutionContext<T> executionContext) {
- List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> constraintViolations = new ArrayList<ConstraintViolation<T>>();
constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext, constraintViolations );
if ( constraintViolations.size() > 0 ) {
executionContext.addConstraintFailures( constraintViolations );
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -113,7 +113,7 @@
object, messageInterpolator, constraintValidatorFactory, traversableResolver
);
- List<ConstraintViolationImpl<T>> list = validateInContext( context, groupChain );
+ List<ConstraintViolation<T>> list = validateInContext( context, groupChain );
return new HashSet<ConstraintViolation<T>>( list );
}
@@ -127,7 +127,7 @@
sanityCheckPropertyPath( propertyName );
GroupChain groupChain = determineGroupExecutionOrder( groups );
- List<ConstraintViolationImpl<T>> failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> failingConstraintViolations = new ArrayList<ConstraintViolation<T>>();
validateProperty( object, new PropertyIterator( propertyName ), failingConstraintViolations, groupChain );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
@@ -142,7 +142,7 @@
sanityCheckPropertyPath( propertyName );
GroupChain groupChain = determineGroupExecutionOrder( groups );
- List<ConstraintViolationImpl<T>> failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> failingConstraintViolations = new ArrayList<ConstraintViolation<T>>();
validateValue( beanType, value, new PropertyIterator( propertyName ), failingConstraintViolations, groupChain );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
@@ -182,7 +182,7 @@
*
* @return List of invalid constraints.
*/
- private <T> List<ConstraintViolationImpl<T>> validateInContext(ExecutionContext<T> context, GroupChain groupChain) {
+ private <T> List<ConstraintViolation<T>> validateInContext(ExecutionContext<T> context, GroupChain groupChain) {
if ( context.peekCurrentBean() == null ) {
return Collections.emptyList();
}
@@ -349,7 +349,7 @@
}
}
- private <T> void validateProperty(T object, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, GroupChain groupChain) {
+ private <T> void validateProperty(T object, PropertyIterator propertyIter, List<ConstraintViolation<T>> failingConstraintViolations, GroupChain groupChain) {
@SuppressWarnings("unchecked")
final Class<T> beanType = ( Class<T> ) object.getClass();
@@ -390,7 +390,7 @@
}
}
- private <T> void validatePropertyForGroup(T object, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Object hostingBeanInstance, Group group) {
+ private <T> void validatePropertyForGroup(T object, PropertyIterator propertyIter, List<ConstraintViolation<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Object hostingBeanInstance, Group group) {
int numberOfConstraintViolationsBefore = failingConstraintViolations.size();
BeanMetaData<T> beanMetaData = getBeanMetaData( metaConstraints.iterator().next().getBeanClass() );
@@ -427,7 +427,7 @@
}
@SuppressWarnings("unchecked")
- private <T> void validateValue(Class<T> beanType, Object value, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, GroupChain groupChain) {
+ private <T> void validateValue(Class<T> beanType, Object value, PropertyIterator propertyIter, List<ConstraintViolation<T>> failingConstraintViolations, GroupChain groupChain) {
Set<MetaConstraint<T, ?>> metaConstraints = new HashSet<MetaConstraint<T, ?>>();
collectMetaConstraintsForPath( beanType, null, propertyIter, metaConstraints );
@@ -469,7 +469,7 @@
}
}
- private <T> void validateValueForGroup(Object value, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Group group) {
+ private <T> void validateValueForGroup(Object value, PropertyIterator propertyIter, List<ConstraintViolation<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Group group) {
int numberOfConstraintViolations = failingConstraintViolations.size();
BeanMetaData<T> beanMetaData = getBeanMetaData( metaConstraints.iterator().next().getBeanClass() );
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -17,11 +17,14 @@
*/
package org.hibernate.validation.engine.graphnavigation;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.hibernate.validation.util.TestUtil;
@@ -59,5 +62,55 @@
Set<ConstraintViolation<Order>> constraintViolations = validator.validate( order );
assertEquals( "Wrong number of constraints", 3, constraintViolations.size() );
+
+ List<String> expectedErrorMessages = new ArrayList<String>();
+ expectedErrorMessages.add( "shippingAddress.addressline1" );
+ expectedErrorMessages.add( "customer.addresses[0].addressline1" );
+ expectedErrorMessages.add( "billingAddress.inhabitant.addresses[0].addressline1" );
+
+ for ( ConstraintViolation<Order> violation : constraintViolations ) {
+ if ( expectedErrorMessages.contains( violation.getPropertyPath() ) ) {
+ expectedErrorMessages.remove( violation.getPropertyPath() );
+ }
+ }
+
+ assertTrue( "All error messages should have occured once", expectedErrorMessages.size() == 0 );
}
+
+ @Test
+ public void testNoEndlessLoop() {
+ User john = new User( "John", null );
+ john.knows( john );
+
+ Validator validator = TestUtil.getValidator();
+
+ Set<ConstraintViolation<User>> constraintViolations = validator.validate( john );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class, null, "lastName"
+ );
+
+
+ User jane = new User( "Jane", "Doe" );
+ jane.knows( john );
+ john.knows( jane );
+
+ constraintViolations = validator.validate( john );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class, null, "lastName"
+ );
+
+ constraintViolations = validator.validate( jane );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class, null, "knowsUser[0].lastName"
+ );
+
+ john.setLastName( "Doe" );
+ constraintViolations = validator.validate( john );
+ assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
+
+
+ }
}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java 2009-03-18 11:16:04 UTC (rev 16181)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java 2009-03-18 13:45:24 UTC (rev 16182)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -17,11 +17,11 @@
*/
package org.hibernate.validation.engine.graphnavigation;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
-import javax.validation.Valid;
/**
* @author Hardy Ferentschik
@@ -35,8 +35,11 @@
private String lastName;
@Valid
- private Set<Address> addresses = new HashSet<Address>();
+ private List<Address> addresses = new ArrayList<Address>();
+ @Valid
+ private List<User> knowsUser = new ArrayList<User>();
+
public User() {
}
@@ -45,7 +48,7 @@
this.lastName = lastName;
}
- public Set<Address> getAddresses() {
+ public List<Address> getAddresses() {
return addresses;
}
@@ -53,6 +56,14 @@
addresses.add( address );
}
+ public void knows(User user) {
+ knowsUser.add( user );
+ }
+
+ public List<User> getKnowsUser() {
+ return knowsUser;
+ }
+
public String getFirstName() {
return firstName;
}
15 years, 9 months
Hibernate SVN: r16181 - validator/trunk/hibernate-validator.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-18 07:16:04 -0400 (Wed, 18 Mar 2009)
New Revision: 16181
Modified:
validator/trunk/hibernate-validator/pom.xml
Log:
HV-130 Switched to groupId org.hibernate.java-persitence for the JPA API
Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml 2009-03-18 11:11:08 UTC (rev 16180)
+++ validator/trunk/hibernate-validator/pom.xml 2009-03-18 11:16:04 UTC (rev 16181)
@@ -44,7 +44,7 @@
This is a temporary dependency. Do not use this dependecy in production.
-->
<dependency>
- <groupId>javax.persistence</groupId>
+ <groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>2.0.Beta1-SNAPSHOT</version>
<optional>true</optional>
15 years, 9 months
Hibernate SVN: r16180 - jpa-api/trunk.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-03-18 07:11:08 -0400 (Wed, 18 Mar 2009)
New Revision: 16180
Modified:
jpa-api/trunk/pom.xml
Log:
switched to org.hibernate.java-persistence as groupId
Modified: jpa-api/trunk/pom.xml
===================================================================
--- jpa-api/trunk/pom.xml 2009-03-18 11:08:10 UTC (rev 16179)
+++ jpa-api/trunk/pom.xml 2009-03-18 11:11:08 UTC (rev 16180)
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>javax.persistence</groupId>
+ <groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>2.0.Beta1-SNAPSHOT</version>
<packaging>jar</packaging>
15 years, 9 months