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.metadata;
017
018 import java.beans.PropertyDescriptor;
019 import java.lang.reflect.Method;
020 import java.util.Iterator;
021
022 import org.springframework.beans.BeanWrapperImpl;
023 import org.springframework.rules.constraint.Constraint;
024 import org.springframework.metadata.Attributes;
025 import org.springframework.rules.Rules;
026 import org.springframework.rules.constraint.property.CompoundPropertyConstraint;
027 import org.springframework.rules.constraint.property.PropertyConstraint;
028 import org.springframework.rules.support.DefaultRulesSource;
029
030 /**
031 * An implementation of RulesSource that loads rules using metadata.
032 *
033 * @author Oliver Hutchison
034 */
035 public class AttributesRulesSource extends DefaultRulesSource {
036
037 private final Attributes attributes;
038
039 public AttributesRulesSource(Attributes attributes) {
040 this.attributes = attributes;
041 }
042
043 public synchronized Rules getRules(Class beanClass, String contextId) {
044 Rules rules = super.getRules(beanClass, contextId);
045 if (rules == null) {
046 buildRules(beanClass);
047 rules = super.getRules(beanClass, contextId);
048 }
049 return rules;
050 }
051
052 private void buildRules(Class beanClass) {
053 Rules rules = new Rules(beanClass);
054 PropertyDescriptor[] propertDescriptors = new BeanWrapperImpl(beanClass).getPropertyDescriptors();
055 for (int i = 0; i < propertDescriptors.length; i++) {
056 loadPropertyConstraints(rules, propertDescriptors[i]);
057 }
058 addRules(rules);
059 }
060
061 private void loadPropertyConstraints(Rules rules, PropertyDescriptor propertDescriptor) {
062 String propertyName = propertDescriptor.getName();
063 loadPropertyConstraintsForMethod(rules, propertyName, propertDescriptor.getReadMethod());
064 loadPropertyConstraintsForMethod(rules, propertyName, propertDescriptor.getWriteMethod());
065 }
066
067 private void loadPropertyConstraintsForMethod(Rules rules, String propertyName, Method method) {
068 if (method != null) {
069 for (Iterator i = attributes.getAttributes(method).iterator(); i.hasNext();) {
070 Object attribute = i.next();
071 if (attribute instanceof Constraint) {
072 Constraint constraint = (Constraint)attribute;
073 if (constraint instanceof PropertyConstraint) {
074 rules.add((PropertyConstraint)constraint);
075 }
076 else if (constraint instanceof CompoundPropertyConstraint) {
077 rules.add((CompoundPropertyConstraint)constraint);
078 }
079 else {
080 rules.add(propertyName, constraint);
081 }
082 }
083 }
084 }
085 }
086 }