KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > javacore > jmiimpl > javamodel > ReferenceColWrapper


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.javacore.jmiimpl.javamodel;
20
21 import java.lang.reflect.Array JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.ConcurrentModificationException JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import javax.jmi.reflect.RefObject;
27
28 import org.netbeans.api.mdr.events.AssociationEvent;
29 import org.netbeans.mdr.handlers.AssociationHandler;
30 import org.netbeans.mdr.storagemodel.MdrStorage;
31 import org.netbeans.mdr.util.EventNotifier;
32
33 /** This collection wrapper is intended to assotiations persistent outside of MDR
34  * repository, in this case in inner collection. So this wrapper simulates MDR event
35  * system and asks MDR for lock/unlock support.
36  * Wrapper can also verify check type for add/remove operations.
37  *
38  * @author Vladimir Hudec
39  */

40 public class ReferenceColWrapper implements Collection JavaDoc {
41     protected final MdrStorage storage;
42     protected final AssociationHandler source;
43     protected final EventNotifier.Association notifier;
44     protected final RefObject fixed;
45     protected final String JavaDoc endName;
46
47     private Collection JavaDoc inner;
48     private int modCount = 0;
49     
50     protected final MetadataElement parent;
51     protected final int changeMask;
52     
53     private TypeVerifier typeVerifier;
54
55     
56     /***********************************************************************************/
57     
58     /** Creates new CollectionWrapper */
59     public ReferenceColWrapper(MdrStorage storage, AssociationHandler source, RefObject fixed, String JavaDoc endName, MetadataElement parent, int changeMask, Collection JavaDoc inner) {
60         this(storage, source, fixed, endName, parent, changeMask);
61         setInnerList(inner);
62     }
63     
64     protected ReferenceColWrapper(MdrStorage storage, AssociationHandler source, RefObject fixed, String JavaDoc endName, MetadataElement parent, int changeMask) {
65         this.storage = storage;
66         this.source = source;
67         this.notifier = storage == null ? null : storage.getEventNotifier().ASSOCIATION;
68         this.fixed = fixed;
69         this.endName = endName;
70         this.parent = parent;
71         this.changeMask = changeMask;
72     }
73
74     public void setInnerList(Collection JavaDoc inner) {
75         modCount++;
76         this.inner = inner;
77         if (inner instanceof TypeVerifier) {
78             typeVerifier = (TypeVerifier) inner;
79         }
80     }
81     
82     public Collection JavaDoc getInnerCollection() {
83         return inner;
84     }
85     
86     protected int getModCount() {
87         return modCount;
88     }
89
90     protected void objectChanged(Object JavaDoc obj) {
91         if (parent == null) {
92             if (obj instanceof MetadataElement) {
93                 ((MetadataElement) obj).objectChanged(changeMask);
94             }
95         } else {
96             parent.objectChanged(changeMask);
97         }
98     }
99     
100     public void setTypeVerifier(TypeVerifier newTypeVerifier) {
101         this.typeVerifier = newTypeVerifier;
102     }
103
104     /** lock/unlock support */
105     protected void lock(boolean writeAccess) {
106         storage.getRepository().beginTrans(writeAccess);
107     }
108     
109     protected void unlock() {
110         storage.getRepository().endTrans();
111     }
112     
113     protected void unlock(boolean fail) {
114         storage.getRepository().endTrans(fail);
115     }
116     
117     protected void checkType(Object JavaDoc obj) throws javax.jmi.reflect.TypeMismatchException {
118         if (typeVerifier != null)
119             typeVerifier.checkType(obj);
120     }
121
122     protected void checkWrite() {
123         if (source == null) {
124             throw new UnsupportedOperationException JavaDoc();
125         }
126     }
127
128     /** Collection read operations */
129     
130     public boolean contains(Object JavaDoc obj) {
131         lock(false);
132         try {
133             return inner.contains(obj);
134         } finally {
135             unlock();
136         }
137     }
138     
139     public Iterator JavaDoc iterator() {
140         lock(false);
141         try {
142             return new ReferenceIteratorWrapper(inner.iterator());
143         } finally {
144             unlock();
145         }
146     }
147     
148     public int size() {
149         lock(false);
150         try {
151             return inner.size();
152         } finally {
153             unlock();
154         }
155     }
156     
157     public boolean isEmpty() {
158         lock(false);
159         try {
160             return inner.isEmpty();
161         } finally {
162             unlock();
163         }
164     }
165     
166     public boolean containsAll(Collection JavaDoc collection) {
167         lock(false);
168         try {
169             return inner.containsAll(collection);
170         } finally {
171             unlock();
172         }
173     }
174     
175     public Object JavaDoc[] toArray(Object JavaDoc[] obj) {
176         lock(false);
177         try {
178 // System.out.println("toArray: obj="+obj+", obj.length="+obj.length+", inner="+inner+", inner.size="+inner.size());
179
// if (obj.length>0&&obj[0]!=null)
180
// System.out.println("toArray: obj[0].getClass="+obj[0].getClass());
181
Object JavaDoc[] value = inner.toArray();
182 // if (value.length>0)
183
// System.out.println("toArray: value[0].getClass="+value[0].getClass());
184
Object JavaDoc[] result = obj;
185             if (value.length > result.length) {
186                 result = (Object JavaDoc[]) Array.newInstance(obj.getClass().getComponentType(), value.length);
187             } else if (value.length < result.length) {
188                 result[value.length] = null;
189             }
190             System.arraycopy(value, 0, result, 0, value.length);
191             return result;
192         } finally {
193             unlock();
194         }
195     }
196     
197     public Object JavaDoc[] toArray() {
198         return toArray(new Object JavaDoc[size()]);
199     }
200     
201     public boolean equals(Object JavaDoc object) {
202         if (object == this) return true;
203         if (!(object instanceof Collection JavaDoc)) return false;
204         lock(false);
205         try {
206             Iterator JavaDoc it1 = iterator();
207             Iterator JavaDoc it2 = ((Collection JavaDoc) object).iterator();
208             while(it1.hasNext() && it2.hasNext()) {
209                 Object JavaDoc o1 = it1.next();
210                 Object JavaDoc o2 = it2.next();
211                 if (!(o1==null ? o2==null : o1.equals(o2)))
212                     return false;
213             }
214             return !(it1.hasNext() || it2.hasNext());
215         } finally {
216             unlock();
217         }
218     }
219     
220     public int hashCode() {
221         lock(false);
222         try {
223             int hashCode = 1;
224             for (Iterator JavaDoc it = iterator(); it.hasNext();) {
225                 Object JavaDoc obj = it.next();
226                 hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
227             }
228             return hashCode;
229         } finally {
230             unlock();
231         }
232     }
233
234     /** Collection add/remove operations */
235     
236     public void clear() {
237         checkWrite();
238         boolean fail = true;
239         lock(true);
240         try {
241             Object JavaDoc elements[] = inner.toArray();
242             for (int i = 0; i < elements.length; i++) {
243                 remove(elements[i]);
244             }
245             fail = false;
246         } finally {
247             unlock(fail);
248         }
249     }
250     
251     public boolean addAll(Collection JavaDoc collection) {
252         checkWrite();
253         boolean fail = true;
254         lock(true);
255         try {
256             boolean result = false;
257             for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
258                 result |= add(it.next());
259             }
260             fail = false;
261             return result;
262         } finally {
263             unlock(fail);
264         }
265     }
266     
267     public boolean retainAll(Collection JavaDoc collection) {
268         checkWrite();
269         boolean fail = true;
270         lock(true);
271         try {
272             boolean result = false;
273             Object JavaDoc elements[] = inner.toArray();
274             for (int i = 0; i < elements.length; i++) {
275                 Object JavaDoc o = elements[i];
276                 if (!collection.contains(o)) {
277                     remove(o);
278                     result = true;
279                 }
280             }
281             fail = false;
282             return result;
283         } finally {
284             unlock(fail);
285         }
286     }
287     
288     public boolean removeAll(Collection JavaDoc collection) {
289         checkWrite();
290         boolean fail = true;
291         lock(true);
292         try {
293             boolean result = false;
294             for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
295                 result |= remove(it.next());
296             }
297             fail = false;
298             return result;
299         } finally {
300             unlock(fail);
301         }
302     }
303     
304     public boolean remove(Object JavaDoc obj) {
305         checkWrite();
306         checkType(obj);
307         boolean fail = true;
308         lock(true);
309         try {
310             if (storage.eventsEnabled()) {
311                 AssociationEvent event = new AssociationEvent(
312                 source,
313                 AssociationEvent.EVENT_ASSOCIATION_REMOVE,
314                 fixed,
315                 endName,
316                 (RefObject) obj,
317                 null,
318                 AssociationEvent.POSITION_NONE);
319                 notifier.firePlannedChange(source, event);
320             }
321             boolean result = inner.remove(obj);
322             objectChanged(obj);
323             fail = false;
324             return result;
325         } finally {
326             unlock(fail);
327         }
328     }
329     
330     public boolean add(Object JavaDoc obj) {
331         checkWrite();
332         checkType(obj);
333         boolean fail = true;
334         lock(true);
335         try {
336             if (storage.eventsEnabled()) {
337                 AssociationEvent event = new AssociationEvent(
338                 source,
339                 AssociationEvent.EVENT_ASSOCIATION_ADD,
340                 fixed,
341                 endName,
342                 null,
343                 (RefObject) obj,
344                 AssociationEvent.POSITION_NONE);
345                 notifier.firePlannedChange(source, event);
346             }
347             boolean result = inner.add(obj);
348             objectChanged(obj);
349             fail = false;
350             return result;
351         } finally {
352             unlock(fail);
353         }
354     }
355     
356     /** Iterator implementation */
357     
358     protected class ReferenceIteratorWrapper implements Iterator JavaDoc {
359         protected Iterator JavaDoc innerIterator;
360         protected Object JavaDoc lastRead = null;
361         protected final int modCount;
362         
363         public ReferenceIteratorWrapper(Iterator JavaDoc innerIterator) {
364             this.innerIterator = innerIterator;
365             this.modCount = getParentModCount();
366         }
367         
368         protected int getParentModCount() {
369             return ReferenceColWrapper.this.getModCount();
370         }
371         
372         protected void testModCount() throws ConcurrentModificationException JavaDoc {
373             if (modCount != getParentModCount())
374                 throw new ConcurrentModificationException JavaDoc();
375         }
376         
377         public boolean hasNext() {
378             testModCount();
379             lock(false);
380             try {
381                 return innerIterator.hasNext();
382             } finally {
383                 unlock();
384             }
385         }
386         
387         public Object JavaDoc next() {
388             testModCount();
389             lock(false);
390             try {
391                 return (lastRead = innerIterator.next());
392             } finally {
393                 unlock();
394             }
395         }
396
397         public void remove() {
398             checkWrite();
399             testModCount();
400             //checkType(lastRead);
401
boolean fail = true;
402             lock(true);
403             try {
404                 if (storage.eventsEnabled()) {
405                     AssociationEvent event = new AssociationEvent(
406                     source,
407                     AssociationEvent.EVENT_ASSOCIATION_REMOVE,
408                     fixed,
409                     endName,
410                     (RefObject) lastRead,
411                     null,
412                     AssociationEvent.POSITION_NONE);
413                     notifier.firePlannedChange(source, event);
414                 }
415                 innerIterator.remove();
416                 objectChanged(lastRead);
417                 fail = false;
418             } finally {
419                 unlock(fail);
420             }
421         }
422     }
423 }
424
Popular Tags