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 }