KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > query > lib > SpeedoExtent


1 /**
2  * Speedo: an implementation of JDO compliant personality on top of JORM generic
3  * I/O sub-system.
4  * Copyright (C) 2001-2004 France Telecom R&D
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *
21  *
22  * Contact: speedo@objectweb.org
23  *
24  * Authors: S.Chassande-Barrioz.
25  *
26  */

27
28 package org.objectweb.speedo.query.lib;
29
30 import org.objectweb.jorm.api.PClassMapping;
31 import org.objectweb.jorm.api.PException;
32 import org.objectweb.jorm.api.PMapper;
33 import org.objectweb.jorm.naming.api.PName;
34 import org.objectweb.speedo.mapper.api.JormFactory;
35 import org.objectweb.speedo.mim.api.SpeedoHome;
36 import org.objectweb.speedo.pm.api.ProxyManager;
37 import org.objectweb.util.monolog.api.BasicLevel;
38 import org.objectweb.util.monolog.api.Logger;
39
40 import javax.jdo.Extent;
41 import javax.jdo.FetchPlan;
42 import javax.jdo.JDOException;
43 import javax.jdo.JDOUserException;
44 import javax.jdo.PersistenceManager;
45 import java.util.ArrayList JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.NoSuchElementException JavaDoc;
49
50 /**
51  */

