View Javadoc

1   /*******************************************************************************
2    *  Imixs Workflow 
3    *  Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,  
4    *  http://www.imixs.com
5    *  
6    *  This program is free software; you can redistribute it and/or 
7    *  modify it under the terms of the GNU General Public License 
8    *  as published by the Free Software Foundation; either version 2 
9    *  of the License, or (at your option) any later version.
10   *  
11   *  This program is distributed in the hope that it will be useful, 
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
14   *  General Public License for more details.
15   *  
16   *  You can receive a copy of the GNU General Public
17   *  License at http://www.gnu.org/licenses/gpl.html
18   *  
19   *  Project: 
20   *  	http://www.imixs.org
21   *  	http://java.net/projects/imixs-workflow
22   *  
23   *  Contributors:  
24   *  	Imixs Software Solutions GmbH - initial API and implementation
25   *  	Ralph Soika - Software Developer
26   *******************************************************************************/
27  
28  package org.imixs.workflow.jee.jpa;
29  
30  import java.util.ArrayList;
31  import java.util.Calendar;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Vector;
35  
36  import javax.persistence.Basic;
37  import javax.persistence.ElementCollection;
38  import javax.persistence.FetchType;
39  import javax.persistence.Id;
40  import javax.persistence.Lob;
41  import javax.persistence.OneToMany;
42  import javax.persistence.OrderBy;
43  import javax.persistence.PrePersist;
44  import javax.persistence.PreUpdate;
45  import javax.persistence.Temporal;
46  import javax.persistence.TemporalType;
47  import javax.persistence.Version;
48  
49  import org.imixs.workflow.WorkflowKernel;
50  
51  /**
52   * This Entity ejb is a wrapper class for the org.imixs.workflow.ItemCollection
53   * which is used in all Imixs Workflow Interfaces. The Entity is used by the
54   * EntityServiceBean to store ItemCollections into a database using the JEE Java
55   * Persistence API. Each Entity contains a universal unique ID to identify the
56   * Entity. Also the Entiy supports the additional properties
57   * <ul>
58   * <li>type
59   * <li>created
60   * <li>modified
61   * <li>readAccess
62   * <li>writeAccess
63   * <li>textItems
64   * <li>calendarItems
65   * <li>integerItems
66   * <li>
67   * </ul>
68   * 
69   * The creation time represents the point of time where the ItemCollection was
70   * first saved by the EntityService to the Database. The modify property
71   * represents the point of time where the ItemCollection was last saved by the
72   * EntityService. The type property is used to categorize entities in a
73   * database. This property is used by the save() method of the
74   * EntityServiceBean. So if an ItemCollection contains the attriubte 'type' the
75   * value will be automatically mapped to the type property. The properties read-
76   * and writeAccess containing the current access restrictions to an
77   * ItemCollection managed by the EntityService.
78   * <p>
79   * The data attribute is used to hold the ItemCollection data. It is mapped by a
80   * OR-Mapper to a large object (Lob). There is no way to query single attributes
81   * using the EJB Query Language. To support the powerful EJB Query language the
82   * Entity contains additional index properties to branch properties of an
83   * ItemCollection into onToMany relationships. These are the supported Index
84   * properties:
85   * <ul>
86   * <li>TextItem
87   * <li>IntegerItem
88   * <li>DoubleItem
89   * <li>CalendarItem
90   * </ul>
91   * A Client should not work directly with an instance of the Entity EJB or its
92   * index Properties. Its recommended to use the EntityService which acts as a
93   * session facade to manage instances of ItemCollection in a database system.
94   * <p>
95   * Notice: All relationships are marked as FetchType=EAGER. This is because the
96   * load and find Methods of the EntiyServiceBean do a clear() call to the
97   * PersitenceContext because the implodeEntity() method of the EntityServiceBean
98   * will modifies the values of an entity. So the Entity needs to be detached
99   * Immediately.
100  * <p>
101  * Why did the Entity Table use Join tables to link to OneToMany relationships ?
102  * <p>
103  * The default schema-level mapping for unidirectional one-to-many relationships
104  * uses a join table, as described in JSR 220 - Section 2.1.8.5. Unidirectional
105  * one-to-many relationships may be implemented using one-to-many foreign key
106  * mappings, however, such support is not required in this release. Applications
107  * that want to use a foreign key mapping strategy for one-to-many relationships
108  * should make these relationships bidirectional to ensure portability.
109  * <p>
110  * To store the Text-, Integer-, Double- and Calendar- Lists we can not use
111  * HashSet because the order in which elements are returned by a HashSet's
112  * iterator is not specified. This is the reason why we use Vectors to store the
113  * values and check for duplicates manually. So we make sure that values added
114  * to the list are not recorded
115  * 
116  * 
117  * @see org.imixs.workflow.jee.ejb.EntityService
118  * @see org.imixs.workflow.jee.ejb.EntityService
119  * @author rsoika
120  * @version 1.0
121  */
122 
123 @javax.persistence.Entity
124 public class Entity implements java.io.Serializable {
125 
126 	private static final long serialVersionUID = 1L;
127 	private String id;
128 	private Integer version;
129 	private String type;
130 	private Calendar created;
131 	private Calendar modified;
132 	private Map<String,Object> data;
133 	private List<ReadAccess> readAccessList;
134 	private List<WriteAccess> writeAccessList;
135 
136 	private List<TextItem> textItems;
137 	private List<IntegerItem> integerItems;
138 	private List<DoubleItem> doubleItems;
139 	private List<CalendarItem> calendarItems;
140 
141 	
142 	/**
143 	 * A Entity will be automatically initialized with a unique id and a
144 	 * creation date.
145 	 */
146 	public Entity() {
147 		/*
148 		 * Generate a new uniqueId
149 		 */
150 		id=WorkflowKernel.generateUniqueID();
151 		/*
152 		String sIDPart1 = Long.toHexString(System.currentTimeMillis());
153 		Double d = Math.random() * 900000000;
154 		int i = d.intValue();
155 		String sIDPart2 = Integer.toHexString(i);
156 		id = sIDPart1 + "-" + sIDPart2;
157 		*/
158 
159 		// Initialize objects
160 		Calendar cal = Calendar.getInstance();
161 		created = cal;
162 	}
163 
164 	/**
165 	 * This constructor allows the creation of an Entity Instance with a default
166 	 * uniqueID
167 	 * 
168 	 * @param aID
169 	 */
170 	public Entity(String aID) {
171 		this();
172 		if (aID != null && !"".equals(aID))
173 			id = aID;
174 	}
175 
176 	/**
177 	 * returns the unique identifier for the Entity.
178 	 * 
179 	 * @return universal id
180 	 */
181 	@Id
182 	public String getId() {
183 		return id;
184 	}
185 
186 	protected void setId(String aID) {
187 		id = aID;
188 	}
189 
190 	
191 	
192 	
193 	@Version
194 	public Integer getVersion() {
195 		return version;
196 	}
197 
198 	public void setVersion(Integer version) {
199 		this.version = version;
200 	}
201 
202 	/**
203 	 * returns the type property of the entity instance. This property can be
204 	 * provided by an itemColleciton in the attribute 'type'. Values will be
205 	 * case sensitive!
206 	 * 
207 	 * @see org.imixs.workflow.jee.ejb.EntityService
208 	 * @return
209 	 */
210 	public String getType() {
211 		return type;
212 	}
213 
214 	public void setType(String type) {
215 		this.type = type;
216 	}
217 
218 	/**
219 	 * returns the creation point of time.
220 	 * 
221 	 * @return time of creation
222 	 */
223 	@Temporal(TemporalType.TIMESTAMP)
224 	public Calendar getCreated() {
225 		return created;
226 	}
227 
228 	public void setCreated(Calendar created) {
229 		this.created = created;
230 	}
231 
232 	/**
233 	 * returns the last modification point of time
234 	 * 
235 	 * @return time of modification
236 	 */
237 	@Temporal(TemporalType.TIMESTAMP)
238 	public Calendar getModified() {
239 		return modified;
240 	}
241 
242 	public void setModified(Calendar modified) {
243 		this.modified = modified;
244 	}
245 
246 	/**
247 	 * updates the modification time before a update by a persistence manager is
248 	 * performed.
249 	 */
250 	@SuppressWarnings("unused")
251 	@PrePersist
252 	@PreUpdate
253 	private void updateModified() {
254 		Calendar cal = Calendar.getInstance();
255 		modified = cal;
256 	}
257 
258 	/**
259 	 * returns the data object part of the Entity represented by a
260 	 * java.util.Map
261 	 * 
262 	 * @return Map
263 	 */
264 	@Lob
265 	@Basic(fetch = FetchType.LAZY)
266 	public Map<String,Object> getData() {
267 		return data;
268 	}
269 
270 	/**
271 	 * sets a data object for this Entity.
272 	 * 
273 	 * @param data
274 	 */
275 	public void setData(Map<String,Object> itemCol) {
276 		this.data = itemCol;
277 	}
278 
279 	/**
280 	 * ReadAccess list is loaded eager as this need to be check on every access
281 	 * 
282 	 * @return ReadAccess list for the entity
283 	 */
284 	@OneToMany(fetch = FetchType.EAGER)
285 	public List<ReadAccess> getReadAccessList() {
286 		if (readAccessList==null)
287 			readAccessList=new ArrayList<ReadAccess>();
288 		return readAccessList;
289 	}
290 
291 	public void setReadAccessList(List<ReadAccess> readAccessList) {
292 		this.readAccessList = readAccessList;
293 	}
294 	
295 	
296 
297 	/**
298 	 * WrateAccess list is loaded lazy as this a check is only on update method
299 	 * needed
300 	 * 
301 	 * @return WriteAccess list for the entity
302 	 */
303 	@OneToMany(fetch = FetchType.LAZY)
304 	public List<WriteAccess> getWriteAccessList() {
305 		if (writeAccessList==null)
306 			writeAccessList=new ArrayList<WriteAccess>();
307 		return writeAccessList;
308 	}
309 
310 	public void setWriteAccessList(List<WriteAccess> writeAccessList) {
311 		this.writeAccessList = writeAccessList;
312 	}
313 	
314 	
315 	/**
316 	 * returns a list of all textItems joined to this Entity.
317 	 * 
318 	 * @return a collection of TextItem objects
319 	 */
320 	@OneToMany(fetch = FetchType.LAZY)
321 	public List<TextItem> getTextItems() {
322 		if (textItems == null)
323 			textItems = new Vector<TextItem>();
324 		return textItems;
325 	}
326 
327 	public void setTextItems(List<TextItem> textItems) {
328 		this.textItems = textItems;
329 	}
330 	
331 	
332 	/**
333 	 * returns a list of all integerItems joined to this Entity
334 	 * 
335 	 * @return a collection of IntegerItem objects
336 	 */
337 	@OneToMany(fetch = FetchType.LAZY)
338 	public List<IntegerItem> getIntegerItems() {
339 		if (integerItems == null)
340 			integerItems = new Vector<IntegerItem>();
341 		return integerItems;
342 	}
343 
344 	public void setIntegerItems(List<IntegerItem> integerItems) {
345 		this.integerItems = integerItems;
346 	}
347 
348 	/**
349 	 * returns a list of all doubleItems joined to this Entity
350 	 * 
351 	 * @return a collection of DoubleItem objects
352 	 */
353 	@OneToMany(fetch = FetchType.LAZY)
354 	public List<DoubleItem> getDoubleItems() {
355 		if (doubleItems == null)
356 			doubleItems = new Vector<DoubleItem>();
357 		return doubleItems;
358 	}
359 
360 	public void setDoubleItems(List<DoubleItem> doubleItems) {
361 		this.doubleItems = doubleItems;
362 	}
363 
364 	/**
365 	 * returns a list of all calendarItems joined to this Entity
366 	 * 
367 	 * @return a collection of CalendarItem objects
368 	 */
369 	@OneToMany(fetch = FetchType.LAZY)
370 	public List<CalendarItem> getCalendarItems() {
371 		if (calendarItems == null)
372 			calendarItems = new Vector<CalendarItem>();
373 		return calendarItems;
374 	}
375 
376 	public void setCalendarItems(List<CalendarItem> calendarItems) {
377 		this.calendarItems = calendarItems;
378 	}
379 
380 	
381 	
382 	
383 	
384 	/*
385 	@ElementCollection(fetch = FetchType.LAZY)
386 	public List<TextItem> getTextItems() {
387 		return textItems;
388 	}
389 
390 	public void setTextItems(List<TextItem> textItems) {
391 		this.textItems = textItems;
392 	}
393 	*/
394 
395 	
396 	/*
397 	@ElementCollection(fetch = FetchType.LAZY)
398 	public Map<String, List<String>> getTextItems() {
399 		return textItems;
400 	}
401 
402 	public void setTextItems(Map<String,List<String>> textItems) {
403 		this.textItems = textItems;
404 	}
405 
406 	@ElementCollection(fetch = FetchType.LAZY)
407 	public Map<String, List<Integer>> getIntegerItems() {
408 		return integerItems;
409 	}
410 
411 	public void setIntegerItems(Map<String, List<Integer>> integerItems) {
412 		this.integerItems = integerItems;
413 	}
414 	*/
415 }