001: /*
002: * Copyright 2006 Davide Deidda
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: /*
018: * EntityList.java
019: *
020: * Created on 15 October 2005, 15:56
021: *
022: * To change this template, choose Tools | Template Manager
023: * and open the template in the editor.
024: */
025:
026: package it.biobytes.ammentos.util;
027:
028: import it.biobytes.ammentos.Ammentos;
029: import it.biobytes.ammentos.PersistenceException;
030: import java.util.*;
031: import it.biobytes.ammentos.query.*;
032: import java.util.logging.Logger;
033:
034: /**
035: *
036: * @author davide
037: */
038: public class EntityList<T> extends ArrayList<T> implements
039: EntityCollection {
040: private boolean m_touched;
041: private boolean m_touchSensible;
042: private Query m_query;
043: private Logger m_logger = Logger.getLogger("ammentos");
044: private Class<T> m_class;
045: private List<T> m_snapshot;
046: private boolean m_saving;
047: private boolean m_deleteOnRemove;
048:
049: public EntityList(Class<T> c, Query query, boolean deleteOnRemove) {
050: m_class = c;
051: m_query = query;
052: m_touchSensible = true;
053: m_deleteOnRemove = deleteOnRemove;
054: }
055:
056: public EntityList(Class<T> c, Query qry, List lst,
057: boolean deleteOnRemove) {
058: this (c, qry, deleteOnRemove);
059: m_touchSensible = false;
060: if ((lst != null) && (lst.size() > 0)) {
061: super .addAll(lst);
062: m_touched = true;
063: }
064: m_touchSensible = true;
065: }
066:
067: @Override
068: public boolean equals(Object o) {
069: touch();
070: boolean retValue;
071:
072: retValue = super .equals(o);
073: return retValue;
074: }
075:
076: @Override
077: public boolean contains(Object elem) {
078: touch();
079: boolean retValue;
080:
081: retValue = super .contains(elem);
082: return retValue;
083: }
084:
085: @Override
086: public int indexOf(Object elem) {
087: touch();
088: int retValue;
089:
090: retValue = super .indexOf(elem);
091: return retValue;
092: }
093:
094: @Override
095: public int lastIndexOf(Object elem) {
096: touch();
097: int retValue;
098:
099: retValue = super .lastIndexOf(elem);
100: return retValue;
101: }
102:
103: @Override
104: public boolean remove(Object o) {
105: touch();
106: boolean retValue;
107:
108: retValue = super .remove(o);
109: return retValue;
110: }
111:
112: @Override
113: public boolean addAll(int index, Collection<? extends T> c) {
114: touch();
115: boolean retValue;
116:
117: retValue = super .addAll(index, c);
118: return retValue;
119: }
120:
121: @Override
122: public boolean containsAll(Collection<?> c) {
123: touch();
124: boolean retValue;
125:
126: retValue = super .containsAll(c);
127: return retValue;
128: }
129:
130: @Override
131: public boolean addAll(Collection<? extends T> c) {
132: touch();
133: boolean retValue;
134:
135: retValue = super .addAll(c);
136: return retValue;
137: }
138:
139: @Override
140: public boolean removeAll(Collection<?> c) {
141: touch();
142: boolean retValue;
143:
144: retValue = super .removeAll(c);
145: return retValue;
146: }
147:
148: @Override
149: public boolean retainAll(Collection<?> c) {
150: touch();
151: boolean retValue;
152:
153: retValue = super .retainAll(c);
154: return retValue;
155: }
156:
157: @Override
158: public T get(int index) {
159: touch();
160: return super .get(index);
161: }
162:
163: @Override
164: public void ensureCapacity(int minCapacity) {
165: touch();
166: super .ensureCapacity(minCapacity);
167: }
168:
169: @Override
170: public ListIterator<T> listIterator(int index) {
171: touch();
172: ListIterator retValue;
173:
174: retValue = super .listIterator(index);
175: return retValue;
176: }
177:
178: @Override
179: public T remove(int index) {
180: touch();
181: return super .remove(index);
182: }
183:
184: @Override
185: public <T> T[] toArray(T[] a) {
186: touch();
187: return (T[]) super .toArray(a);
188: }
189:
190: @Override
191: public void add(int index, T element) {
192: touch();
193: super .add(index, element);
194: }
195:
196: @Override
197: public T set(int index, T element) {
198: touch();
199: return super .set(index, element);
200: }
201:
202: @Override
203: public void trimToSize() {
204: touch();
205: super .trimToSize();
206: }
207:
208: @Override
209: public String toString() {
210: touch();
211: String retValue;
212:
213: retValue = super .toString();
214: return retValue;
215: }
216:
217: @Override
218: public Object[] toArray() {
219: touch();
220: Object[] retValue;
221:
222: retValue = super .toArray();
223: return retValue;
224: }
225:
226: @Override
227: public List<T> subList(int fromIndex, int toIndex) {
228: touch();
229: List retValue;
230:
231: retValue = super .subList(fromIndex, toIndex);
232: return retValue;
233: }
234:
235: @Override
236: public int size() {
237: touch();
238: int retValue;
239:
240: retValue = super .size();
241: return retValue;
242: }
243:
244: @Override
245: public int hashCode() {
246: touch();
247: int retValue;
248:
249: retValue = super .hashCode();
250: return retValue;
251: }
252:
253: @Override
254: public Object clone() {
255: touch();
256: Object retValue;
257: retValue = super .clone();
258: return retValue;
259: }
260:
261: @Override
262: public void clear() {
263: touch();
264: super .clear();
265: }
266:
267: @Override
268: public boolean isEmpty() {
269: touch();
270: boolean retValue;
271:
272: retValue = super .isEmpty();
273: return retValue;
274: }
275:
276: @Override
277: public Iterator<T> iterator() {
278: touch();
279: Iterator retValue;
280:
281: retValue = super .iterator();
282: return retValue;
283: }
284:
285: @Override
286: public ListIterator<T> listIterator() {
287: touch();
288: ListIterator retValue;
289:
290: retValue = super .listIterator();
291: return retValue;
292: }
293:
294: @Override
295: protected void removeRange(int fromIndex, int toIndex) {
296: touch();
297: super .removeRange(fromIndex, toIndex);
298: }
299:
300: @Override
301: public boolean add(T o) {
302: touch();
303: return super .add(o);
304: }
305:
306: private synchronized void touch() {
307: m_logger.info("touch called. m_touched: " + m_touched);
308: if (!m_touchSensible)
309: return;
310: if (!m_touched) {
311: load();
312: m_touched = true;
313: }
314: }
315:
316: private synchronized void load() {
317: m_logger.info("load called");
318: try {
319: // Loads objects without beeing touched
320: m_touchSensible = false;
321: m_logger.info("query: " + m_query.getSql());
322: List<T> objs = Ammentos.load(m_class, m_query);
323: m_logger.info("objects loaded: " + objs.size());
324: super .addAll(objs);
325: takeSnapshot();
326: m_touchSensible = true;
327: } catch (PersistenceException e) {
328: m_logger.severe("Error loading query");
329: }
330: }
331:
332: private synchronized void takeSnapshot() {
333: m_touchSensible = false;
334: m_snapshot = new ArrayList<T>(this );
335: m_touchSensible = true;
336: }
337:
338: public synchronized void save() throws PersistenceException {
339: if ((!m_saving) && m_touched) {
340: m_saving = true;
341: try {
342: // Manages removed elements
343: m_logger.info("deleteOnRemove: " + m_deleteOnRemove);
344: m_logger.info("snapshot: " + m_snapshot);
345:
346: if (m_snapshot != null) {
347: // Removes from snapshot all present elements
348: m_snapshot.removeAll(this );
349: m_logger.info("snapshot after removeAll: "
350: + m_snapshot);
351:
352: if (m_deleteOnRemove) {
353: for (T obj : m_snapshot) {
354: Ammentos.delete(obj);
355: }
356: } else {
357: for (T obj : m_snapshot) {
358: Ammentos.save(obj);
359: }
360: }
361: }
362:
363: m_touchSensible = false;
364: for (T obj : this ) {
365: m_logger.info("saving: "
366: + System.identityHashCode(obj));
367: Ammentos.save(obj);
368: m_logger.info("saved: "
369: + System.identityHashCode(obj));
370: }
371: m_touchSensible = true;
372: } finally {
373: takeSnapshot();
374: m_saving = false;
375: }
376: }
377: }
378:
379: public synchronized void delete() throws PersistenceException {
380: for (T obj : this) {
381: Ammentos.delete(obj);
382: }
383: }
384:
385: }
|