52 public class SpeedoExtent implements Extent {
53
54     private Class JavaDoc candidateClass = null;
55     private boolean hasSubclasses = false;
56     private boolean prefetch = false;
57     private ProxyManager pm = null;
58     private PClassMapping pcm;
59     private Logger logger;
60     private List JavaDoc iterators;
61     private int nextUnused;
62
63     /**
64      * The fetch plan.
65      * When an Extent is retrieved from a PersistenceManager, its FetchPlan is initialized to the same settings
66      * as that of the PersistenceManager.
67      * Subsequent modifications of the Extent's FetchPlan are not reflected
68      * in the FetchPlan of the PersistenceManager.
69      */

70     private FetchPlan fetchPlan;
71     /**
72      * create a new SpeedoExtent object, this object is not obtained by a
73      * call to 'new' by the client application, but by the PersistenceManager
74      * object with getExtent() method
75      * @param candidateClass
76      * @param hasSubclasses
77      * @param pm
78      */

79     public SpeedoExtent(Class JavaDoc candidateClass,
80                         boolean hasSubclasses,
81                         ProxyManager pm,
82                         JormFactory jf,
83                         boolean prefetch,
84                         Logger logger) {
85         iterators = new ArrayList JavaDoc();
86         nextUnused = 0;
87         this.candidateClass = candidateClass;
88         this.hasSubclasses = hasSubclasses;
89         this.prefetch = prefetch;
90         this.logger = logger;
91         this.pm = pm;
92         //initialize the fetch plan to the same settings as that of the peristence manager
93
this.fetchPlan = pm.getFetchPlan();
94         try {
95             pcm = jf.getPClassMapping(candidateClass);
96         } catch (PException e) {
97             throw new JDOUserException("The class '" + candidateClass
98                     + "' is not mapped or is not a persistent class",
99                     new Exception JavaDoc[]{e});
100         }
101         if (pcm == null) {
102             throw new JDOUserException("The class '" + candidateClass
103                     + "' is not mapped or is not a persistent class");
104         }
105         if (prefetch) {
106             prefetch = ((SpeedoHome) pcm).getPrefetchOnExtent();
107         }
108     }
109
110     /**
111      * Returns an iterator over all the instances in the Extent.
112      * @return an iterator over all instances in the Extent
113      */

114     public synchronized Iterator JavaDoc iterator() {
115         POIterator poi;
116         int size = iterators.size();
117         if (nextUnused < size) {
118             // free POIterator instances availlable
119
poi = (POIterator) iterators.get(nextUnused);
120         } else {
121             // Allocate a POIterator
122
poi = new POIterator();
123             iterators.add(nextUnused, poi);
124         }
125         nextUnused++;
126         try {
127             poi.open(pm, pcm, hasSubclasses, prefetch);
128         } catch (PException e) {
129             throw new JDOException("Problem to fetch an Iterator over the class "
130                     + candidateClass.getName(), new Exception JavaDoc[]{e});
131         }
132         return poi;
133     }
134
135     /**
136      * Returns whether this Extent was defined to contain subclasses.
137      * @return true if this Extent was defined to contain instances
138      * that are of a subclass type
139      */

140     public boolean hasSubclasses() {
141         return hasSubclasses;
142     }
143
144     /**
145      * An Extent contains all instances of a particular Class in the data
146      * store; this method returns the Class of the instances
147      * @return the Class of instances of this Extent
148      */

149     public Class JavaDoc getCandidateClass() {
150         return candidateClass;
151     }
152
153     /**
154      * An Extent is managed by a PersistenceManager; this method gives access
155      * to the owning PersistenceManager.
156      * @return the owning PersistenceManager
157      */

158     public PersistenceManager getPersistenceManager() {
159         return pm;
160     }
161
162     public FetchPlan getFetchPlan(){
163         return fetchPlan;
164     }
165     
166     public void setFetchPlan(FetchPlan fp){
167         fetchPlan = fp;
168     }
169         
170     /**
171      * Close all Iterators associated with this Extent instance. Iterators closed
172      * by this method will return false to hasNext() and will throw
173      * NoSuchElementException on next(). The Extent instance can still be used
174      * as a parameter of Query.setExtent, and to get an Iterator.
175      */

176     public synchronized void closeAll() {
177         if (iterators.size() == 0) {
178             return;
179         }
180         for(int i=0; i<nextUnused; i++) {
181             POIterator poi = (POIterator) iterators.get(i);
182             try {
183                 poi.close();
184             } catch (PException e) {
185                 logger.log(BasicLevel.ERROR,
186                         "Impossible to close an Iterator over the class "
187                         + candidateClass.getName(), e);
188             }
189         }
190         nextUnused = 0;
191     }
192
193     /**
194      * Close an Iterator associated with this Extent instance. Iterators closed
195      * by this method will return false to hasNext() and will throw
196      * NoSuchElementException on next(). The Extent instance can still be used
197      * as a parameter of Query.setExtent, and to get an Iterator.
198      * @param it an iterator obtained by the method iterator() on this Extent instance.
199      */

200     public synchronized void close(Iterator JavaDoc it) {
201         if (it instanceof POIterator) {
202             try {
203                 ((POIterator) it).close();
204             } catch (PException e) {
205                 logger.log(BasicLevel.ERROR,
206                         "Impossible to close an Iterator over the class "
207                         + candidateClass.getName(), e);
208             }
209             int idx = iterators.indexOf(it);
210             if (idx == -1) {
211                 logger.log(BasicLevel.WARN,
212                         "The Iterator not managed by this Extent has been closed");
213             } else if (idx < nextUnused) {
214                 iterators.add(iterators.remove(idx));
215                 nextUnused--;
216             } else {
217                 //nothing to do the iterator is already unused
218
}
219         }
220     }
221 }
222 class POIterator implements Iterator JavaDoc {
223
224     private ProxyManager pm;
225     private Iterator JavaDoc pnameIt;
226     private boolean closed;
227     private boolean connectionOpened;
228     private PMapper mapper;
229     private Object JavaDoc connection;
230
231     public void open(ProxyManager pm,
232                      PClassMapping pcm,
233                      boolean subclass,
234                      boolean prefetch) throws PException {
235         this.pm = pm;
236         closed = false;
237         this.mapper = pcm.getPMapper();
238         Object JavaDoc cs = pm.getConnectionSpec();
239         if (cs == null) {
240             connection = mapper.getConnection();
241         } else {
242             connection = mapper.getConnection(cs);
243         }
244         connectionOpened = true;
245         pnameIt = pcm.getPNameIterator(connection, subclass, prefetch, pm.currentTransaction());
246     }
247
248     public void close() throws PException {
249         closed = true;
250         if (connectionOpened) {
251             connectionOpened = false;
252             mapper.closeConnection(connection);
253         }
254         pm = null;
255         mapper = null;
256         connection = null;
257         pnameIt = null;
258     }
259
260     public boolean hasNext() {
261         if (closed || pm.isClosed()) {
262             throw new NoSuchElementException JavaDoc();
263         }
264         if (connectionOpened && !pnameIt.hasNext()) {
265             connectionOpened = false;
266             try {
267                 mapper.closeConnection(connection);
268             } catch (PException e) {
269             }
270         }
271         return pnameIt.hasNext();
272     }
273
274     public Object JavaDoc next() {
275         if (closed || pm.isClosed() || !pnameIt.hasNext()) {
276             if (connectionOpened) {
277                 connectionOpened = false;
278                 try {
279                     mapper.closeConnection(connection);
280                 } catch (PException e) {
281                 }
282             }
283             throw new NoSuchElementException JavaDoc();
284         }
285         PName pn = (PName) pnameIt.next();
286         return pm.getObjectById(pn, false);
287     }
288
289     public void remove() {
290         throw new UnsupportedOperationException JavaDoc();
291     }
292
293     
294     protected void finalize() throws Throwable JavaDoc {
295         super.finalize();
296         if (connectionOpened && mapper!=null) {
297             connectionOpened = false;
298             try {
299                 mapper.closeConnection(connection);
300             } catch (PException e) {
301             }
302         }
303     }
304 }
305
Popular Tags