001    /**
002     * Copyright 2005-2013 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.rice.kew.xml;
017    
018    import org.jdom.Element;
019    import org.jdom.Namespace;
020    import org.kuali.rice.core.api.util.xml.XmlException;
021    import org.kuali.rice.core.api.util.xml.XmlHelper;
022    import org.kuali.rice.kew.rule.RuleBaseValues;
023    import org.kuali.rice.kew.rule.RuleExtensionBo;
024    import org.kuali.rice.kew.rule.RuleExtensionValue;
025    import org.kuali.rice.kew.rule.bo.RuleAttribute;
026    import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
027    import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
028    import org.kuali.rice.kew.service.KEWServiceLocator;
029    
030    import java.util.ArrayList;
031    import java.util.Collection;
032    import java.util.Iterator;
033    import java.util.List;
034    
035    
036    /**
037     * Parses {@link org.kuali.rice.kew.rule.RuleExtensionBo}s from XML.
038     *
039     * @see org.kuali.rice.kew.rule.RuleExtensionBo
040     * @see RuleExtensionValue
041     *
042     * @author Kuali Rice Team (rice.collab@kuali.org)
043     */
044    public class RuleExtensionXmlParser {
045    
046        private static final Namespace NAMESPACE = Namespace.getNamespace("", "ns:workflow/Rule");
047        private static final String RULE_EXTENSION = "ruleExtension";
048        private static final String ATTRIBUTE = "attribute";
049        private static final String RULE_TEMPLATE = "ruleTemplate";
050        private static final String RULE_EXTENSION_VALUES = "ruleExtensionValues";
051        private static final String RULE_EXTENSION_VALUE = "ruleExtensionValue";
052        private static final String KEY = "key";
053        private static final String VALUE = "value";
054    
055        public List parseRuleExtensions(Element element, RuleBaseValues rule) throws XmlException {
056            List ruleExtensions = new ArrayList();
057            Collection<Element> ruleElements = XmlHelper.findElements(element, RULE_EXTENSION);
058            for (Iterator iterator = ruleElements.iterator(); iterator.hasNext();) {
059                ruleExtensions.add(parseRuleExtension((Element) iterator.next(), rule));
060            }
061            return ruleExtensions;
062        }
063    
064        private RuleExtensionBo parseRuleExtension(Element element, RuleBaseValues rule) throws XmlException {
065            String attributeName = element.getChildText(ATTRIBUTE, NAMESPACE);
066            String templateName = element.getChildText(RULE_TEMPLATE, NAMESPACE);
067            Element valuesElement = element.getChild(RULE_EXTENSION_VALUES, NAMESPACE);
068            if (attributeName == null) {
069                throw new XmlException("Rule extension must have a valid attribute.");
070            }
071            if (templateName == null) {
072                throw new XmlException("Rule extension must have a valid rule template.");
073            }
074            RuleAttribute ruleAttribute = KEWServiceLocator.getRuleAttributeService().findByName(attributeName);
075            if (ruleAttribute == null) {
076                throw new XmlException("Could not locate attribute for the given name '" + attributeName + "'");
077            }
078            RuleTemplateBo ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(templateName);
079            if (ruleTemplate == null) {
080                throw new XmlException("Could not locate rule template for the given name '" + templateName + "'");
081            }
082            RuleExtensionBo extension = new RuleExtensionBo();
083            extension.setRuleBaseValues(rule);
084            boolean attributeFound = false;
085            for (Iterator iter = ruleTemplate.getActiveRuleTemplateAttributes().iterator(); iter.hasNext();) {
086                RuleTemplateAttributeBo templateAttribute = (RuleTemplateAttributeBo) iter.next();
087                if (templateAttribute.getRuleAttributeId().equals(ruleAttribute.getId())) {
088                    extension.setRuleTemplateAttribute(templateAttribute);
089                    extension.setRuleTemplateAttributeId(templateAttribute.getId());
090                    attributeFound = true;
091                    break;
092                }
093            }
094    
095            if (!attributeFound) {
096                // TODO: need test case for this
097                throw new XmlException("Attribute '" + attributeName + "' not found on template '" + ruleTemplate.getName() + "'");
098            }
099    
100            extension.setExtensionValues(parseRuleExtensionValues(valuesElement, extension));
101            return extension;
102        }
103    
104        private List parseRuleExtensionValues(Element element, RuleExtensionBo ruleExtension) throws XmlException {
105            List values = new ArrayList();
106            if (element == null) {
107                return values;
108            }
109            Collection<Element> valueElements = XmlHelper.findElements(element, RULE_EXTENSION_VALUE);
110            for (Iterator iterator = valueElements.iterator(); iterator.hasNext();) {
111                Element valueElement = (Element) iterator.next();
112                values.add(parseRuleExtensionValue(valueElement, ruleExtension));
113            }
114            return values;
115        }
116    
117        private RuleExtensionValue parseRuleExtensionValue(Element element, RuleExtensionBo ruleExtension) throws XmlException {
118            String key = element.getChildText(KEY, NAMESPACE);
119            String value = element.getChildText(VALUE, NAMESPACE);
120            if (org.apache.commons.lang.StringUtils.isEmpty(key)) {
121                throw new XmlException("RuleExtensionValue must have a non-empty key.");
122            }
123            if (value == null) {
124                throw new XmlException("RuleExtensionValue must have a non-null value.");
125            }
126            RuleExtensionValue extensionValue = new RuleExtensionValue(key, value);
127            extensionValue.setExtension(ruleExtension);
128            return extensionValue;
129        }
130    
131    }