1 18 package org.objectweb.speedo.mapper.lib; 19 20 import org.objectweb.perseus.persistence.api.StorageManager; 21 import org.objectweb.perseus.persistence.api.PersistenceException; 22 import org.objectweb.perseus.persistence.api.NoDSIPersistenceException; 23 import org.objectweb.perseus.persistence.api.ConnectionHolder; 24 import org.objectweb.perseus.persistence.api.WorkingSet; 25 import org.objectweb.perseus.persistence.api.State; 26 import org.objectweb.jorm.api.PException; 27 import org.objectweb.jorm.api.PBinding; 28 import org.objectweb.jorm.api.PExceptionNoDSI; 29 import org.objectweb.jorm.api.PAccessor; 30 import org.objectweb.jorm.naming.api.PName; 31 import org.objectweb.fractal.api.control.BindingController; 32 import org.objectweb.util.monolog.api.Logger; 33 import org.objectweb.util.monolog.api.BasicLevel; 34 import org.objectweb.speedo.api.ExceptionHelper; 35 import org.objectweb.speedo.mapper.api.JormFactory; 36 import org.objectweb.speedo.mim.api.LifeCycle; 37 import org.objectweb.speedo.mim.api.SpeedoAccessor; 38 import org.objectweb.speedo.mim.api.SpeedoProxy; 39 40 import javax.jdo.listener.InstanceLifecycleEvent; 41 42 import java.util.Iterator ; 43 import java.util.Map ; 44 import java.util.HashMap ; 45 import java.util.HashSet ; 46 import java.util.Set ; 47 48 49 57 public class JormStorageManager 58 implements StorageManager, BindingController { 59 60 public final static String JORM_FACTORY_BINDING = "jorm-factory"; 61 public final static String LOGGER_NAME = "org.objectweb.jorm.storageManager"; 62 63 protected JormFactory jormFactory = null; 64 65 protected Logger logger = null; 66 67 73 protected Map ws2removedpo = new HashMap (); 74 75 78 public String [] listFc() { 79 return new String [] { JORM_FACTORY_BINDING }; 80 } 81 82 public Object lookupFc(String s) { 83 if (JORM_FACTORY_BINDING.equals(s)) { 84 return jormFactory; 85 } 86 return null; 87 } 88 89 public void bindFc(String s, Object o) { 90 if ("logger".equals(s)) { 91 logger = (Logger) o; 92 } else if (JORM_FACTORY_BINDING.equals(s)) { 93 jormFactory = (JormFactory) o; 94 } 95 } 96 97 public void unbindFc(String s) { 98 if (JORM_FACTORY_BINDING.equals(s)) { 99 jormFactory = null; 100 } 101 } 102 103 104 107 public Object export(ConnectionHolder context, Object obj) throws PersistenceException { 108 PBinding pb = (PBinding) obj; 109 try { 110 if (pb.getStatus() == PBinding.LIFECYCLE_DELTOWRITE) { 111 pb.write(context, (PAccessor) obj); 112 } 113 return pb.export(context); 114 } catch (PException e) { 115 throw new PersistenceException(e); 116 } 117 } 118 119 public Object export(ConnectionHolder context, Object obj, Object hints) throws PersistenceException { 120 PBinding pb = (PBinding) obj; 121 try { 122 if (pb.getStatus() == PBinding.LIFECYCLE_DELTOWRITE) { 123 pb.write(context, (PAccessor) obj); 124 } 125 return pb.export(context, hints); 126 } catch (PException e) { 127 throw new PersistenceException(e); 128 } 129 } 130 131 public void unexport(ConnectionHolder context, Object oid) throws PersistenceException { 132 if (logger.isLoggable(BasicLevel.DEBUG)) { 133 logger.log(BasicLevel.DEBUG, 134 "unexport ctx=" + context + " / oid=" + oid); 135 } 136 try { 137 ((PName) oid).unexport(context); 138 } catch (PException e) { 139 throw new PersistenceException(e); 140 } 141 registerUnexport(context.getWorkingSet(), oid); 142 } 143 144 public void unexport(ConnectionHolder context, Object oid, Object hints) throws PersistenceException { 145 if (logger.isLoggable(BasicLevel.DEBUG)) { 146 logger.log(BasicLevel.DEBUG, 147 "unexport(hints) ctx=" + context + " / oid=" + oid); 148 } 149 try { 150 ((PName) oid).unexport(context, hints); 151 } catch (PException e) { 152 throw new PersistenceException(e); 153 } 154 registerUnexport(context.getWorkingSet(), oid); 155 } 156 157 public void read(ConnectionHolder context, Object oid, State obj) throws PersistenceException { 158 if (logger.isLoggable(BasicLevel.DEBUG)) 159 logger.log(BasicLevel.DEBUG, "read ctx=" + context 160 + " / oid=" + oid 161 + " / obj.class=" + obj.getClass().getName()); 162 SpeedoProxy pb = (SpeedoProxy) obj.getCacheEntry(); 163 int jdoStatus = ((SpeedoAccessor) obj).jdoGetStatus(); 164 if (pb.getStatus() == PBinding.LIFECYCLE_DELTOWRITE 165 && jdoStatus != LifeCycle.PERSISTENT_DELETED 166 && jdoStatus != LifeCycle.PERSISTENT_NEW_DELETED) { 167 throw new PersistenceException( 168 "Concurrency problem, transaction must be rolledback"); 169 } 170 try { 171 pb.read(context, (PAccessor) obj); 172 ((SpeedoAccessor) obj).indexFieldModified(Integer.MAX_VALUE, true); 174 pb.getSpeedoHome().sendEvent(InstanceLifecycleEvent.LOAD, pb, null, false); 175 } catch (PExceptionNoDSI e) { 176 if (logger.isLoggable(BasicLevel.DEBUG)) { 177 logger.log(BasicLevel.DEBUG, "read ==> NO DSI"); 178 } 179 throw new NoDSIPersistenceException(e); 180 } catch (PException e) { 181 Exception ie = ExceptionHelper.getNested(e); 182 logger.log(BasicLevel.ERROR, "read ctx=" + context 183 + " / oid=" + oid 184 + " / obj.class=" + obj.getClass().getName(), ie); 185 throw new PersistenceException(ie); 186 } 187 } 188 189 public void read(WorkingSet ws, Object oid, State obj) throws PersistenceException { 190 Object conn = ws.getConnectionHolder().getCHConnectionForRead(); 191 if (logger.isLoggable(BasicLevel.DEBUG)) 192 logger.log(BasicLevel.DEBUG, "read conn=" + conn 193 + " / oid=" + oid 194 + " / obj.class=" + obj.getClass().getName() 195 + " / tx=" + ws); 196 SpeedoProxy pb = (SpeedoProxy) obj.getCacheEntry(); 197 int jdoStatus = ((SpeedoAccessor) obj).jdoGetStatus(); 198 if (pb.getStatus() == PBinding.LIFECYCLE_DELTOWRITE 199 && jdoStatus != LifeCycle.PERSISTENT_DELETED 200 && jdoStatus != LifeCycle.PERSISTENT_NEW_DELETED) { 201 throw new PersistenceException( 202 "Concurrency problem, transaction must be rolledback"); 203 } 204 Object ctx = usePrefetchBuffer(ws, oid) ? ws : null; 205 try { 206 pb.read(conn, (PAccessor) obj, ctx); 207 ((SpeedoAccessor) obj).indexFieldModified(Integer.MAX_VALUE, true); 209 pb.getSpeedoHome().sendEvent(InstanceLifecycleEvent.LOAD, pb, null, false); 210 } catch (PExceptionNoDSI e) { 211 if (logger.isLoggable(BasicLevel.DEBUG)) { 212 logger.log(BasicLevel.DEBUG, "read ==> NO DSI"); 213 } 214 throw new NoDSIPersistenceException(e); 215 } catch (PException e) { 216 Exception ie = ExceptionHelper.getNested(e); 217 logger.log(BasicLevel.ERROR, "read conn=" + conn 218 + " / oid=" + oid 219 + " / obj.class=" + obj.getClass().getName() 220 + " / tx=" + ws, ie); 221 throw new PersistenceException(ie); 222 } 223 } 224 225 public void write(ConnectionHolder context, Object oid, State obj) throws PersistenceException { 226 SpeedoProxy pb = (SpeedoProxy) obj.getCacheEntry(); 227 if (logger.isLoggable(BasicLevel.DEBUG)) { 228 logger.log(BasicLevel.DEBUG, "write ctx=" + context 229 + " / oid=" + oid 230 + " / obj.class=" + obj.getClass().getName() 231 + " / binding.status=" + pb.getStatus()); 232 } 233 int s = pb.getStatus(); 234 if (s == PBinding.LIFECYCLE_ACTIVEFORIO 235 || s == PBinding.LIFECYCLE_NEWTOWRITE 236 || s == PBinding.LIFECYCLE_DELTOWRITE) { 237 if (s != PBinding.LIFECYCLE_DELTOWRITE) { 238 pb.getSpeedoHome().sendEvent(InstanceLifecycleEvent.STORE, pb, null, true); 239 } 240 try { 241 pb.write(context, (PAccessor) obj); 242 } catch (PExceptionNoDSI e) { 243 throw new NoDSIPersistenceException(e); 244 } catch (PException e) { 245 throw new PersistenceException(e); 246 } 247 if (s != PBinding.LIFECYCLE_DELTOWRITE) { 248 pb.getSpeedoHome().sendEvent(InstanceLifecycleEvent.STORE, pb, null, false); 249 } 250 } 251 } 252 253 public void beginWS(WorkingSet ws) { 254 synchronized(ws2removedpo) { 255 ws2removedpo.put(ws, new RemovedPOMemento(ws)); 256 if (logger.isLoggable(BasicLevel.DEBUG)) { 257 logger.log(BasicLevel.DEBUG, "Begin of WS" 258 + "\n\t-ws=" + ws); 259 } 260 } 261 } 262 263 266 public void endWS(WorkingSet ws) { 267 synchronized(ws2removedpo) { 268 RemovedPOMemento mem = (RemovedPOMemento) ws2removedpo.remove(ws); 269 StringBuffer sb = null; 270 if (mem.removedPOFromWS != null) { 271 for (Iterator it = ws2removedpo.values().iterator(); it.hasNext();) { 272 RemovedPOMemento _mem = (RemovedPOMemento) it.next(); 273 _mem.addRemovedPOFromOtherWS(mem.removedPOFromWS); 274 if (logger.isLoggable(BasicLevel.DEBUG)) { 275 if (sb == null) { 276 sb = new StringBuffer (); 277 sb.append("Add\n\t-oids= "); 278 sb.append(mem.removedPOFromWS); 279 } 280 sb.append("\n\t-ws= " + _mem.ws); 281 } 282 } 283 if (logger.isLoggable(BasicLevel.DEBUG)) { 284 logger.log(BasicLevel.DEBUG, sb.toString()); 285 } 286 } 287 } 288 } 289 290 private void registerUnexport(WorkingSet ws, Object oid) { 291 synchronized(ws2removedpo) { 292 ((RemovedPOMemento) ws2removedpo.get(ws)).registerRemovedPOFromWS(oid); 293 if (logger.isLoggable(BasicLevel.DEBUG)) { 294 logger.log(BasicLevel.DEBUG, "Register the removed object:" 295 + "\n\t-oid=" + oid 296 + "\n\t-ws=" + ws); 297 } 298 } 299 } 300 301 306 private boolean usePrefetchBuffer(WorkingSet ws, Object oid) { 307 synchronized(ws2removedpo) { 308 boolean res = !((RemovedPOMemento) ws2removedpo.get(ws)).isRemoved(oid); 309 if (logger.isLoggable(BasicLevel.DEBUG)) { 310 logger.log(BasicLevel.DEBUG,(res ? "": "NOT " ) + "USE prefetch buffer" 311 + "\n\t-oid=" + oid 312 + "\n\t-ws= " + ws); 313 } 314 return res; 315 } 316 } 317 } 318 324 class RemovedPOMemento { 325 331 public HashSet removedPOFromWS = null; 332 333 339 public HashSet removedPO = null; 340 341 public final WorkingSet ws; 342 343 public RemovedPOMemento(WorkingSet _ws) { 344 this.ws = _ws; 345 } 346 347 351 public void registerRemovedPOFromWS(Object oid) { 352 if (removedPOFromWS == null) { 353 removedPOFromWS = new HashSet (); 354 } 355 removedPOFromWS.add(oid); 356 if (removedPO == null) { 357 removedPO = new HashSet (); 358 } 359 removedPO.add(oid); 360 } 361 362 368 public void addRemovedPOFromOtherWS(Set oids) { 369 if (removedPO == null) { 370 removedPO = new HashSet (); 371 } 372 removedPO.addAll(oids); 373 } 374 375 381 public boolean isRemoved(Object oid) { 382 return removedPO != null && removedPO.contains(oid); 383 } 384 } 385 | Popular Tags |