1 18 package org.objectweb.speedo.mim.lib; 19 20 import org.objectweb.fractal.api.control.BindingController; 21 import org.objectweb.jorm.api.PClassMapping; 22 import org.objectweb.jorm.api.PException; 23 import org.objectweb.jorm.lib.JormPathHelper; 24 import org.objectweb.jorm.naming.api.PBinder; 25 import org.objectweb.jorm.naming.api.PName; 26 import org.objectweb.jorm.type.api.PType; 27 import org.objectweb.jorm.util.api.Loggable; 28 import org.objectweb.perseus.cache.api.CacheEntry; 29 import org.objectweb.perseus.cache.api.CacheEntryFactory; 30 import org.objectweb.perseus.cache.api.CacheEvent; 31 import org.objectweb.perseus.cache.api.FixableCacheEntry; 32 import org.objectweb.perseus.persistence.api.ConnectionHolder; 33 import org.objectweb.perseus.persistence.api.MemoryInstanceManager; 34 import org.objectweb.perseus.persistence.api.PersistenceException; 35 import org.objectweb.perseus.persistence.api.State; 36 import org.objectweb.perseus.persistence.api.StateManager; 37 import org.objectweb.speedo.api.ExceptionHelper; 38 import org.objectweb.speedo.genclass.SpeedoGenClassHome; 39 import org.objectweb.speedo.genclass.SupportedGenClass; 40 import org.objectweb.speedo.genclass.api.SpeedoGenClassProxy; 41 import org.objectweb.speedo.mapper.api.JormFactory; 42 import org.objectweb.speedo.mim.api.LifeCycle; 43 import org.objectweb.speedo.mim.api.MemoryInstanceManagerAttribute; 44 import org.objectweb.speedo.mim.api.SpeedoAccessor; 45 import org.objectweb.speedo.mim.api.SpeedoHome; 46 import org.objectweb.speedo.mim.api.SpeedoProxy; 47 import org.objectweb.speedo.pm.api.ProxyManagerFactory; 48 import org.objectweb.util.monolog.api.BasicLevel; 49 import org.objectweb.util.monolog.api.Logger; 50 51 import java.util.Collections ; 52 import java.util.HashMap ; 53 import java.util.Iterator ; 54 import java.util.Map ; 55 import java.util.StringTokenizer ; 56 57 import javax.jdo.JDOException; 58 import javax.jdo.listener.InstanceLifecycleEvent; 59 60 74 public class SpeedoMemoryInstanceManager 75 implements MemoryInstanceManager, 76 MemoryInstanceManagerAttribute, 77 StateManager, 78 CacheEntryFactory, 79 BindingController { 80 81 public final static String JORM_FACTORY_BINDING = "jorm-factory"; 82 public final static String PMS_BINDING = "proxy-manager-factory"; 83 84 88 private Map name2gcimpl = null; 89 90 protected JormFactory jf = null; 91 protected ProxyManagerFactory pmf = null; 92 93 protected Logger logger = null; 94 95 public SpeedoMemoryInstanceManager() { 96 name2gcimpl = Collections.EMPTY_MAP; 97 } 98 99 private String getGCClassName(String cn) { 100 String res = (String ) name2gcimpl.get(cn); 101 if (res != null) { 102 return res; 103 } 104 for (int i = 0; i < SupportedGenClass.GC_IMPL.length; i++) { 105 if (SupportedGenClass.GC_IMPL[i][0].equals(cn)) { 106 return SupportedGenClass.GC_IMPL[i][1]; 107 } 108 } 109 return null; 110 } 111 112 121 private void activeProxy(SpeedoProxy sp, PName pn) { 122 PClassMapping pcm = null; 124 if (pn != null && (pn.getPNameManager() instanceof PBinder)) { 125 pcm = ((PBinder) pn.getPNameManager()).getBinderClassMapping(); 126 } 127 if (sp instanceof SpeedoGenClassProxy) { 128 if (((SpeedoGenClassProxy) sp).jdoGetPBinding() == null) { 129 if (pcm == null) { 130 pcm = jf.getGenClassMapping( 131 ((SpeedoGenClassProxy) sp).jdoGetGenClassId()); 132 } 133 try { 135 ((SpeedoGenClassProxy) sp).jdoSetPBinding(pcm.createPBinding()); 136 } catch (PException e) { 137 throw new JDOException("Impossible to initialize the delegate PBinding of the genclass", e); 138 } 139 if (sp instanceof Loggable) { 140 ((Loggable) sp).setLogger(logger); 141 } 142 } 143 } else { 144 if (pcm == null) { 145 try { 146 pcm = jf.getPClassMapping(sp.getClass()); 147 } catch (PException e) { 148 throw new JDOException("Impossible to initialize a class", e); 149 } 150 } 151 if (sp.getPClassMapping() == null) { 152 try { 154 sp.init(pcm); 155 } catch (PException e) { 156 Exception ie = ExceptionHelper.getNested(e); 157 if (logger != null) 158 logger.log(BasicLevel.ERROR, 159 "Impossible to init the persistent class: " 160 + sp.getClass().getName(), ie); 161 throw new JDOException("Impossible to init the persistent class:" + 162 ie.getMessage()); 163 } 164 } 165 } 166 sp.jdoIsActive(true); 168 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) 169 logger.log(BasicLevel.DEBUG, "Proxy activated: " + sp.getClass().getName()); 170 } 171 172 public String [] listFc() { 175 return new String []{JORM_FACTORY_BINDING, PMS_BINDING}; 176 } 177 178 public Object lookupFc(String s) { 179 if (JORM_FACTORY_BINDING.equals(s)) { 180 return jf; 181 } else if (PMS_BINDING.equals(s)) { 182 return pmf; 183 } else { 184 return null; 185 } 186 } 187 188 public void bindFc(String s, Object o) { 189 if (JORM_FACTORY_BINDING.equals(s)) { 190 jf = (JormFactory) o; 191 } else if (PMS_BINDING.equals(s)) { 192 pmf =(ProxyManagerFactory) o; 193 } else if ("logger".equals(s)) { 194 logger = (Logger) o; 195 } 196 } 197 198 public void unbindFc(String s) { 199 if (JORM_FACTORY_BINDING.equals(s)) { 200 jf = null; 201 } else if (PMS_BINDING.equals(s)) { 202 pmf = null; 203 } 204 } 205 206 207 210 214 public String getGenClassNames() { 215 if (name2gcimpl == null || name2gcimpl.size() == 0) 216 return "{}"; 217 StringBuffer res = new StringBuffer (""); 218 boolean first = true; 219 for (Iterator it = name2gcimpl.entrySet().iterator(); it.hasNext();) { 220 if (first) { 221 res.append("{"); 222 first = false; 223 } else 224 res.append(","); 225 res.append("("); 226 Map.Entry me = (Map.Entry ) it.next(); 227 res.append(me.getKey()); 228 res.append(","); 229 res.append(me.getValue()); 230 res.append(")"); 231 } 232 res.append("}"); 233 return res.toString(); 234 } 235 236 241 public void setGenClassNames(String gcname) { 242 if (gcname == null || gcname.length() == 0) 243 name2gcimpl = Collections.EMPTY_MAP; 244 name2gcimpl = new HashMap (5); 245 StringTokenizer st = new StringTokenizer (gcname, "{,()}:;[]", false); 246 String key = null; 247 while (st.hasMoreTokens()) { 248 if (key == null) { 249 key = st.nextToken().trim(); 250 } else { 251 name2gcimpl.put(key, st.nextToken().trim()); 252 } 253 } 254 } 255 256 257 260 265 public Object newInstance(Object oid, ConnectionHolder context) throws PersistenceException { 266 if (!(oid instanceof PName)) 267 throw new PersistenceException("Unmanaged object identifier: " + oid); 268 PName pn = (PName) oid; 269 String className = null; 270 try { 271 pn = pn.resolve(context); 272 if (logger.isLoggable(BasicLevel.DEBUG)) { 273 logger.log(BasicLevel.DEBUG, "newInstance(" + oid + "): pn.resolve=" + pn); 274 logger.log(BasicLevel.DEBUG, "newInstance(" + oid + "): pn.type=" + pn.getPType()); 275 } 276 PType type = pn.getPType(); 277 if (type == null) { 278 throw new PersistenceException("newInstance() " 280 + "\n\toid=" + oid 281 + "\n\tpn=" + pn 282 + "\n\tpn.pnc=" + (pn.getPNameManager() != null ? pn.getPNameManager() : null)); 283 } 284 className = type.getJormName(); 285 int idx = className.indexOf(JormPathHelper.SEP); 286 PClassMapping pcm = ((PBinder) pn.getPNameManager()) 287 .getBinderClassMapping(); 288 SpeedoProxy sp = null; 289 if ((pcm instanceof SpeedoGenClassHome) && idx != -1) { 290 className = getGCClassName(className.substring(0, idx)); 292 sp = (SpeedoProxy) Class.forName(className).newInstance(); 293 } else { 294 if (pcm != null) { 295 className = pcm.getClassName(); 296 } 297 ClassLoader cl = jf.getClassLoader(className); 298 if (cl == null) { 299 cl = oid.getClass().getClassLoader(); 300 if (cl == null) { 301 cl = ClassLoader.getSystemClassLoader(); 302 } 303 } 304 sp = (SpeedoProxy) 305 cl.loadClass(className).newInstance(); 306 } 307 return sp; 308 } catch (PException e) { 309 throw new PersistenceException( 310 "Impossible to analyze the object identifier" + oid, e); 311 } catch (Exception e) { 312 throw new PersistenceException( 313 "Impossible to instanciate the class " + className 314 + "Be careful to the generic class (Collection, ...), oid class:" 315 + oid.getClass(), e); 316 } 317 } 318 319 320 public State createState(CacheEntry ce) { 323 return ((SpeedoProxy) ce).createAccessor(); 324 } 325 326 public State createState(State s) { 327 SpeedoProxy sp = (SpeedoProxy) s.getCacheEntry(); 328 SpeedoAccessor sa = sp.createAccessor(); 329 sp.copyAccessor(((SpeedoAccessor) s), sa); 330 return sa; 331 } 332 333 public State getReferenceState(CacheEntry ce) { 334 return ((SpeedoProxy) ce).getReferenceAccessor(); 335 } 336 337 public void destroyState(State state) { 338 } 340 341 public void makeUnexported(State state) { 342 ((SpeedoAccessor) state).jdoChangeStatus(LifeCycle.ACTION_DELETEPERSISTENT); 343 } 344 345 public boolean isUnexported(State state) { 346 return LifeCycle.isDeleted(((SpeedoAccessor) state).jdoGetStatus()); 347 } 348 349 public void makeExported(State state) { 350 ((SpeedoAccessor) state).jdoChangeStatus(LifeCycle.ACTION_MAKEPERSISTENT); 351 } 352 353 public boolean isExported(State state) { 354 return LifeCycle.isNew(((SpeedoAccessor) state).jdoGetStatus()); 355 } 356 357 public void makeDirty(State state) { 358 ((SpeedoAccessor) state).jdoChangeStatus(LifeCycle.ACTION_WRITEFIELD_ACTIVEDATASTORETRANSACTION); 359 ((SpeedoAccessor) state).setFlushed(false); 360 } 361 362 public boolean isDirty(State state) { 363 return LifeCycle.isDirty(((SpeedoAccessor) state).jdoGetStatus()); 364 } 365 366 public void setReferenceState(CacheEntry ce, State state) { 367 if (state == ((SpeedoProxy) ce).getReferenceAccessor()) { 368 return; 369 } 370 SpeedoProxy sp = (SpeedoProxy) ce; 371 if (sp.jdoIsActive() && state != null) { 372 sp.getSpeedoHome().sendEvent(InstanceLifecycleEvent.CLEAR, sp, null, false); 373 } 374 if (state == null || !sp.jdoIsActive() || sp.getSpeedoHome().isCacheable()) { 375 sp.setReferenceAccessor((SpeedoAccessor) state); 376 } else { 377 sp.setReferenceAccessor(null); 378 } 379 } 380 381 public void makeClean(State state) { 382 SpeedoAccessor sa = (SpeedoAccessor) state; 383 sa.jdoSetStatus(LifeCycle.PERSISTENT_CLEAN); 384 } 385 386 public void makeFlushed(State state) { 387 ((SpeedoAccessor) state).setFlushed(true); 388 } 389 390 public boolean isFlushed(State state) { 391 return ((SpeedoAccessor) state).hasBeenFlush(); 392 } 393 394 public void makeUnbound(CacheEntry ce) { 395 SpeedoProxy sp = (SpeedoProxy) ce; 396 sp.jdoIsActive(false); 397 try { 398 sp.init(null); 399 } catch (PException e) { 400 logger.log(BasicLevel.WARN, "Error during the unbinding: ", e); 401 } 402 } 403 404 public void makeBound(CacheEntry ce, Object oid) { 405 PName pname = (PName) oid; 406 SpeedoProxy sp = (SpeedoProxy) ce; 407 try { 408 sp.bind(pname); 409 } catch (PException e) { 410 logger.log(BasicLevel.WARN, "Error during the binding: ", e); 411 } 412 } 413 414 public boolean isBound(CacheEntry ce) { 415 return ((SpeedoProxy) ce).jdoIsActive(); 416 } 417 418 public boolean isToMerge(State state) { 419 return ((SpeedoAccessor) state).isToMerge(); 420 } 421 public void makeToMerge(State state, Object thinLock) { 422 ((SpeedoAccessor) state).makeToMerge(thinLock); 423 } 424 public State merge(State oldState, State newState) { 425 return ((SpeedoAccessor) newState).merge(oldState); 426 } 427 428 public void stateNoMoreUsed(State state) { 429 ((SpeedoAccessor) state).unSwizzle(); 430 } 431 432 435 438 public void entryBound(CacheEvent event) { 439 } 440 441 444 public void entryUnbound(CacheEvent event) { 445 if (logger.isLoggable(BasicLevel.DEBUG)) { 446 logger.log(BasicLevel.DEBUG, "Entry unbound from the cache: \n\tid: " 447 + event.getCeIdentifier()); 448 } 449 PName pn = (PName) event.getCeIdentifier(); 450 SpeedoHome sh = (SpeedoHome) 451 ((PBinder) pn.getPNameManager()).getBinderClassMapping(); 452 sh.userCacheEntryUnbound(pn); 453 } 454 455 456 459 466 public FixableCacheEntry create(Object id, Object obj) { 467 SpeedoProxy sp = (SpeedoProxy) obj; 468 PName pn = (PName) id; 469 activeProxy(sp, pn); 470 if (sp.getPName() == null || sp.getPName().isNull()) { 471 try { 472 pn.resolve(null); 473 sp.bind(pn); 474 } catch (PException e) { 475 throw new JDOException( 476 "Impossible to bind the proxy to its persistent name: ", e); 477 } 478 } 479 483 return (FixableCacheEntry) obj; 484 } 485 } 486 | Popular Tags |