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 */
016package org.kuali.rice.krms.api.repository.function;
017
018import java.io.Serializable;
019import java.util.Collection;
020
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlAnyElement;
024import javax.xml.bind.annotation.XmlElement;
025import javax.xml.bind.annotation.XmlRootElement;
026import javax.xml.bind.annotation.XmlType;
027
028import org.apache.commons.lang.StringUtils;
029import org.kuali.rice.core.api.CoreConstants;
030import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
031import org.kuali.rice.core.api.mo.ModelBuilder;
032import 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})
054public 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}