/* * Copyright 2004-2005 the original author or authors. * * 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.springmodules.validation.bean.conf.loader.xml; import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springmodules.validation.bean.conf.loader.xml.handler.ClassValidationElementHandler; import org.springmodules.validation.bean.conf.loader.xml.handler.PropertyValidationElementHandler; import org.springmodules.validation.util.cel.ConditionExpressionBased; import org.springmodules.validation.util.cel.ConditionExpressionParser; import org.springmodules.validation.util.cel.valang.ValangConditionExpressionParser; import org.springmodules.validation.util.context.BasicContextAware; import org.springmodules.validation.util.fel.FunctionExpressionBased; import org.springmodules.validation.util.fel.FunctionExpressionParser; import org.springmodules.validation.util.fel.parser.ValangFunctionExpressionParser; import org.w3c.dom.Element; /** * A simple implementation of {@link ValidationRuleElementHandlerRegistry} that enableds registration of element * handlers. * * @author Uri Boness */ public class SimpleValidationRuleElementHandlerRegistry extends BasicContextAware implements ValidationRuleElementHandlerRegistry, InitializingBean, ConditionExpressionBased, FunctionExpressionBased { private final static Log logger = LogFactory.getLog(SimpleValidationRuleElementHandlerRegistry.class); private List classHandlers; private List propertyHandlers; private boolean functoinExpressionParserSet = false; private FunctionExpressionParser functionExpressionParser; private boolean conditionExpressionParserSet = false; private ConditionExpressionParser conditionExpressionParser; /** * Constructs a new DefaultValidationRuleElementHandlerRegistry with the default handlers. */ public SimpleValidationRuleElementHandlerRegistry() { classHandlers = new ArrayList(); propertyHandlers = new ArrayList(); functionExpressionParser = new ValangFunctionExpressionParser(); conditionExpressionParser = new ValangConditionExpressionParser(); } /** * Registers the given class handler with this registry. The registered handler is registered in such a way that it will * be checked first for support (LIFC - Last In First Checked). */ public void registerClassHandler(ClassValidationElementHandler handler) { classHandlers.add(0, handler); } /** * @see org.springmodules.validation.bean.conf.loader.xml.ValidationRuleElementHandlerRegistry#findClassHandler(org.w3c.dom.Element, Class) */ public ClassValidationElementHandler findClassHandler(Element element, Class clazz) { for (Iterator iter = classHandlers.iterator(); iter.hasNext();) { ClassValidationElementHandler handler = (ClassValidationElementHandler) iter.next(); if (handler.supports(element, clazz)) { return handler; } } return null; } /** * Registers the given property handler with this registry. The registered handler is registered in such a way that * it will be checked first for support. (LIFC - Last In First Checked). */ public void registerPropertyHandler(PropertyValidationElementHandler handler) { propertyHandlers.add(0, handler); } /** * @see org.springmodules.validation.bean.conf.loader.xml.ValidationRuleElementHandlerRegistry#findPropertyHandler(org.w3c.dom.Element, Class, java.beans.PropertyDescriptor) */ public PropertyValidationElementHandler findPropertyHandler(Element element, Class clazz, PropertyDescriptor descriptor) { for (Iterator iter = propertyHandlers.iterator(); iter.hasNext();) { PropertyValidationElementHandler handler = (PropertyValidationElementHandler) iter.next(); if (handler.supports(element, clazz, descriptor)) { return handler; } } return null; } public void afterPropertiesSet() throws Exception { findConditionExpressionParserInApplicationContext(); findFunctionExpressionParserInApplicationContext(); for (Iterator iter = classHandlers.iterator(); iter.hasNext();) { ClassValidationElementHandler handler = (ClassValidationElementHandler) iter.next(); setExpressionParsers(handler); initLifecycle(handler); } for (Iterator iter = propertyHandlers.iterator(); iter.hasNext();) { PropertyValidationElementHandler handler = (PropertyValidationElementHandler) iter.next(); setExpressionParsers(handler); initLifecycle(handler); } } //=============================================== Setter/Getter ==================================================== /** * Registeres the given class handlers with this registry. * * @param handlers The handlers to register with this registry. */ public void setExtraClassHandlers(ClassValidationElementHandler[] handlers) { for (int i = handlers.length - 1; i >= 0; i--) { registerClassHandler(handlers[i]); } } /** * Resets the class handlers in this registry with the given ones. * * @param handlers The class handlers to be registered with this registry. */ public void setClassHandlers(ClassValidationElementHandler[] handlers) { classHandlers.clear(); setExtraClassHandlers(handlers); } /** * Registeres the given property handlers with this registry. * * @param handlers The handlers to register with this registry. */ public void setExtraPropertyHandlers(PropertyValidationElementHandler[] handlers) { for (int i = handlers.length - 1; i >= 0; i--) { registerPropertyHandler(handlers[i]); } } /** * Resets the property handlers in this registry to the given ones (overriding the existing ones). * * @param handlers The property handlers to register with this registry. */ public void setPropertyHandlers(PropertyValidationElementHandler[] handlers) { propertyHandlers.clear(); setExtraPropertyHandlers(handlers); } /** * Return all class handlers that are registered with this registry. * * @return All class handlers that are registered with this registry. */ public ClassValidationElementHandler[] getClassHandlers() { return (ClassValidationElementHandler[]) classHandlers.toArray(new ClassValidationElementHandler[classHandlers.size()]); } /** * Return all property handlers that are registered with this registry. * * @return All property handlers that are registered with this registry. */ public PropertyValidationElementHandler[] getPropertyHandlers() { return (PropertyValidationElementHandler[]) propertyHandlers.toArray(new PropertyValidationElementHandler[propertyHandlers.size()]); } /** * @see org.springmodules.validation.util.fel.FunctionExpressionBased#setFunctionExpressionParser(org.springmodules.validation.util.fel.FunctionExpressionParser) */ public void setFunctionExpressionParser(FunctionExpressionParser functionExpressionParser) { this.functoinExpressionParserSet = true; this.functionExpressionParser = functionExpressionParser; } /** * @see org.springmodules.validation.util.cel.ConditionExpressionBased#setConditionExpressionParser(org.springmodules.validation.util.cel.ConditionExpressionParser) */ public void setConditionExpressionParser(ConditionExpressionParser conditionExpressionParser) { this.conditionExpressionParserSet = true; this.conditionExpressionParser = conditionExpressionParser; } //=============================================== Helper Methods =================================================== protected void setExpressionParsers(Object object) { if (ConditionExpressionBased.class.isInstance(object) && conditionExpressionParser != null) { ((ConditionExpressionBased) object).setConditionExpressionParser(conditionExpressionParser); } if (FunctionExpressionBased.class.isInstance(object) && functionExpressionParser != null) { ((FunctionExpressionBased) object).setFunctionExpressionParser(functionExpressionParser); } } protected void findConditionExpressionParserInApplicationContext() { if (conditionExpressionParserSet) { return; } ConditionExpressionParser parser = (ConditionExpressionParser) findObjectInApplicationContext(ConditionExpressionParser.class); if (parser == null) { return; } conditionExpressionParser = parser; } protected void findFunctionExpressionParserInApplicationContext() { if (functoinExpressionParserSet) { return; } FunctionExpressionParser parser = (FunctionExpressionParser) findObjectInApplicationContext(FunctionExpressionParser.class); if (parser == null) { return; } functionExpressionParser = parser; } protected Object findObjectInApplicationContext(Class clazz) { if (applicationContext == null) { return null; } String[] names = applicationContext.getBeanNamesForType(clazz); if (names.length == 0) { return null; } if (names.length > 1) { SimpleValidationRuleElementHandlerRegistry.logger.warn("Multiple bean of type '" + clazz.getName() + "' are defined in the application context." + "Only the first encountered one will be used"); } return applicationContext.getBean(names[0]); } }