1 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 ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.NoSuchElementException ; 49 50 52 public class SpeedoExtent implements Extent { 53 54 private Class 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 iterators; 61 private int nextUnused; 62 63 70 private FetchPlan fetchPlan; 71 79 public SpeedoExtent(Class candidateClass, 80 boolean hasSubclasses, 81 ProxyManager pm, 82 JormFactory jf, 83 boolean prefetch, 84 Logger logger) { 85 iterators = new ArrayList (); 86 nextUnused = 0; 87 this.candidateClass = candidateClass; 88 this.hasSubclasses = hasSubclasses; 89 this.prefetch = prefetch; 90 this.logger = logger; 91 this.pm = pm; 92 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 []{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 114 public synchronized Iterator iterator() { 115 POIterator poi; 116 int size = iterators.size(); 117 if (nextUnused < size) { 118 poi = (POIterator) iterators.get(nextUnused); 120 } else { 121 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 []{e}); 131 } 132 return poi; 133 } 134 135 140 public boolean hasSubclasses() { 141 return hasSubclasses; 142 } 143 144 149 public Class getCandidateClass() { 150 return candidateClass; 151 } 152 153 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 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 200 public synchronized void close(Iterator 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 } 219 } 220 } 221 } 222 class POIterator implements Iterator { 223 224 private ProxyManager pm; 225 private Iterator pnameIt; 226 private boolean closed; 227 private boolean connectionOpened; 228 private PMapper mapper; 229 private Object 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 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 (); 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 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 (); 284 } 285 PName pn = (PName) pnameIt.next(); 286 return pm.getObjectById(pn, false); 287 } 288 289 public void remove() { 290 throw new UnsupportedOperationException (); 291 } 292 293 294 protected void finalize() throws Throwable { 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 |