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.api.rule;
017    
018    import java.io.Serializable;
019    import java.util.Collection;
020    import java.util.Map;
021    import javax.xml.bind.annotation.XmlAccessType;
022    import javax.xml.bind.annotation.XmlAccessorType;
023    import javax.xml.bind.annotation.XmlAnyElement;
024    import javax.xml.bind.annotation.XmlElement;
025    import javax.xml.bind.annotation.XmlRootElement;
026    import javax.xml.bind.annotation.XmlType;
027    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
028    
029    import org.apache.commons.lang.ObjectUtils;
030    import org.kuali.rice.core.api.CoreConstants;
031    import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
032    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
033    import org.kuali.rice.core.api.mo.ModelBuilder;
034    import org.kuali.rice.core.api.util.collect.CollectionUtils;
035    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
036    import org.w3c.dom.Element;
037    
038    @XmlRootElement(name = RuleExtension.Constants.ROOT_ELEMENT_NAME)
039    @XmlAccessorType(XmlAccessType.NONE)
040    @XmlType(name = RuleExtension.Constants.TYPE_NAME, propOrder = {
041        RuleExtension.Elements.RULE_TEMPLATE_ATTRIBUTE,
042        RuleExtension.Elements.EXTENSION_VALUES_MAP,
043        CoreConstants.CommonElements.VERSION_NUMBER,
044        CoreConstants.CommonElements.FUTURE_ELEMENTS
045    })
046    public final class RuleExtension
047        extends AbstractDataTransferObject
048        implements RuleExtensionContract
049    {
050    
051        @XmlElement(name = Elements.RULE_TEMPLATE_ATTRIBUTE, required = true)
052        private final RuleTemplateAttribute ruleTemplateAttribute;
053        @XmlElement(name = Elements.EXTENSION_VALUES_MAP, required = false)
054        @XmlJavaTypeAdapter(MapStringStringAdapter.class)
055        private final Map<String, String> extensionValuesMap;
056        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
057        private final Long versionNumber;
058        @SuppressWarnings("unused")
059        @XmlAnyElement
060        private final Collection<Element> _futureElements = null;
061    
062        /**
063         * Private constructor used only by JAXB.
064         * 
065         */
066        private RuleExtension() {
067            this.ruleTemplateAttribute = null;
068            this.extensionValuesMap = null;
069            this.versionNumber = null;
070        }
071    
072        private RuleExtension(Builder builder) {
073            this.ruleTemplateAttribute = builder.getRuleTemplateAttribute().build();
074            this.extensionValuesMap = builder.getExtensionValuesMap();
075            this.versionNumber = builder.getVersionNumber();
076        }
077    
078        @Override
079        public RuleTemplateAttributeContract getRuleTemplateAttribute() {
080            return this.ruleTemplateAttribute;
081        }
082    
083        @Override
084        public Map<String, String> getExtensionValuesMap() {
085            return this.extensionValuesMap;
086        }
087    
088        @Override
089        public Long getVersionNumber() {
090            return this.versionNumber;
091        }
092    
093    
094        /**
095         * A builder which can be used to construct {@link RuleExtension} instances.  Enforces the constraints of the {@link RuleExtensionContract}.
096         * 
097         */
098        public final static class Builder
099            implements Serializable, ModelBuilder, RuleExtensionContract
100        {
101    
102            private RuleTemplateAttribute.Builder ruleTemplateAttribute;
103            private Map<String, String> extensionValuesMap;
104            private Long versionNumber;
105    
106            private Builder(RuleTemplateAttribute.Builder ruleTemplateAttribute) {
107                setRuleTemplateAttribute(ruleTemplateAttribute);
108            }
109    
110            public static Builder create(RuleTemplateAttribute.Builder ruleTemplateAttribute) {
111                return new Builder(ruleTemplateAttribute);
112            }
113    
114            public static Builder create(RuleExtensionContract contract) {
115                if (contract == null) {
116                    throw new IllegalArgumentException("contract was null");
117                }
118                // TODO if create() is modified to accept required parameters, this will need to be modified
119                Builder builder = create(RuleTemplateAttribute.Builder.create(contract.getRuleTemplateAttribute()));
120                builder.setExtensionValuesMap(contract.getExtensionValuesMap());
121                builder.setVersionNumber(contract.getVersionNumber());
122                return builder;
123            }
124    
125            public RuleExtension build() {
126                return new RuleExtension(this);
127            }
128    
129            @Override
130            public RuleTemplateAttribute.Builder getRuleTemplateAttribute() {
131                return this.ruleTemplateAttribute;
132            }
133    
134            @Override
135            public Map<String, String> getExtensionValuesMap() {
136                return this.extensionValuesMap;
137            }
138    
139            @Override
140            public Long getVersionNumber() {
141                return this.versionNumber;
142            }
143    
144            public void setRuleTemplateAttribute(RuleTemplateAttribute.Builder ruleTemplateAttribute) {
145                if (ruleTemplateAttribute == null) {
146                    throw new RiceIllegalArgumentException("ruleTemplateAttribute was null");
147                }
148                this.ruleTemplateAttribute = ruleTemplateAttribute;
149            }
150    
151            public void setExtensionValuesMap(Map<String, String> extensionValuesMap) {
152                this.extensionValuesMap = extensionValuesMap;
153            }
154    
155            public void setVersionNumber(Long versionNumber) {
156                this.versionNumber = versionNumber;
157            }
158    
159        }
160    
161        public boolean equals(Object o) {
162            if (o == null) return false;
163            if (!(o instanceof RuleExtension)) return false;
164            RuleExtension pred = (RuleExtension) o;
165            return ObjectUtils.equals(ruleTemplateAttribute, pred.getRuleTemplateAttribute()) &&
166                   CollectionUtils.collectionsEquivalent(extensionValuesMap.entrySet(), pred.getExtensionValuesMap().entrySet());
167        }
168    
169        /**
170         * Defines some internal constants used on this class.
171         * 
172         */
173        static class Constants {
174    
175            final static String ROOT_ELEMENT_NAME = "ruleExtension";
176            final static String TYPE_NAME = "RuleExtensionType";
177    
178        }
179    
180    
181        /**
182         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
183         * 
184         */
185        static class Elements {
186    
187            final static String RULE_TEMPLATE_ATTRIBUTE = "ruleTemplateAttribute";
188            final static String EXTENSION_VALUES_MAP = "extensionValuesMap";
189    
190        }
191    
192    }