PageRenderTime 27ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/version_1_2/Rapla/src/org/rapla/storage/LocalCache.java

http://rapla.googlecode.com/
Java | 420 lines | 332 code | 59 blank | 29 comment | 72 complexity | 7bb2b95e35bcc25e2069946d243ca9d6 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, which license fulfills the Open Source |
  11. | Definition as published by the Open Source Initiative (OSI). |
  12. *--------------------------------------------------------------------------*/
  13. package org.rapla.storage;
  14. import java.text.ParseException;
  15. import java.util.ArrayList;
  16. import java.util.Collection;
  17. import java.util.Comparator;
  18. import java.util.Date;
  19. import java.util.HashMap;
  20. import java.util.HashSet;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.Locale;
  24. import java.util.Map;
  25. import java.util.Set;
  26. import java.util.SortedSet;
  27. import java.util.TreeSet;
  28. import org.rapla.components.util.Assert;
  29. import org.rapla.components.util.iterator.NestedIterator;
  30. import org.rapla.entities.Category;
  31. import org.rapla.entities.EntityNotFoundException;
  32. import org.rapla.entities.RaplaType;
  33. import org.rapla.entities.User;
  34. import org.rapla.entities.configuration.Preferences;
  35. import org.rapla.entities.domain.Allocatable;
  36. import org.rapla.entities.domain.Appointment;
  37. import org.rapla.entities.domain.AppointmentStartComparator;
  38. import org.rapla.entities.domain.Period;
  39. import org.rapla.entities.domain.Reservation;
  40. import org.rapla.entities.dynamictype.Attribute;
  41. import org.rapla.entities.dynamictype.DynamicType;
  42. import org.rapla.entities.internal.CategoryImpl;
  43. import org.rapla.entities.storage.EntityResolver;
  44. import org.rapla.entities.storage.RefEntity;
  45. import org.rapla.entities.storage.internal.SimpleIdentifier;
  46. import org.rapla.framework.RaplaException;
  47. public class LocalCache implements EntityResolver
  48. {
  49. Map passwords = new HashMap();
  50. Map entities;
  51. Set dynamicTypes;
  52. Set users;
  53. Set resources;
  54. Set reservations;
  55. Set periods;
  56. Set categories;
  57. Set appointments;
  58. Set attributes;
  59. Set preferences;
  60. Map entityMap;
  61. Map enities;
  62. Locale locale;
  63. // Index for start and end dates
  64. TreeSet appointmentsStart;
  65. class IdComparator implements Comparator {
  66. public int compare(Object o1,Object o2) {
  67. SimpleIdentifier id1 = (SimpleIdentifier)((RefEntity)o1).getId();
  68. SimpleIdentifier id2 = (SimpleIdentifier)((RefEntity)o2).getId();
  69. if ( id1.getKey() == id2.getKey())
  70. return 0;
  71. return (id1.getKey() < id2.getKey()) ? -1 : 1;
  72. }
  73. }
  74. private CategoryImpl superCategory = new CategoryImpl();
  75. public LocalCache(Locale locale) {
  76. this.locale = locale;
  77. superCategory.setId(LocalCache.SUPER_CATEGORY_ID);
  78. superCategory.setKey("supercategory");
  79. entityMap = new HashMap();
  80. entities = new HashMap();
  81. // top-level-entities
  82. reservations = new TreeSet( new IdComparator());
  83. periods = new TreeSet(new IdComparator());
  84. users = new TreeSet( new IdComparator());
  85. resources = new TreeSet( new IdComparator());
  86. dynamicTypes = new TreeSet(new IdComparator());
  87. // non-top-level-entities with exception of one super-category
  88. categories = new HashSet();
  89. appointments = new HashSet();
  90. preferences = new HashSet();
  91. attributes = new HashSet();
  92. entityMap.put(DynamicType.TYPE,dynamicTypes);
  93. entityMap.put(Attribute.TYPE, attributes);
  94. entityMap.put(Category.TYPE, categories);
  95. entityMap.put(Allocatable.TYPE,resources);
  96. entityMap.put(User.TYPE,users);
  97. entityMap.put(Period.TYPE,periods);
  98. entityMap.put(Reservation.TYPE,reservations);
  99. entityMap.put(Appointment.TYPE,appointments);
  100. entityMap.put(Preferences.TYPE, preferences);
  101. appointmentsStart = new TreeSet(new AppointmentStartComparator());
  102. initSuperCategory();
  103. }
  104. /** @return true if the entity has been removed and false if the entity was not found*/
  105. public boolean remove(RefEntity entity) {
  106. RaplaType raplaType = entity.getRaplaType();
  107. Set entitySet = (Set)entityMap.get(raplaType);
  108. boolean bResult = true;
  109. if (entitySet != null) {
  110. if (entities.get(entity.getId()) != null)
  111. bResult = false;
  112. if (entity.getId() == null)
  113. return false;
  114. if ( Appointment.TYPE.equals( raplaType )) {
  115. removeAppointment(entity);
  116. }
  117. entities.remove(entity.getId());
  118. entitySet.remove( entity );
  119. } else {
  120. throw new RuntimeException("UNKNOWN TYPE. Can't remove object:" + entity.getRaplaType());
  121. }
  122. return bResult;
  123. }
  124. public void put(RefEntity entity) {
  125. Assert.notNull(entity);
  126. RaplaType raplaType = entity.getRaplaType();
  127. Object id = entity.getId();
  128. if (id == null)
  129. throw new IllegalStateException("ID can't be null");
  130. Set entitySet = (Set) entityMap.get(raplaType);
  131. if (entitySet != null) {
  132. if (Appointment.TYPE.equals( raplaType )) {
  133. removeAppointment(entity);
  134. appointmentsStart.add(entity);
  135. }
  136. entities.put(id,entity);
  137. entitySet.remove( entity );
  138. entitySet.add( entity );
  139. } else {
  140. throw new RuntimeException("UNKNOWN TYPE. Can't store object in cache: " + entity.getRaplaType());
  141. }
  142. }
  143. public RefEntity get(Object id) {
  144. if (id == null)
  145. throw new RuntimeException("id is null");
  146. return (RefEntity)entities.get(id);
  147. }
  148. private void removeAppointment(RefEntity entity) {
  149. if (appointments.remove(entity)) {
  150. // start date could have been changed, so we probably won't find it with a binary search
  151. if (!appointmentsStart.remove(entity)) {
  152. Iterator it = appointmentsStart.iterator();
  153. while (it.hasNext())
  154. if (entity.equals(it.next())) {
  155. it.remove();
  156. break;
  157. }
  158. }
  159. }
  160. }
  161. public SortedSet getAppointments(User user,Date start,Date end) {
  162. SortedSet appointmentSet = new TreeSet(new AppointmentStartComparator());
  163. Iterator it;
  164. if (end != null) {
  165. // all appointments that start before the enddate
  166. it = appointmentsStart.headSet(end).iterator();
  167. //it = appointments.values().iterator();
  168. } else {
  169. it = appointmentsStart.iterator();
  170. }
  171. while (it.hasNext()) {
  172. Appointment appointment = (Appointment) it.next();
  173. // test if appointment end before the start-date
  174. if (end != null && appointment.getStart().after(end))
  175. break;
  176. // Ignore appointments without a reservation
  177. if ( appointment.getReservation() == null)
  178. continue;
  179. if ( !appointment.overlaps(start,end, false))
  180. continue;
  181. if (user == null || user.equals(appointment.getOwner()) ) {
  182. appointmentSet.add(appointment);
  183. }
  184. }
  185. return appointmentSet;
  186. }
  187. public List getReservations(User user, Date start, Date end) {
  188. HashSet reservationSet = new HashSet();
  189. Iterator it = getAppointments(user,start,end).iterator();
  190. while (it.hasNext()) {
  191. Appointment appointment = (Appointment) it.next();
  192. reservationSet.add( appointment.getReservation() );
  193. }
  194. return new ArrayList(reservationSet);
  195. }
  196. public Collection getCollection(RaplaType type) {
  197. Set entities = (Set) entityMap.get(type);
  198. if ( Period.TYPE.equals( type)) {
  199. entities = new TreeSet( entities);
  200. }
  201. if (entities != null) {
  202. return entities;
  203. } else {
  204. throw new RuntimeException("UNKNOWN TYPE. Can't get collection: "
  205. + type);
  206. }
  207. }
  208. public Iterator getIterator(RaplaType type) throws RaplaException {
  209. Set entities = (Set) entityMap.get(type);
  210. if (entities != null) {
  211. return entities.iterator();
  212. }
  213. throw new RaplaException("Can't get iterator for " + type);
  214. }
  215. public void clearAll() {
  216. passwords.clear();
  217. Iterator it = entityMap.values().iterator();
  218. while (it.hasNext()) {
  219. ((Set)it.next()).clear();
  220. }
  221. appointmentsStart.clear();
  222. entities.clear();
  223. initSuperCategory();
  224. }
  225. private void initSuperCategory() {
  226. entities.put (LocalCache.SUPER_CATEGORY_ID, superCategory);
  227. superCategory.setReadOnly( false );
  228. categories.add( superCategory );
  229. Category[] childs = superCategory.getCategories();
  230. for (int i=0;i<childs.length;i++) {
  231. superCategory.removeCategory( childs[i] );
  232. }
  233. }
  234. public static Object SUPER_CATEGORY_ID = new SimpleIdentifier(Category.TYPE,0);
  235. public CategoryImpl getSuperCategory() {
  236. return (CategoryImpl) get(SUPER_CATEGORY_ID);
  237. }
  238. public Collection getAttributeList(Category category) {
  239. HashSet result = new HashSet();
  240. Iterator it = attributes.iterator();
  241. while (it.hasNext()) {
  242. Attribute attribute = (Attribute) it.next();
  243. if (((RefEntity)attribute).isRefering((RefEntity)category))
  244. result.add(attribute);
  245. }
  246. return result;
  247. }
  248. public Collection getDynamicTypeList(Category category) {
  249. HashSet result = new HashSet();
  250. Iterator it = getAttributeList(category).iterator();
  251. while (it.hasNext()) {
  252. result.add(((Attribute)it.next()).getDynamicType());
  253. }
  254. return result;
  255. }
  256. public Collection getReferers(RaplaType raplaType,RefEntity object) {
  257. ArrayList result = new ArrayList();
  258. Iterator it = getCollection(raplaType).iterator();
  259. while (it.hasNext())
  260. {
  261. RefEntity referer = (RefEntity)it.next();
  262. if (referer != null && referer.isRefering(object)) {
  263. result.add(referer);
  264. }
  265. }
  266. return result;
  267. }
  268. public User getUser(String username) {
  269. Iterator it = users.iterator();
  270. while (it.hasNext()) {
  271. User user = (User) it.next();
  272. if (user.getUsername().equals(username))
  273. return user;
  274. }
  275. return null;
  276. }
  277. public Preferences getPreferences(User user) {
  278. Iterator it = preferences.iterator();
  279. while (it.hasNext()) {
  280. Preferences pref = (Preferences) it.next();
  281. if ( user == null && pref.getOwner() == null ) {
  282. return pref;
  283. }
  284. if (user!= null && pref.getOwner() != null && user.equals(pref.getOwner())) {
  285. return pref;
  286. }
  287. }
  288. return null;
  289. }
  290. static public Object getId(RaplaType type,String str) throws ParseException {
  291. if (str == null)
  292. throw new ParseException("Id string for " + type + " can't be null", 0);
  293. int index = str.lastIndexOf("_") + 1;
  294. if (index>str.length())
  295. throw new ParseException("invalid rapla-id '" + str + "'", index);
  296. try {
  297. return new SimpleIdentifier(type,Integer.parseInt(str.substring(index)));
  298. } catch (NumberFormatException ex) {
  299. throw new ParseException("invalid rapla-id '" + str + "'", index);
  300. }
  301. }
  302. public DynamicType getDynamicType(String elementKey) {
  303. Iterator it = dynamicTypes.iterator();
  304. while (it.hasNext()) {
  305. DynamicType dt = (DynamicType) it.next();
  306. if (dt.getElementKey().equals(elementKey))
  307. return dt;
  308. }
  309. return null;
  310. }
  311. public Iterator getVisibleEntities() {
  312. return new NestedIterator(entityMap.keySet().iterator()) {
  313. public Iterator getNestedIterator(Object key) {
  314. RaplaType raplaType = (RaplaType)key;
  315. if ( Reservation.TYPE.equals( raplaType ) ||
  316. Appointment.TYPE.equals( raplaType ) )
  317. return null;
  318. Set set = (Set) entityMap.get( key);
  319. return set.iterator();
  320. }
  321. };
  322. }
  323. public Iterator getAllEntities() {
  324. return new NestedIterator(entityMap.keySet().iterator()) {
  325. public Iterator getNestedIterator(Object raplaType) {
  326. Set set = (Set) entityMap.get(raplaType);
  327. return set.iterator();
  328. }
  329. /*
  330. public Object next() {
  331. Object obj = super.next();
  332. System.out.println(obj);
  333. return obj;
  334. }
  335. */
  336. };
  337. }
  338. // Implementation of EntityResolver
  339. public RefEntity resolve(Object id) throws EntityNotFoundException {
  340. if (!(id instanceof SimpleIdentifier))
  341. new EntityNotFoundException("Unknown identifier class: " + id.getClass()
  342. + ". Only the SimpleIdentier class is supported.");
  343. RefEntity entity = (RefEntity) get(id);
  344. if (entity == null)
  345. throw new EntityNotFoundException("Object for id [" + id.toString() + "] not found");
  346. return entity;
  347. }
  348. public String getPassword(Object userId) {
  349. return (String) passwords.get(userId);
  350. }
  351. public void putPassword(Object userId, String password) {
  352. passwords.put(userId,password);
  353. }
  354. public void putAll( Collection list )
  355. {
  356. Iterator it = list.iterator();
  357. while (it.hasNext()) {
  358. put((RefEntity)it.next());
  359. }
  360. }
  361. }