001 /*
002 * Copyright 2002-2004 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016 package org.springframework.rules.constraint.property;
017
018 import java.util.Collection;
019 import java.util.HashMap;
020 import java.util.Iterator;
021 import java.util.Map;
022
023 import org.springframework.binding.MutablePropertyAccessStrategy;
024 import org.springframework.binding.support.BeanPropertyAccessStrategy;
025 import org.springframework.rules.constraint.AbstractConstraint;
026
027 public class UniquePropertyValueConstraint extends AbstractConstraint implements PropertyConstraint {
028 private String propertyName;
029
030 private Map distinctValueTable;
031
032 public UniquePropertyValueConstraint(String propertyName) {
033 this.propertyName = propertyName;
034 }
035
036 public String getPropertyName() {
037 return propertyName;
038 }
039
040 public boolean isDependentOn(String propertyName) {
041 return getPropertyName().equals(propertyName);
042 }
043
044 public boolean isCompoundRule() {
045 return false;
046 }
047
048
049 /**
050 * Returns <code>true</code> if each domain object in the provided collection has a unique
051 * value for the configured property.
052 */
053 public boolean test(Object o) {
054 Collection domainObjects = (Collection)o;
055 distinctValueTable = new HashMap((int)(domainObjects.size() * .75));
056 Iterator it = domainObjects.iterator();
057 MutablePropertyAccessStrategy accessor = null;
058 while (it.hasNext()) {
059 Object domainObject = it.next();
060 if (accessor == null) {
061 accessor = createPropertyAccessStrategy(domainObject);
062 }
063 else {
064 accessor.getDomainObjectHolder().setValue(domainObject);
065 }
066 Object propertyValue = accessor.getPropertyValue(propertyName);
067 Integer hashCode;
068 if (propertyValue == null) {
069 hashCode = new Integer(0);
070 }
071 else {
072 hashCode = new Integer(propertyValue.hashCode());
073 }
074 if (distinctValueTable.containsKey(hashCode)) {
075 return false;
076 }
077
078 distinctValueTable.put(hashCode, propertyValue);
079 }
080 return true;
081 }
082
083 protected MutablePropertyAccessStrategy createPropertyAccessStrategy(Object o) {
084 return new BeanPropertyAccessStrategy(o);
085 }
086
087 }