001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
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,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.spring.datadictionary;
017    
018    import org.apache.log4j.Logger;
019    import org.kuali.kfs.sys.KFSPropertyConstants;
020    import org.springframework.beans.factory.config.BeanDefinition;
021    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
022    import org.springframework.beans.factory.xml.ParserContext;
023    import org.springframework.util.StringUtils;
024    import org.w3c.dom.Element;
025    import org.w3c.dom.Node;
026    import org.w3c.dom.NodeList;
027    
028    public class AttributeBeanDefinitionParser extends KualiBeanDefinitionParserBase {
029    
030        private static Logger LOG = Logger.getLogger(AttributeBeanDefinitionParser.class);
031        
032        
033        @Override
034        protected String getBaseBeanTypeParent(Element element) {
035            return "AttributeDefinition";
036        }    
037        
038        
039        @Override
040        protected void doParse(Element element, ParserContext context, BeanDefinitionBuilder bean) {
041            // get all attributes
042            handleAbstractAttribute( element, bean );
043            processAttributeAttributes(element, bean);
044            // parse inner tags
045            NodeList children = element.getChildNodes();
046            processChildNodes( children, bean );
047            parseEmbeddedPropertyElements(element, bean);
048        }
049        
050        protected void processAttributeAttributes( Element element, BeanDefinitionBuilder bean ) {
051            String attributeName = element.getAttribute("attributeName");
052            String label = element.getAttribute("label");
053            String shortLabel = element.getAttribute("shortLabel");
054            String required = element.getAttribute("required");
055            String forceUppercase = element.getAttribute("forceUppercase");
056            String maxLength = element.getAttribute("maxLength");
057            String displayLabelAttribute = element.getAttribute("displayLabelAttribute");
058            String formatterClass = element.getAttribute("formatterClass");
059    
060            if ( StringUtils.hasText( attributeName ) ) {
061                bean.addPropertyValue("name", attributeName);
062            }
063            if ( StringUtils.hasText( label ) ) {
064                bean.addPropertyValue("label", label);
065            }
066            if ( StringUtils.hasText( shortLabel ) ) {
067                bean.addPropertyValue("shortLabel", shortLabel);
068            }
069            if ( StringUtils.hasText( displayLabelAttribute ) ) {
070                bean.addPropertyValue("displayLabelAttribute", displayLabelAttribute);
071            }
072            if ( StringUtils.hasText( formatterClass ) ) {
073                bean.addPropertyValue("formatterClass", formatterClass);
074            }
075            if ( StringUtils.hasText( required ) ) {
076                bean.addPropertyValue("required", Boolean.valueOf(required));
077            }
078            if ( StringUtils.hasText( forceUppercase ) ) {
079                bean.addPropertyValue("forceUppercase", Boolean.valueOf(forceUppercase));
080            }
081            if ( StringUtils.hasText( maxLength ) ) {
082                bean.addPropertyValue("maxLength", Integer.valueOf(maxLength));
083            }
084        }
085    
086        protected void processChildNodes( NodeList children, BeanDefinitionBuilder bean ) {
087            for ( int i = 0; i < children.getLength(); i++ ) {
088                Node child = children.item(i);
089                if ( child.getNodeType() != Node.ELEMENT_NODE ) continue;
090                Element ele = (Element)child;
091                String elementName = ele.getLocalName();
092                if ( elementName == null ) continue;
093                if ( elementName.equals( "text" ) ) {
094                    bean.addPropertyValue("control", processTextControlElement(ele) );
095                } else if ( elementName.equals( "textarea" ) ) {
096                    bean.addPropertyValue("control", processTextareaControlElement(ele) );
097                } else if ( elementName.equals( "select" ) ) {
098                    bean.addPropertyValue("control", processSelectControlElement(ele) );
099                } else if ( elementName.equals( "radio" ) ) {
100                    bean.addPropertyValue("control", processRadioControlElement(ele) );
101                } else if ( elementName.equals( "hidden" ) ) {
102                    bean.addPropertyValue("control", processHiddenControlElement(ele) );
103                } else if ( elementName.equals( "user" ) ) {
104                    bean.addPropertyValue("control", processUserControlElement(ele) );
105                } else if ( elementName.equals( "checkbox" ) ) {
106                    bean.addPropertyValue("control", processCheckboxControlElement(ele) );
107                } else if ( elementName.equals( "validationPattern") ) {
108                    bean.addPropertyValue("validationPattern", processValidationPatternElement(ele) );
109                }
110            }
111        }
112        
113        protected BeanDefinition processTextControlElement( Element ele ) {
114            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "TextControlDefinition" );
115            
116            String size = ele.getAttribute("size");
117            if ( StringUtils.hasText(size) ) {
118                controlBean.addPropertyValue("size", Integer.valueOf(size) );
119            }
120            parseEmbeddedPropertyElements(ele, controlBean);
121            
122            return controlBean.getBeanDefinition();
123        }
124    
125        protected BeanDefinition processUserControlElement( Element ele ) {
126            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "KualiUserControlDefinition" );
127            
128            String universalIdAttribute = ele.getAttribute("universalIdAttribute");
129            if ( StringUtils.hasText(universalIdAttribute) ) {
130                controlBean.addPropertyValue("universalIdAttributeName", universalIdAttribute );
131            }
132            String userObjectAttribute = ele.getAttribute("userObjectAttribute");
133            if ( StringUtils.hasText(userObjectAttribute) ) {
134                controlBean.addPropertyValue("userIdAttributeName", userObjectAttribute + "." + KFSPropertyConstants.PERSON_USER_ID );
135                controlBean.addPropertyValue("personNameAttributeName", userObjectAttribute + "." + KFSPropertyConstants.PERSON_NAME );
136            }
137            parseEmbeddedPropertyElements(ele, controlBean);
138            
139            return controlBean.getBeanDefinition();
140        }
141    
142        protected BeanDefinition processTextareaControlElement( Element ele ) {
143            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "TextareaControlDefinition" );
144            
145            String rows = ele.getAttribute("rows");
146            if ( StringUtils.hasText(rows) ) {
147                controlBean.addPropertyValue("rows", Integer.valueOf(rows) );
148            }
149            String cols = ele.getAttribute("rows");
150            if ( StringUtils.hasText(cols) ) {
151                controlBean.addPropertyValue("cols", Integer.valueOf(cols) );
152            }
153            parseEmbeddedPropertyElements(ele, controlBean);
154            
155            return controlBean.getBeanDefinition();
156        }
157    
158        protected BeanDefinition processHiddenControlElement( Element ele ) {
159            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "HiddenControlDefinition" );
160            parseEmbeddedPropertyElements(ele, controlBean);
161            return controlBean.getBeanDefinition();
162        }
163    
164        protected BeanDefinition processCheckboxControlElement( Element ele ) {
165            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "CheckboxControlDefinition" );
166            parseEmbeddedPropertyElements(ele, controlBean);
167            return controlBean.getBeanDefinition();
168        }
169        
170        protected void setMultiValueControlAttributes( Element ele, BeanDefinitionBuilder controlBean ) {
171            String valuesFinderClass = ele.getAttribute("valuesFinderClass");
172            if ( StringUtils.hasText(valuesFinderClass) ) {
173                controlBean.addPropertyValue("valuesFinderClass", valuesFinderClass );
174            }
175            String boClass = ele.getAttribute("boClass");
176            if ( StringUtils.hasText(boClass) ) {
177                controlBean.addPropertyValue("boClass", boClass );
178            }
179            String keyAttribute = ele.getAttribute("keyAttribute");
180            if ( StringUtils.hasText(keyAttribute) ) {
181                controlBean.addPropertyValue("keyAttribute", keyAttribute );
182            }
183            String labelAttribute = ele.getAttribute("labelAttribute");
184            if ( StringUtils.hasText(labelAttribute) ) {
185                controlBean.addPropertyValue("labelAttribute", labelAttribute );
186            }
187            String includeKeyInLabel = ele.getAttribute("includeKeyInLabel");
188            if ( StringUtils.hasText(includeKeyInLabel) ) {
189                controlBean.addPropertyValue("includeKeyInLabel", Boolean.valueOf(includeKeyInLabel) );
190            }
191        }
192        
193        protected BeanDefinition processSelectControlElement( Element ele ) {
194            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "SelectControlDefinition" );
195            
196            setMultiValueControlAttributes( ele, controlBean );
197            parseEmbeddedPropertyElements(ele, controlBean);
198                      
199            return controlBean.getBeanDefinition();
200        }
201    
202        protected BeanDefinition processRadioControlElement( Element ele ) {
203            BeanDefinitionBuilder controlBean = BeanDefinitionBuilder.childBeanDefinition( "RadioControlDefinition" );
204    
205            setMultiValueControlAttributes( ele, controlBean );
206            parseEmbeddedPropertyElements(ele, controlBean);
207            
208            return controlBean.getBeanDefinition();
209        }
210    
211        protected BeanDefinition processValidationPatternElement( Element ele ) {
212            BeanDefinitionBuilder validatorBean = null;
213            String parent = ele.getAttribute( "parent" );
214            String validationPatternClass = ele.getAttribute( "validationPatternClass" );
215            if ( StringUtils.hasText(parent) ) {
216                validatorBean = BeanDefinitionBuilder.childBeanDefinition( parent );
217            } else if ( StringUtils.hasText(validationPatternClass)) {
218                try {
219                    validatorBean = BeanDefinitionBuilder.rootBeanDefinition(Class.forName(validationPatternClass));
220                } catch ( ClassNotFoundException ex ) {
221                    LOG.fatal( "Invalid class name given for validationPattern bean: " + validationPatternClass );
222                    throw new RuntimeException( "Invalid class name given for validationPattern bean: " + validationPatternClass, ex );
223                }
224            }
225            
226            parseEmbeddedPropertyElements(ele, validatorBean);
227                       
228            return validatorBean.getBeanDefinition();
229        }
230    }