View Javadoc

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