View Javadoc

1   package org.kuali.rice.krms.api.repository.agenda;
2   
3   import java.io.Serializable;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.HashMap;
7   import java.util.Map;
8   
9   import javax.xml.bind.annotation.XmlAccessType;
10  import javax.xml.bind.annotation.XmlAccessorType;
11  import javax.xml.bind.annotation.XmlAnyElement;
12  import javax.xml.bind.annotation.XmlElement;
13  import javax.xml.bind.annotation.XmlRootElement;
14  import javax.xml.bind.annotation.XmlType;
15  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
16  
17  import org.apache.commons.lang.StringUtils;
18  import org.apache.commons.lang.builder.EqualsBuilder;
19  import org.apache.commons.lang.builder.HashCodeBuilder;
20  import org.apache.commons.lang.builder.ToStringBuilder;
21  import org.kuali.rice.core.api.CoreConstants;
22  import org.kuali.rice.core.api.mo.ModelBuilder;
23  import org.kuali.rice.core.api.mo.ModelObjectComplete;
24  import org.kuali.rice.core.util.jaxb.MapStringStringAdapter;
25  import org.kuali.rice.krms.api.repository.context.ContextDefinitionContract;
26  import org.kuali.rice.krms.api.repository.context.ContextDefinition.Builder;
27  
28  /**
29   * Concrete model object implementation of KRMS Repository Agenda 
30   * immutable. 
31   * Instances of Agenda can be (un)marshalled to and from XML.
32   *
33   * @see AgendaDefinitionContract
34   */
35  @XmlRootElement(name = AgendaDefinition.Constants.ROOT_ELEMENT_NAME)
36  @XmlAccessorType(XmlAccessType.NONE)
37  @XmlType(name = AgendaDefinition.Constants.TYPE_NAME, propOrder = {
38  		AgendaDefinition.Elements.AGENDA_ID,
39  		AgendaDefinition.Elements.NAME,
40  		AgendaDefinition.Elements.NAMESPACE_CODE,
41  		AgendaDefinition.Elements.TYPE_ID,
42  		AgendaDefinition.Elements.CONTEXT_ID,
43          AgendaDefinition.Elements.ACTIVE,
44  		AgendaDefinition.Elements.FIRST_ITEM_ID,
45  		AgendaDefinition.Elements.ATTRIBUTES,
46          CoreConstants.CommonElements.VERSION_NUMBER,
47  		CoreConstants.CommonElements.FUTURE_ELEMENTS
48  })
49  public final class AgendaDefinition implements AgendaDefinitionContract, ModelObjectComplete{
50  	private static final long serialVersionUID = 2783959459503209577L;
51  
52  	@XmlElement(name = Elements.AGENDA_ID, required = false)
53  	private final String id;
54  	
55  	@XmlElement(name = Elements.NAME, required = true)
56  	private final String name;
57  	
58  	@XmlElement(name = Elements.NAMESPACE_CODE, required = true)
59  	private final String namespaceCode;
60  	
61  	@XmlElement(name = Elements.TYPE_ID, required = false)
62  	private final String typeId;
63  	
64  	@XmlElement(name = Elements.CONTEXT_ID, required = true)
65  	private final String contextId;
66  
67      @XmlElement(name = Elements.ACTIVE, required = false)
68      private final boolean active;
69  	
70  	@XmlElement(name = Elements.FIRST_ITEM_ID, required = false)
71  	private final String firstItemId;
72  	
73  	@XmlElement(name = Elements.ATTRIBUTES, required = false)
74  	@XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
75  	private final Map<String, String> attributes;
76  	
77      @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
78      private final Long versionNumber;
79  
80      @SuppressWarnings("unused")
81      @XmlAnyElement
82      private final Collection<org.w3c.dom.Element> _futureElements = null;
83  	
84  	/** 
85       * This constructor should never be called.  
86       * It is only present for use during JAXB unmarshalling. 
87       */
88      private AgendaDefinition() {
89      	this.id = null;
90      	this.name = null;
91      	this.namespaceCode = null;
92      	this.typeId = null;
93      	this.contextId = null;
94          this.active = false;
95      	this.firstItemId = null;
96      	this.attributes = null;
97          this.versionNumber = null;
98      }
99      
100     /**
101 	 * Constructs a KRMS Repository Agenda object from the given builder.  
102 	 * This constructor is private and should only ever be invoked from the builder.
103 	 * 
104 	 * @param builder the Builder from which to construct the Agenda
105 	 */
106     private AgendaDefinition(Builder builder) {
107         this.id = builder.getId();
108         this.name = builder.getName();
109         this.namespaceCode = builder.getNamespaceCode();
110         this.typeId = builder.getTypeId();
111         this.contextId = builder.getContextId();
112         this.active = builder.isActive();
113         this.firstItemId = builder.getFirstItemId();
114         if (builder.getAttributes() != null){
115         	this.attributes = Collections.unmodifiableMap(new HashMap<String, String>(builder.getAttributes()));
116         } else {
117         	this.attributes = null;
118         }
119         this.versionNumber = builder.getVersionNumber();
120     }
121     
122 	@Override
123 	public String getId() {
124 		return this.id;
125 	}
126 
127 	@Override
128 	public String getName() {
129 		return this.name;
130 	}
131 
132 	@Override
133 	public String getNamespaceCode() {
134 		return this.namespaceCode;
135 	}
136 
137 	@Override
138 	public String getTypeId() {
139 		return this.typeId;
140 	}
141 
142 	@Override
143 	public String getContextId(){
144 		return this.contextId;
145 	}
146 
147     @Override
148     public boolean isActive() {
149         return this.active;
150     }
151 
152 	@Override
153 	public String getFirstItemId(){
154 		return this.firstItemId;
155 	}
156 	
157 	@Override
158 	public Map<String, String> getAttributes() {
159 		return this.attributes; 
160 	}
161 
162     @Override
163     public Long getVersionNumber() {
164         return versionNumber;
165     }
166     
167  	/**
168      * This builder is used to construct instances of KRMS Repository Agenda.  It enforces the constraints of the {@link AgendaDefinitionContract}.
169      */
170     public static class Builder implements AgendaDefinitionContract, ModelBuilder, Serializable {
171 		
172         private static final long serialVersionUID = -8862851720709537839L;
173         
174 		private String id;
175         private String name;
176         private String namespaceCode;
177         private String typeId;
178         private String contextId;
179         private boolean active;
180         private String firstItemId;
181         private Map<String, String> attributes;
182         private Long versionNumber;
183 
184 		/**
185 		 * Private constructor for creating a builder with all of it's required attributes.
186 		 */
187         private Builder(String id, String name, String namespaceCode, String typeId, String contextId) {
188         	setId(id);
189             setName(name);
190             setNamespaceCode(namespaceCode);
191             setTypeId(typeId);
192             setContextId(contextId);
193             setActive(true);
194             setAttributes(new HashMap<String, String>());
195         }
196         
197         public static Builder create(String id, String name, String namespaceCode, String typeId, String contextId){
198         	return new Builder(id, name, namespaceCode, typeId, contextId);
199         }
200         /**
201          * Creates a builder by populating it with data from the given {@link AgendaDefinitionContract}.
202          * 
203          * @param contract the contract from which to populate this builder
204          * @return an instance of the builder populated with data from the contract
205          */
206         public static Builder create(AgendaDefinitionContract contract) {
207         	if (contract == null) {
208                 throw new IllegalArgumentException("contract is null");
209             }
210             Builder builder =  new Builder(contract.getId(), contract.getName(),
211             		contract.getNamespaceCode(), contract.getTypeId(), contract.getContextId());
212             builder.setActive(contract.isActive());
213             builder.setFirstItemId( contract.getFirstItemId() );
214             if (contract.getAttributes() != null) {
215                 builder.setAttributes(new HashMap<String, String>(contract.getAttributes()));
216             }
217             builder.setVersionNumber(contract.getVersionNumber());
218             return builder;
219         }
220 
221 		/**
222 		 * Sets the value of the id on this builder to the given value.
223 		 * 
224 		 * @param id the id value to set, must not be null or blank
225 		 * @throws IllegalArgumentException if the id is null or blank
226 		 */
227 
228         public void setId(String agendaId) {
229             if (agendaId != null && StringUtils.isBlank(agendaId)) {
230                 throw new IllegalArgumentException("agenda ID must be null or non-blank");
231             }
232 			this.id = agendaId;
233 		}
234      
235         public void setName(String name) {
236             if (StringUtils.isBlank(name)) {
237                 throw new IllegalArgumentException("name is blank");
238             }
239 			this.name = name;
240 		}
241      
242         public void setNamespaceCode(String namespaceCode) {
243             if (StringUtils.isBlank(namespaceCode)) {
244                 throw new IllegalArgumentException("namespace is blank");
245             }
246 			this.namespaceCode = namespaceCode;
247 		}
248      
249 		public void setTypeId(String typeId) {
250 			if (StringUtils.isBlank(typeId)) {
251 	                throw new IllegalArgumentException("KRMS type id is blank");
252 			}
253 			this.typeId = typeId;
254 		}
255 		
256 		public void setContextId(String contextId) {
257 			if (StringUtils.isBlank(contextId)) {
258                 throw new IllegalArgumentException("context id is blank");
259 		}
260 			this.contextId = contextId;
261 		}
262 
263         public void setActive(boolean active) {
264             this.active = active;
265         }
266 		
267 		public void setFirstItemId(String firstItemId) {
268 			this.firstItemId = firstItemId;
269 		}
270 		
271 		public void setAttributes(Map<String, String> attributes){
272 			if (attributes == null){
273 				this.attributes = Collections.emptyMap();
274 			}
275 			this.attributes = Collections.unmodifiableMap(attributes);
276 		}
277 		
278 		/**
279          * Sets the version number for the style that will be returned by this
280          * builder.
281          * 
282          * <p>In general, this value should not be manually set on the builder,
283          * but rather copied from an existing {@link ContextDefinitionContract} when
284          * invoking {@link Builder#create(ContextDefinitionContract)}.
285          * 
286          * @param versionNumber the version number to set
287          */
288         public void setVersionNumber(Long versionNumber){
289             this.versionNumber = versionNumber;
290         }
291         
292 		@Override
293 		public String getId() {
294 			return id;
295 		}
296 
297 		@Override
298 		public String getName() {
299 			return name;
300 		}
301 
302 		@Override
303 		public String getNamespaceCode() {
304 			return namespaceCode;
305 		}
306 
307 		@Override
308 		public String getTypeId() {
309 			return typeId;
310 		}
311 
312 		@Override
313 		public String getContextId() {
314 			return contextId;
315 		}
316 
317         @Override
318         public boolean isActive() {
319             return active;
320         }
321 
322 		@Override
323 		public String getFirstItemId() {
324 			return firstItemId;
325 		}
326 
327 		@Override
328 		public Map<String, String> getAttributes() {
329 			return attributes;
330 		}
331 
332         @Override
333         public Long getVersionNumber() {
334             return versionNumber;
335         }
336 
337 		/**
338 		 * Builds an instance of a Agenda based on the current state of the builder.
339 		 * 
340 		 * @return the fully-constructed Agenda
341 		 */
342         @Override
343         public AgendaDefinition build() {
344             return new AgendaDefinition(this);
345         }
346 		
347     }
348 	@Override
349 	public int hashCode() {
350 		return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
351 	}
352 
353 	@Override
354 	public boolean equals(Object obj) {
355 		return EqualsBuilder.reflectionEquals(obj, this, Constants.HASH_CODE_EQUALS_EXCLUDE);
356 	}
357 
358 	@Override
359 	public String toString() {
360 		return ToStringBuilder.reflectionToString(this);
361 	}
362 	
363 	/**
364 	 * Defines some constants used on this class.
365 	 */
366 	public static class Constants {
367 		final static String ROOT_ELEMENT_NAME = "agenda";
368 		final static String TYPE_NAME = "AgendaType";
369 		final static String[] HASH_CODE_EQUALS_EXCLUDE = { "_furutreElements" };
370         public final static String EVENT = "Event";   // key for event attribute
371 	}
372 	
373 	/**
374 	 * A private class which exposes constants which define the XML element names to use
375 	 * when this object is marshalled to XML.
376 	 */
377 	public static class Elements {
378 		final static String AGENDA_ID = "id";
379 		final static String NAME = "name";
380 		final static String NAMESPACE_CODE = "namespaceCode";
381 		final static String TYPE_ID = "typeId";
382 		final static String CONTEXT_ID = "contextId";
383         final static String ACTIVE = "active";
384 		final static String FIRST_ITEM_ID = "firstItemId";
385 		final static String ATTRIBUTES = "attributes";
386 		final static String ATTRIBUTE = "attribute";
387 	}
388 
389 }