PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/src/org/rapla/entities/domain/internal/ReservationImpl.java

http://rapla.googlecode.com/
Java | 446 lines | 360 code | 60 blank | 26 comment | 67 complexity | 1d4e4902c53b60235f39de783cc746d5 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, CPL-1.0, LGPL-2.0, AGPL-1.0
  1. /*--------------------------------------------------------------------------*
  2. | Copyright (C) 2006 Christopher Kohlhaas |
  3. | |
  4. | This program is free software; you can redistribute it and/or modify |
  5. | it under the terms of the GNU General Public License as published by the |
  6. | Free Software Foundation. A copy of the license has been included with |
  7. | these distribution in the COPYING file, if not go to www.fsf.org . |
  8. | |
  9. | As a special exception, you are granted the permissions to link this |
  10. | program with every library, of which license fullfill the Open Source |
  11. | Definition as published by the Open Source Initiative (OSI). |
  12. *--------------------------------------------------------------------------*/
  13. package org.rapla.entities.domain.internal;
  14. /** The default Implementation of the <code>Reservation</code>
  15. * @see ModificationEvent
  16. * @see org.rapla.facade.ClientFacade
  17. */
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Date;
  21. import java.util.HashMap;
  22. import java.util.HashSet;
  23. import java.util.Iterator;
  24. import java.util.Locale;
  25. import java.util.Map;
  26. import org.rapla.components.util.Assert;
  27. import org.rapla.components.util.iterator.IteratorChain;
  28. import org.rapla.entities.EntityNotFoundException;
  29. import org.rapla.entities.RaplaType;
  30. import org.rapla.entities.domain.Allocatable;
  31. import org.rapla.entities.domain.Appointment;
  32. import org.rapla.entities.domain.Reservation;
  33. import org.rapla.entities.dynamictype.Classification;
  34. import org.rapla.entities.dynamictype.DynamicType;
  35. import org.rapla.entities.dynamictype.internal.ClassificationImpl;
  36. import org.rapla.entities.internal.ModifiableTimestamp;
  37. import org.rapla.entities.storage.CannotExistWithoutTypeException;
  38. import org.rapla.entities.storage.DynamicTypeDependant;
  39. import org.rapla.entities.storage.EntityResolver;
  40. import org.rapla.entities.storage.RefEntity;
  41. import org.rapla.entities.storage.internal.SimpleEntity;
  42. public class ReservationImpl extends SimpleEntity<Reservation> implements Reservation,java.io.Serializable, ModifiableTimestamp, DynamicTypeDependant
  43. {
  44. // Don't forget to increase the serialVersionUID when you change the fields
  45. private static final long serialVersionUID = 1;
  46. private ClassificationImpl classification;
  47. private Map restrictions;
  48. private Date lastChanged;
  49. private Date createDate;
  50. private Date slotDate;
  51. transient private boolean allocatableArrayUpToDate = false;
  52. transient private boolean appointmentArrayUpToDate = false;
  53. // The resolved references
  54. transient private Allocatable[] allocatables;
  55. transient private Allocatable[] persons;
  56. transient private Allocatable[] resources;
  57. transient private Appointment[] appointments;
  58. ReservationImpl() {
  59. this (null, null);
  60. }
  61. public ReservationImpl( Date createDate, Date lastChanged ) {
  62. this.createDate = createDate;
  63. if (createDate == null)
  64. this.createDate = new Date();
  65. this.lastChanged = lastChanged;
  66. if (lastChanged == null)
  67. this.lastChanged = this.createDate;
  68. }
  69. public void resolveEntities( EntityResolver resolver) throws EntityNotFoundException {
  70. super.resolveEntities( resolver);
  71. allocatableArrayUpToDate = false;
  72. appointmentArrayUpToDate = false;
  73. classification.resolveEntities( resolver);
  74. }
  75. public void setReadOnly(boolean enable) {
  76. super.setReadOnly( enable );
  77. classification.setReadOnly( enable );
  78. }
  79. final public RaplaType getRaplaType() {return TYPE;}
  80. // Implementation of interface classifiable
  81. public Classification getClassification() { return classification; }
  82. public void setClassification(Classification classification) {
  83. checkWritable();
  84. this.classification = (ClassificationImpl) classification;
  85. }
  86. public String getName(Locale locale) {
  87. Classification c = getClassification();
  88. if (c == null)
  89. return "";
  90. return c.getName(locale);
  91. }
  92. public Date getLastChangeTime() {
  93. return lastChanged;
  94. }
  95. public Date getCreateTime() {
  96. return createDate;
  97. }
  98. public void setLastChanged(Date date) {
  99. lastChanged = date;
  100. }
  101. public Appointment[] getAppointments() {
  102. updateAppointmentArray();
  103. return appointments;
  104. }
  105. public Iterator<RefEntity<?>> getReferences() {
  106. return new IteratorChain<RefEntity<?>>
  107. (
  108. super.getReferences()
  109. ,classification.getReferences()
  110. )
  111. ;
  112. }
  113. public boolean isRefering(RefEntity object) {
  114. if (super.isRefering(object))
  115. return true;
  116. return classification.isRefering(object);
  117. }
  118. public void addAppointment(Appointment appointment) {
  119. checkWritable();
  120. if (super.isSubEntity((RefEntity) appointment))
  121. return;
  122. if (appointment.getReservation() != null
  123. && !this.isIdentical(appointment.getReservation()))
  124. throw new IllegalStateException("Appointment '" + appointment
  125. + "' belongs to another reservation :"
  126. + appointment.getReservation());
  127. ((AppointmentImpl) appointment).setParent(this);
  128. appointmentArrayUpToDate = false;
  129. super.addEntity((RefEntity)appointment);
  130. }
  131. public void removeAppointment(Appointment appointment) {
  132. checkWritable();
  133. if ( findAppointment( appointment ) == null)
  134. return;
  135. appointmentArrayUpToDate = false;
  136. super.removeEntity((RefEntity)appointment);
  137. clearRestrictions(appointment);
  138. if (this.equals(appointment.getReservation()))
  139. ((AppointmentImpl) appointment).setParent(null);
  140. }
  141. protected void clearRestrictions(Appointment appointment) {
  142. if (restrictions == null)
  143. return;
  144. ArrayList<Object> list = null;
  145. for (Object key:restrictions.keySet()) {
  146. Appointment[] appointments = (Appointment[]) restrictions.get(key);
  147. for ( int i = 0; i < appointments.length; i++) {
  148. if (list == null)
  149. list = new ArrayList<Object>();
  150. list.add(key);
  151. }
  152. }
  153. if (list == null)
  154. return;
  155. for (Object key: list) {
  156. Appointment[] appointments = (Appointment[]) restrictions.get(key);
  157. ArrayList<Appointment> newApps = new ArrayList<Appointment>();
  158. for ( int i=0; i< appointments.length; i++) {
  159. if ( !appointments[i].equals( appointment ) ) {
  160. newApps.add( appointments[i] );
  161. }
  162. }
  163. setRestrictionForId( key, newApps.toArray( Appointment.EMPTY_ARRAY) );
  164. }
  165. }
  166. public void addAllocatable(Allocatable allocatable) {
  167. checkWritable();
  168. if (getReferenceHandler().isRefering((RefEntity)allocatable))
  169. return;
  170. allocatableArrayUpToDate = false;
  171. getReferenceHandler().add((RefEntity)allocatable);
  172. }
  173. public void removeAllocatable(Allocatable allocatable) {
  174. checkWritable();
  175. if (!getReferenceHandler().isRefering((RefEntity)allocatable))
  176. return;
  177. getReferenceHandler().remove((RefEntity)allocatable);
  178. allocatableArrayUpToDate = false;
  179. }
  180. public Allocatable[] getAllocatables() {
  181. updateAllocatableArrays();
  182. return allocatables;
  183. }
  184. public Allocatable[] getResources() {
  185. updateAllocatableArrays();
  186. return resources;
  187. }
  188. public Allocatable[] getPersons() {
  189. updateAllocatableArrays();
  190. return persons;
  191. }
  192. private void updateAppointmentArray() {
  193. if (appointmentArrayUpToDate)
  194. return;
  195. Collection appointmentList = new ArrayList();
  196. Iterator it = super.getSubEntities();
  197. while (it.hasNext()) {
  198. RefEntity o = (RefEntity) it.next();
  199. if (o.getRaplaType().equals( Appointment.TYPE) ) {
  200. appointmentList.add(o);
  201. // System.out.println("Appointment " + o + " belongs to reservation " + this);
  202. }
  203. }
  204. appointments = (Appointment[]) appointmentList.toArray(Appointment.EMPTY_ARRAY);
  205. //notwendig?
  206. //Arrays.sort(appointments, new AppointmentStartComparator());
  207. }
  208. private void updateAllocatableArrays() {
  209. if (allocatableArrayUpToDate)
  210. return;
  211. Collection allocatableList = new ArrayList();
  212. Collection resourceList = new ArrayList();
  213. Collection personList = new ArrayList();
  214. Iterator it = super.getReferences();
  215. while (it.hasNext()) {
  216. RefEntity o = (RefEntity) it.next();
  217. if (o.getRaplaType().equals( Allocatable.TYPE)) {
  218. if (((Allocatable) o).isPerson()) {
  219. personList.add(o);
  220. } else {
  221. resourceList.add(o);
  222. }
  223. allocatableList.add(o);
  224. }
  225. }
  226. allocatables = (Allocatable[]) allocatableList.toArray(Allocatable.ALLOCATABLE_ARRAY);
  227. persons = (Allocatable[]) personList.toArray(Allocatable.ALLOCATABLE_ARRAY);
  228. resources = (Allocatable[]) resourceList.toArray(Allocatable.ALLOCATABLE_ARRAY);
  229. allocatableArrayUpToDate = true;
  230. }
  231. public boolean hasAllocated(Allocatable allocatable) {
  232. return getReferenceHandler().isRefering((RefEntity)allocatable);
  233. }
  234. public boolean hasAllocated(Allocatable allocatable,Appointment appointment) {
  235. if (!hasAllocated(allocatable))
  236. return false;
  237. Appointment[] restrictions = getRestriction(allocatable);
  238. for ( int i = 0; i < restrictions.length; i++) {
  239. if ( restrictions[i].equals( appointment ) )
  240. return true;
  241. }
  242. return restrictions.length == 0;
  243. }
  244. public void setRestriction(Allocatable allocatable,Appointment[] appointments) {
  245. Object id = ((RefEntity)allocatable).getId();
  246. Assert.notNull(id,"Allocatable object has no ID");
  247. setRestrictionForId(id,appointments);
  248. }
  249. public void setRestrictionForId(Object id,Appointment[] appointments) {
  250. if (restrictions == null)
  251. restrictions = new HashMap();
  252. if (appointments == null || appointments.length == 0)
  253. restrictions.remove(id);
  254. else
  255. restrictions.put(id, appointments);
  256. }
  257. public void addRestrictionForId(Object id,Appointment appointment) {
  258. if (restrictions == null)
  259. restrictions = new HashMap();
  260. Appointment[] appointmentsNew;
  261. Appointment[] appointments = (Appointment[])restrictions.get( id );
  262. if ( appointments != null)
  263. {
  264. appointmentsNew = new Appointment[appointments.length + 1];
  265. System.arraycopy( appointments, 0,appointmentsNew, 0, appointments.length );
  266. }
  267. else
  268. {
  269. appointmentsNew = new Appointment[1];
  270. }
  271. appointmentsNew[appointmentsNew.length -1] = appointment;
  272. restrictions.put(id, appointmentsNew);
  273. }
  274. public Appointment[] getRestriction(Allocatable allocatable) {
  275. Object id = ((RefEntity)allocatable).getId();
  276. Assert.notNull(id,"Allocatable object has no ID");
  277. if (restrictions != null) {
  278. Appointment[] restriction = (Appointment[]) restrictions.get(id);
  279. if (restriction != null)
  280. return restriction;
  281. }
  282. return Appointment.EMPTY_ARRAY;
  283. }
  284. public Appointment[] getAppointmentsFor(Allocatable allocatable) {
  285. Appointment[] restrictedAppointments = getRestriction( allocatable);
  286. if ( restrictedAppointments.length == 0)
  287. return getAppointments();
  288. else
  289. return restrictedAppointments;
  290. }
  291. public Allocatable[] getRestrictedAllocatables(Appointment appointment) {
  292. HashSet<Allocatable> set = new HashSet<Allocatable>();
  293. Allocatable[] allocatables = getAllocatables();
  294. for (int i=0;i<allocatables.length;i++) {
  295. Appointment[] restriction = getRestriction( allocatables[i] );
  296. for (int j = 0; j < restriction.length; j++ ) {
  297. if ( restriction[j].equals( appointment ) ) {
  298. set.add( allocatables[i] );
  299. }
  300. }
  301. }
  302. return set.toArray( Allocatable.ALLOCATABLE_ARRAY);
  303. }
  304. public Allocatable[] getAllocatablesFor(Appointment appointment) {
  305. HashSet<Allocatable> set = new HashSet<Allocatable>();
  306. Allocatable[] allocatables = getAllocatables();
  307. for (int i=0;i<allocatables.length;i++) {
  308. Appointment[] restriction = getRestriction( allocatables[i] );
  309. for (int j = 0; j < restriction.length; j++ ) {
  310. if ( restriction[j].equals( appointment ) ) {
  311. set.add( allocatables[i] );
  312. }
  313. }
  314. if ( restriction.length == 0)
  315. {
  316. set.add(allocatables[i]);
  317. }
  318. }
  319. return set.toArray( Allocatable.ALLOCATABLE_ARRAY);
  320. }
  321. public Appointment findAppointment(Appointment copy) {
  322. return (Appointment) super.findEntity((RefEntity)copy);
  323. }
  324. static private void copy(ReservationImpl source,ReservationImpl dest) {
  325. // First we must invalidate the arrays.
  326. dest.allocatableArrayUpToDate = false;
  327. dest.appointmentArrayUpToDate = false;
  328. dest.classification = (ClassificationImpl) source.classification.clone();
  329. dest.restrictions = null;
  330. Allocatable[] allocatables = dest.getAllocatables();
  331. for (int i=0;i<allocatables.length;i++) {
  332. RefEntity reference = (RefEntity) allocatables[i];
  333. if (reference instanceof Allocatable) {
  334. // We have to copy the restrictions
  335. Appointment[] sourceRestriction = source.getRestriction( allocatables[i] );
  336. Appointment[] destRestriction = new Appointment[ sourceRestriction.length ];
  337. for ( int j = 0; j < sourceRestriction.length; j ++) {
  338. destRestriction[j] = dest.findAppointment( sourceRestriction[j] );
  339. }
  340. dest.setRestriction( allocatables[i], destRestriction );
  341. }
  342. }
  343. Iterator it = dest.getSubEntities();
  344. while ( it.hasNext()) {
  345. ((AppointmentImpl)it.next()).setParent(dest);
  346. }
  347. dest.createDate = source.createDate;
  348. dest.lastChanged = source.lastChanged;
  349. dest.slotDate = source.slotDate;
  350. }
  351. public boolean needsChange(DynamicType type) {
  352. return classification.needsChange( type );
  353. }
  354. public void commitChange(DynamicType type) {
  355. classification.commitChange( type );
  356. }
  357. public void copy(Reservation obj) {
  358. super.copy((SimpleEntity<Reservation>)obj);
  359. copy((ReservationImpl)obj,this);
  360. }
  361. public Reservation clone() {
  362. ReservationImpl clone = new ReservationImpl();
  363. super.clone(clone);
  364. copy(this,clone);
  365. return clone;
  366. }
  367. public Reservation deepClone() {
  368. ReservationImpl clone = new ReservationImpl();
  369. super.deepClone(clone);
  370. copy(this,clone);
  371. return clone;
  372. }
  373. public Date getSelectedSlotDate() {
  374. // get the Date of the GUI selected slot
  375. return slotDate;
  376. }
  377. public void setSelectedSlotDate(Date d) {
  378. // set the Date of the GUI selected slot
  379. slotDate=d;
  380. return;
  381. }
  382. public void commitRemove(DynamicType type) throws CannotExistWithoutTypeException
  383. {
  384. classification.commitRemove(type);
  385. }
  386. }