001    /**
002     * Copyright 2005-2012 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.krms.api.repository.proposition;
017    
018    import java.io.Serializable;
019    import java.util.Collection;
020    
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    
028    import org.apache.commons.lang.StringUtils;
029    import org.kuali.rice.core.api.CoreConstants;
030    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
031    import org.kuali.rice.core.api.mo.ModelBuilder;
032    
033    /**
034     * Concrete model object implementation of KRMS Proposition Parameter 
035     * immutable. 
036     * Instances of PropositionParameter can be (un)marshalled to and from XML.
037     *
038     * @see PropositionParameterContract
039     */
040    @XmlRootElement(name = PropositionParameter.Constants.ROOT_ELEMENT_NAME)
041    @XmlAccessorType(XmlAccessType.NONE)
042    @XmlType(name = PropositionParameter.Constants.TYPE_NAME, propOrder = {
043                    PropositionParameter.Elements.ID,
044                    PropositionParameter.Elements.PROP_ID,
045                    PropositionParameter.Elements.VALUE,
046                    PropositionParameter.Elements.PARM_TYPE,
047                    PropositionParameter.Elements.SEQUENCE,
048            CoreConstants.CommonElements.VERSION_NUMBER,
049                    CoreConstants.CommonElements.FUTURE_ELEMENTS
050    })
051    public final class PropositionParameter extends AbstractDataTransferObject implements PropositionParameterContract {
052            private static final long serialVersionUID = 2783959459503209577L;
053    
054            @XmlElement(name = Elements.ID, required=true)
055            private String id;
056            @XmlElement(name = Elements.PROP_ID, required=true)
057            private String propId;
058            @XmlElement(name = Elements.VALUE, required=true)
059            private String value;
060            @XmlElement(name = Elements.PARM_TYPE, required=true)
061            private String parameterType;
062            @XmlElement(name = Elements.SEQUENCE, required=true)
063            private Integer sequenceNumber;
064        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
065        private final Long versionNumber;
066            
067            @SuppressWarnings("unused")
068        @XmlAnyElement
069        private final Collection<org.w3c.dom.Element> _futureElements = null;
070            
071             /** 
072         * This constructor should never be called.  
073         * It is only present for use during JAXB unmarshalling. 
074         */
075        private PropositionParameter() {
076            this.id = null;
077            this.propId = null;
078            this.value = null;
079            this.parameterType = null;
080            this.sequenceNumber = null;
081            this.versionNumber = null;
082        }
083        
084        /**
085             * Constructs a PropositionParameter from the given builder.  
086             * This constructor is private and should only ever be invoked from the builder.
087             * 
088             * @param builder the Builder from which to construct the PropositionParameter
089             */
090        private PropositionParameter(Builder builder) {
091            this.id = builder.getId();
092            this.propId = builder.getPropId();
093            this.value = builder.getValue();
094            this.parameterType = builder.getParameterType();
095            this.sequenceNumber = builder.getSequenceNumber();
096            this.versionNumber = builder.getVersionNumber();
097        }
098        
099            @Override
100            public String getId() {
101                    return this.id;
102            }
103            
104            @Override
105            public String getPropId() {
106                    return this.propId;
107            }
108    
109            @Override
110            public String getValue() {
111                    return this.value;
112            }
113    
114            @Override
115            public String getParameterType() {
116                    return this.parameterType;
117            }
118            @Override
119            public Integer getSequenceNumber() {
120                    return this.sequenceNumber; 
121            }
122    
123        @Override
124        public Long getVersionNumber() {
125            return versionNumber;
126        }
127            
128            /**
129         * This builder is used to construct instances of PropositionParameter.  
130         * It enforces the constraints of the {@link PropositionParameterContract}.
131         */
132        public static class Builder implements PropositionParameterContract, ModelBuilder, Serializable {
133            private static final long serialVersionUID = -6889320709850568900L;
134                    
135                    private String id;
136            private String propId;
137            private String value;
138            private String parameterType;
139            private Integer sequenceNumber;
140            private Long versionNumber;
141            private PropositionDefinition.Builder proposition;
142    
143            /**
144             * Private constructor for creating a builder with all of it's required attributes.
145             * @param id the id value to set, must not be null or blank
146             * @param propId the propId value to set, must not be null or blank
147             * @param value the value value to set, must not be null or blank
148             * @param parameterType the value parameterType to set, must not be null or blank
149             * @param sequenceNumber the value sequenceNumber to set, must not be null or blank
150             */
151            private Builder(String id, String propId, String value, String parameterType, Integer sequenceNumber) {
152                setId(id);
153                setPropId(propId);
154                setValue(value);
155                setParameterType(parameterType);
156                            setSequenceNumber(sequenceNumber);
157            }
158    
159            /**
160             * Create a builder using the given values
161             * @param id the id value to set, must not be null or blank
162             * @param propId the propId value to set, must not be null or blank
163             * @param value the value value to set, must not be null or blank
164             * @param parameterType the value parameterType to set, must not be null or blank
165             * @param sequenceNumber the value sequenceNumber to set, must not be null or blank
166             * @return Builder with the given values set
167             */
168            public static Builder create(String id, String propId, String value, String parameterType, Integer sequenceNumber) {
169                    return new Builder(id, propId, value, parameterType, sequenceNumber);
170            }
171    
172            /**
173             * Creates a builder by populating it with data from the given {@link PropositionParameterContract}.
174             * 
175             * @param contract the contract from which to populate this builder
176             * @return an instance of the builder populated with data from the contract
177             */
178            public static Builder create(PropositionParameterContract contract) {
179                    if (contract == null) {
180                    throw new IllegalArgumentException("contract is null");
181                }
182                Builder builder =  new Builder(contract.getId(), contract.getPropId(), contract.getValue(), contract.getParameterType(), contract.getSequenceNumber());
183                builder.setVersionNumber(contract.getVersionNumber());
184                return builder;
185            }
186    
187                    /**
188                     * Sets the value of the id on this builder to the given value.
189                     * 
190                     * @param id the id value to set, must not be null or blank
191                     * @throws IllegalArgumentException if the id is null or blank
192                     */
193            public void setId(String id) {
194                if (id != null && StringUtils.isBlank(id)) {
195                    throw new IllegalArgumentException("id must not be null or blank");
196                }
197                this.id = id;
198            }
199    
200            /**
201             * Sets the value of the propId on this builder to the given value.
202             *
203             * @param propId the propId value to set, must not be null or blank
204             * @throws IllegalArgumentException if the propId is null or blank
205             */
206                    public void setPropId(String propId) {
207                        // have to be able to create it with a null propId for chicken/egg reasons.
208                if (null != propId && StringUtils.isBlank(propId)) {
209                    throw new IllegalArgumentException("propId must be not be null or blank");
210                }
211                            this.propId = propId;
212                    }
213    
214            /**
215             * Sets the value of the value on this builder to the given value.
216             *
217             * @param value the value value to set, must not be null or blank
218             * @throws IllegalArgumentException if the value is null or blank
219             */
220                    public void setValue(String value) {
221                if (StringUtils.isBlank(value)) {
222                    throw new IllegalArgumentException("value must not be null or blank");
223                }
224                            this.value = value;
225                    }
226    
227            /**
228             * Sets the value of the parameterType on this builder to the given value.
229             *
230             * @param parameterType the value parameterType to set, must not be null or blank
231             * @throws IllegalArgumentException if the parameterType is null, blank, or invalid
232             */
233                    public void setParameterType(String parameterType) {
234                            if (StringUtils.isBlank(parameterType)){
235                            throw new IllegalArgumentException("parameter type is null or blank");
236                            }
237                            if (!PropositionParameterType.VALID_TYPE_CODES.contains(parameterType)){
238                    throw new IllegalArgumentException("parameter type is invalid");                                
239                            }
240                            // TODO: check against valid values
241                            this.parameterType = parameterType;
242                    }
243    
244            /**
245             * Sets the value of the sequenceNumber on this builder to the given value.
246             *
247             * @param sequenceNumber the value sequenceNumber to set, must not be null or blank
248             * @throws IllegalArgumentException if the sequenceNumber is null, blank, or invalid
249             */
250                    public void setSequenceNumber(Integer sequenceNumber) {
251                            if (sequenceNumber == null) {
252                    throw new IllegalArgumentException("sequenceNumber type is blank");
253                            }
254                            this.sequenceNumber = sequenceNumber;
255                    }
256    
257            /**
258             * Sets the value of the proposition on this builder to the given value.
259             *
260             * @param proposition the value proposition to set
261             */
262                    public void setProposition(PropositionDefinition.Builder proposition) {
263                        if (proposition != null && !StringUtils.isBlank(proposition.getId())) {
264                            setPropId(proposition.getId());
265                        }
266                        this.proposition = proposition;
267                    }
268    
269            /**
270             * Sets the value of the versionNumber on this builder to the given value.
271             *
272             * @param versionNumber the value versionNumber to set
273             */
274            public void setVersionNumber(Long versionNumber){
275                this.versionNumber = versionNumber;
276            }
277            
278                    @Override
279                    public String getId() {
280                            return id;
281                    }
282    
283                    @Override
284                    public String getPropId() {
285                            return propId;
286                    }
287    
288                    @Override
289                    public String getValue() {
290                            return value;
291                    }
292    
293                    @Override
294                    public String getParameterType() {
295                            return parameterType;
296                    }
297    
298                    @Override
299                    public Integer getSequenceNumber() {
300                            return sequenceNumber;
301                    }
302    
303            @Override
304            public Long getVersionNumber() {
305                return versionNumber;
306            }
307    
308                    /**
309                     * Builds an instance of a PropositionParameter based on the current state of the builder.
310                     * 
311                     * @return the fully-constructed PropositionParameter
312                     */
313            @Override
314            public PropositionParameter build() {
315                if (proposition == null && StringUtils.isBlank(propId)) {
316                    throw new IllegalStateException("either proposition must be non-null or propId must be non-blank");
317                }
318                return new PropositionParameter(this);
319            }
320                    
321        }
322            
323            /**
324             * Defines some internal constants used on this class.
325             */
326            static class Constants {
327                    final static String ROOT_ELEMENT_NAME = "PropositionParameter";
328                    final static String TYPE_NAME = "PropositionParameterType";
329            }
330            
331            /**
332             * A private class which exposes constants which define the XML element names to use
333             * when this object is marshalled to XML.
334             */
335            public static class Elements {
336                    final static String ID = "id";
337                    final static String PROP_ID = "propId";
338                    final static String VALUE = "value";
339                    final static String PARM_TYPE = "parameterType";
340                    final static String SEQUENCE = "sequenceNumber";
341            }
342    
343    }