001/**
002 * Copyright 2005-2017 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 */
016package org.kuali.rice.kew.xml;
017
018import org.jdom.Element;
019import org.jdom.Namespace;
020import org.kuali.rice.core.api.util.xml.XmlException;
021import org.kuali.rice.core.api.util.xml.XmlHelper;
022import org.kuali.rice.kew.rule.RuleBaseValues;
023import org.kuali.rice.kew.rule.RuleExtensionBo;
024import org.kuali.rice.kew.rule.RuleExtensionValue;
025import org.kuali.rice.kew.rule.bo.RuleAttribute;
026import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
027import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
028import org.kuali.rice.kew.service.KEWServiceLocator;
029
030import java.util.ArrayList;
031import java.util.Collection;
032import java.util.Iterator;
033import 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 */
044public 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}