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.function;
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    import org.w3c.dom.Element;
033    
034    /**
035     * An immutable representation of a function parameter definition.
036     * 
037     * @see FunctionParameterDefinitionContract
038     * 
039     * @author Kuali Rice Team (rice.collab@kuali.org)
040     *
041     */
042    @XmlRootElement(name = FunctionParameterDefinition.Constants.ROOT_ELEMENT_NAME)
043    @XmlAccessorType(XmlAccessType.NONE)
044    @XmlType(name = FunctionParameterDefinition.Constants.TYPE_NAME, propOrder = {
045                    FunctionParameterDefinition.Elements.ID,
046                    FunctionParameterDefinition.Elements.NAME,
047                    FunctionParameterDefinition.Elements.DESCRIPTION,
048                    FunctionParameterDefinition.Elements.PARAMETER_TYPE,
049                    FunctionParameterDefinition.Elements.SEQUENCE,
050                    FunctionParameterDefinition.Elements.FUNCTION_ID,
051            CoreConstants.CommonElements.VERSION_NUMBER,
052            CoreConstants.CommonElements.FUTURE_ELEMENTS
053    })
054    public class FunctionParameterDefinition extends AbstractDataTransferObject implements FunctionParameterDefinitionContract {
055    
056            private static final long serialVersionUID = 1391030685309770560L;
057    
058            @XmlElement(name = Elements.ID, required = false)
059            private final String id;
060                    
061            @XmlElement(name = Elements.NAME, required = true)
062            private final String name;
063            
064            @XmlElement(name = Elements.DESCRIPTION, required = false)
065            private final String description;
066            
067            @XmlElement(name = Elements.TYPE, required = true)
068            private final String parameterType;
069            
070            @XmlElement(name = Elements.FUNCTION_ID, required = true)
071            private final String functionId;
072            
073            @XmlElement(name = Elements.SEQUENCE, required=true)
074            private Integer sequenceNumber;
075    
076            @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
077            private final Long versionNumber;
078            
079            @SuppressWarnings("unused")
080        @XmlAnyElement
081        private final Collection<Element> _futureElements = null;
082            
083            /**
084         * Private constructor used only by JAXB.
085         */
086        private FunctionParameterDefinition() {
087            this.id = null;
088            this.name = null;
089            this.description = null;
090            this.parameterType = null;
091            this.functionId = null;
092            this.sequenceNumber = null;
093            this.versionNumber = null;
094        }
095    
096        /**
097         * Constructs a FunctionParameterDefinition from the given builder.  This constructor is private and should only
098         * ever be invoked from the builder.
099         *
100         * @param builder the Builder from which to construct the FunctionParameterDefinition
101         */
102        private FunctionParameterDefinition(Builder builder) {
103            this.id = builder.getId();
104            this.name = builder.getName();
105            this.description = builder.getDescription();
106            this.parameterType = builder.getParameterType();
107            this.functionId = builder.getFunctionId();
108            this.sequenceNumber = builder.getSequenceNumber();
109            this.versionNumber = builder.getVersionNumber();
110        }
111        
112            @Override
113            public String getId() {
114                    return id;
115            }
116    
117            @Override
118            public String getName() {
119                    return name;
120            }
121    
122            @Override
123            public String getDescription() {
124                    return description;
125            }
126            
127            @Override
128            public String getParameterType() {
129                    return parameterType;
130            }
131            
132            @Override
133            public String getFunctionId() {
134                    return functionId;
135            }
136            
137            @Override
138            public Long getVersionNumber() {
139                    return versionNumber;
140            }
141    
142            @Override
143            public Integer getSequenceNumber() {
144                    return sequenceNumber;
145            }
146    
147            /**
148             * A builder which can be used to construct {@link FunctionParameterDefinition}
149             * instances.  Enforces the constraints of the {@link FunctionParameterDefinitionContract}.
150             * 
151             * @author Kuali Rice Team (rice.collab@kuali.org)
152             *
153             */
154            public static final class Builder implements FunctionParameterDefinitionContract, ModelBuilder, Serializable  {
155                    
156            private static final long serialVersionUID = -4470376239998290245L;
157            
158                    private String id;
159            private String name;
160            private String description;
161            private String functionId;
162            private String parameterType;
163            private Integer sequenceNumber;
164            private Long versionNumber;
165    
166            /**
167             * Private constructor use the create method.
168             * @param name to use when building
169             * @param type to use when building
170             * @param sequenceNumber to use when building
171             */
172            private Builder(String name, String type, Integer sequenceNumber) {
173                    setName(name);
174                    setParameterType(type);
175                    setSequenceNumber(sequenceNumber);
176            }
177            
178            /**
179             * Creates a function parameter definition builder with the given required values.  This builder
180             * is the only means by which a {@link FunctionParameterDefinition} object should be created.
181             * 
182             * @param name the name of the function parameter definition to create, must not be null or blank
183             * @param type the type of the function parameter definition to create, must not be null or blank
184             * 
185             * @return a builder with the required values already initialized
186             * 
187             * @throws IllegalArgumentException if any of the given arguments is null or blank
188             */
189            public static Builder create(String name, String type, Integer sequenceNumber) {
190                    return new Builder(name, type, sequenceNumber);
191            }
192            
193            /**
194             * Creates and populates a builder with the data on the given {@link FunctionParameterDefinitionContract}.
195             * This is similar in nature to a "copy constructor" for {@link FunctionParameterDefinition}.
196             * 
197             * @param contract an object implementing the {@link FunctionParameterDefinitionContract} from which
198             * to copy property values
199             *  
200             * @return a builder with the values from the contract already initialized
201             * 
202             * @throws IllegalArgumentException if the given contract is null
203             */
204            public static Builder create(FunctionParameterDefinitionContract contract) {
205                    if (contract == null) {
206                            throw new IllegalArgumentException("contract was null");
207                    }
208                    Builder builder = create(contract.getName(), contract.getParameterType(), contract.getSequenceNumber());
209                    builder.setId(contract.getId());
210                    builder.setDescription(contract.getDescription());
211                    builder.setParameterType(contract.getParameterType());
212                    builder.setFunctionId(contract.getFunctionId());
213                    builder.setVersionNumber(contract.getVersionNumber());
214                    return builder;
215            }
216    
217            @Override
218            public FunctionParameterDefinition build() {
219                    return new FunctionParameterDefinition(this);
220            }
221            
222            @Override
223                    public String getId() {
224                            return this.id;
225                    }
226    
227            /**
228             * Sets the id for the function parameter definition that will be returned by this builder.
229             * 
230             * @param id the function parameter definition id to set
231             */
232                    public void setId(String id) {
233                            this.id = id;
234                    }
235    
236                    @Override
237                    public String getName() {
238                            return this.name;
239                    }
240    
241                    /**
242             * Sets the name for the function parameter definition that will be returned by this builder.
243             * The name must not be null or blank.
244             * 
245             * @param name the name to set on this builder, must not be null or blank
246             */
247                    public void setName(String name) {
248                            if (StringUtils.isBlank(name)) {
249                                    throw new IllegalArgumentException("name was blank");
250                            }
251                            this.name = name;
252                    }
253                    
254                    @Override
255                    public String getDescription() {
256                            return this.description;
257                    }
258    
259            /**
260             * Sets the description for the function parameter definition that will be returned by this builder.
261             * 
262             * @param description the description to set on this builder
263             */
264                    public void setDescription(String description) {
265                            this.description = description;
266                    }
267    
268                    @Override
269                    public String getParameterType() {
270                            return this.parameterType;
271                    }
272    
273                    /**
274             * Sets the type for the function parameter definition that will be
275             * returned by this builder.  This can be one of a set of "built-in"
276             * data types or a custom datatype represented as a fully qualified
277             * java class name.  The type must not be null or blank.
278             * 
279             * @param type the type to set on this builder, must not be null or blank
280             */
281                    public void setParameterType(String type) {
282                            if (StringUtils.isBlank(type)) {
283                                    throw new IllegalArgumentException("type was blank");
284                            }
285                            this.parameterType = type;
286                    }
287    
288                    @Override
289                    public String getFunctionId() {
290                            return this.functionId;
291                    }
292    
293                    /**
294             * Sets the type for the function id
295             * If provided, the function id must be non-blank.
296             * Must allow id to be null, to prevent chicken/egg problems.
297             * 
298             * @param functionId the functionId to set on this builder, must be either null or non-blank
299             */
300                    public void setFunctionId(String functionId) {
301                            if (functionId != null && StringUtils.isBlank(functionId)) {
302                                    throw new IllegalArgumentException("functionId must be null or non-blank");
303                            }
304                            this.functionId = functionId;
305                    }
306    
307                    @Override
308                    public Integer getSequenceNumber() {
309                            return this.sequenceNumber;
310                    }
311    
312                    /**
313             * Sets the sequence number for the function parameter definition that
314             * will be returned by this builder. This is the position in the functions
315             * parameter list.
316             * 
317             * @param sequenceNumber the position of the parameter in the function parameter list
318             */
319                    public void setSequenceNumber(Integer sequenceNumber) {
320                            this.sequenceNumber = sequenceNumber;
321                    }
322    
323                    @Override
324                    public Long getVersionNumber() {
325                            return this.versionNumber;
326                    }
327    
328                    /**
329             * Sets the version number for the function parameter definition that
330             * will be returned by this builder.
331             * 
332             * <p>In general, this value should not be manually set on the builder,
333             * but rather copied from an existing {@link FunctionParameterDefinitionContract} when
334             * invoking {@link Builder#create(FunctionParameterDefinitionContract)}.
335             * 
336             * @param versionNumber the version number to set
337             */
338                    public void setVersionNumber(Long versionNumber) {
339                            this.versionNumber = versionNumber;
340                    }
341    
342            }
343            
344            /**
345         * Defines some internal constants used on this class.
346         */
347        static class Constants {
348            final static String ROOT_ELEMENT_NAME = "functionParameter";
349            final static String TYPE_NAME = "FunctionParameterType";
350        }
351    
352        /**
353         * A private class which exposes constants which define the XML element names to use
354         * when this object is marshalled to XML.
355         */
356        static class Elements {
357            final static String ID = "id";
358            final static String NAME = "name";
359            final static String DESCRIPTION = "description";
360            final static String PARAMETER_TYPE = "parameterType";
361            final static String TYPE = "type";
362            final static String FUNCTION_ID = "functionId";
363                    final static String SEQUENCE = "sequenceNumber";
364        }
365        
366    }