001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013: package org.rapla.facade.internal;
014:
015: import java.util.Collections;
016: import java.util.HashMap;
017: import java.util.HashSet;
018: import java.util.Iterator;
019: import java.util.Map;
020: import java.util.Set;
021:
022: import org.rapla.components.util.Tools;
023: import org.rapla.entities.RaplaObject;
024: import org.rapla.entities.RaplaType;
025: import org.rapla.facade.ModificationEvent;
026:
027: /** Encapsulate the changes that are made in the backend-store.*/
028: public class ModificationEventImpl implements ModificationEvent {
029: Set updatedObjects;
030: Set removedObjects;
031: boolean isRefresh = false;
032: Map updatedIndex;
033: Map removedIndex;
034:
035: public ModificationEventImpl() {
036: isRefresh = true;
037: }
038:
039: public ModificationEventImpl(Set changedObjects, Set removedObjects) {
040: isRefresh = false;
041: this .updatedObjects = Collections
042: .unmodifiableSet(changedObjects);
043: this .removedObjects = Collections
044: .unmodifiableSet(removedObjects);
045: updatedIndex = new HashMap();
046: Iterator it = updatedObjects.iterator();
047: while (it.hasNext()) {
048: addToIndex(updatedIndex, (RaplaObject) it.next());
049: }
050: makeIndexReadOnly(updatedIndex);
051: removedIndex = new HashMap();
052: it = removedObjects.iterator();
053: while (it.hasNext()) {
054: addToIndex(removedIndex, (RaplaObject) it.next());
055: }
056: makeIndexReadOnly(removedIndex);
057: }
058:
059: private void addToIndex(Map index, RaplaObject type) {
060: Set set = (Set) index.get(type.getRaplaType());
061: if (set == null) {
062: set = new HashSet();
063: index.put(type.getRaplaType(), set);
064: }
065: set.add(type);
066: }
067:
068: private void makeIndexReadOnly(Map index) {
069: Iterator it = index.keySet().iterator();
070: while (it.hasNext()) {
071: Object key = it.next();
072: Set set = Collections.unmodifiableSet((Set) index.get(key));
073: index.put(key, set);
074: }
075: }
076:
077: /** All objects in the cache are modified. This is not selective. */
078: private boolean isRefresh() {
079: return isRefresh;
080: }
081:
082: private Set retainObjects(Set set, Set col) {
083: HashSet tempSet = new HashSet(col.size());
084: tempSet.addAll(col);
085: tempSet.retainAll(set);
086: if (tempSet.size() > 0)
087: return tempSet;
088: else
089: return Tools.EMPTY_SET;
090: }
091:
092: /** returns the modified objects from a given set.*/
093: public Set getChanged(Set col) {
094: checkNotRefresh();
095: return retainObjects(updatedObjects, col);
096: }
097:
098: /** returns the removed objects from a given set.*/
099: public Set getRemoved(Set col) {
100: checkNotRefresh();
101: return retainObjects(removedObjects, col);
102: }
103:
104: /** returns if the objects has changed.*/
105: public boolean hasChanged(Object object) {
106: if (isRefresh()) {
107: return true;
108: }
109: checkNotRefresh();
110: return updatedObjects.contains(object);
111: }
112:
113: /** returns if the objects was removed.*/
114: public boolean isRemoved(Object object) {
115: if (isRefresh()) {
116: return true;
117: }
118: checkNotRefresh();
119: return removedObjects.contains(object);
120: }
121:
122: /** returns if the objects has changed or was removed.*/
123: public boolean isModified(Object object) {
124: if (isRefresh()) {
125: return true;
126: }
127: checkNotRefresh();
128: return hasChanged(object) || isRemoved(object);
129: }
130:
131: /** returns if an objects of the specied type was changed or removed.*/
132: public boolean isModified(RaplaType raplaType) {
133: if (isRefresh()) {
134: return true;
135: }
136: checkNotRefresh();
137: return updatedIndex.get(raplaType) != null
138: || removedIndex.get(raplaType) != null;
139: }
140:
141: private Set getFromIndex(Map index, RaplaType raplaType) {
142: Set set = (Set) index.get(raplaType);
143: if (set != null)
144: return set;
145: else
146: return Tools.EMPTY_SET;
147: }
148:
149: /** returns if an objects of the specied type has changed .*/
150: public Set getChanged(RaplaType raplaType) {
151: checkNotRefresh();
152: return getFromIndex(updatedIndex, raplaType);
153: }
154:
155: /** returns if an objects of the specied type was removed .*/
156: public Set getRemoved(RaplaType raplaType) {
157: checkNotRefresh();
158: return getFromIndex(removedIndex, raplaType);
159: }
160:
161: /** returns all removed objects .*/
162: public Set getRemoved() {
163: checkNotRefresh();
164: return removedObjects;
165: }
166:
167: /** returns all changed object .*/
168: public Set getChanged() {
169: checkNotRefresh();
170: return updatedObjects;
171: }
172:
173: private void checkNotRefresh() {
174: if (isRefresh())
175: throw new IllegalStateException(
176: "Refresh is set. All objects could be changed!");
177: }
178: }
|