1 27 package ch.ethz.prose; 28 29 import java.security.AccessControlException ; 31 import java.util.Collections ; 32 import java.util.Comparator ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Set ; 37 import java.util.SortedSet ; 38 import java.util.TreeSet ; 39 import java.util.Vector ; 40 import java.util.HashMap ; 41 42 import ch.ethz.jvmai.JVMAspectInterface; 43 import ch.ethz.prose.crosscut.Crosscut; 44 import ch.ethz.prose.crosscut.CrosscutRequest; 45 import ch.ethz.prose.crosscut.CrosscutGroup; 46 import ch.ethz.prose.engine.ClassLoadListener; 47 import ch.ethz.prose.engine.JoinPointManager; 48 import ch.ethz.prose.engine.JoinPointRequest; 49 import ch.ethz.prose.query.JoinPointRequestSurrogate; 50 import ch.ethz.inf.util.Logger; 51 52 60 public 61 class LocalAspectManager implements AspectManager, ClassLoadListener { 62 63 static int ABORT = 0x1; 64 static int COMMIT = 0x2; 65 66 private HashMap txMap = new HashMap (); 67 private Set theExtensions; 68 private boolean isConnectedToVM; 69 private boolean isStarted; 70 protected JoinPointManager jpm; 71 72 73 79 protected LocalAspectManager(boolean isConnected, JVMAspectInterface ai) 80 { 81 isConnectedToVM = isConnected; 82 isStarted = false; 83 theExtensions = Collections.synchronizedSet(new HashSet ()); 84 createJoinPointManager(isConnectedToVM, ai); 85 jpm.registerListener(this); 86 } 87 88 89 93 protected void createJoinPointManager(boolean isConnected, JVMAspectInterface ai) 94 { 95 jpm = new JoinPointManager(isConnected, ai, true); 96 } 97 98 101 public synchronized void startup() 102 { 103 isStarted = true; 104 } 106 107 110 public synchronized void teardown() 111 { 112 if (!isStarted) 113 return; 114 115 withdrawAll(); 116 if (jpm != null) 117 { 118 jpm.disconnectFromJVMAI(); 119 jpm = null; 120 } 121 isStarted=false; 122 } 123 124 125 { Class c=Throwable .class;} 126 133 public void classLoaded(Class newClass) 134 { 135 if (newClass.getName().endsWith("Exception")) 141 return; 142 143 synchronized(theExtensions) 144 { 145 Iterator i = theExtensions.iterator(); 146 while (i.hasNext()) 147 { 148 Aspect crtExtension = (Aspect)i.next(); 149 registerCrosscuts(crtExtension,newClass); 150 } 151 } 152 } 153 154 155 156 static class TransactionGroup 157 { 158 CrosscutGroup insertGroup; 159 CrosscutGroup withdrawGroup; 160 List toBeInserted; 161 List toBeWithdrawn; 162 163 TransactionGroup() 164 { 165 insertGroup = new CrosscutGroup(); 166 insertGroup.setExecuteAdvice(false); 167 withdrawGroup = new CrosscutGroup(); 168 withdrawGroup.setExecuteAdvice(true); 169 toBeInserted = new Vector (); 170 toBeWithdrawn = new Vector (); 171 } 172 }; 173 174 private TransactionGroup getTransactionGroup(Object transactionId) 175 { 176 TransactionGroup crtGroup = (TransactionGroup)txMap.get(transactionId); 177 if (crtGroup == null) 178 { 179 crtGroup = new TransactionGroup(); 180 txMap.put(transactionId,crtGroup); 181 } 182 183 return crtGroup; 184 } 185 186 private void prepareInsertExtension(Aspect ext, Object transactionId) 187 { 188 TransactionGroup crtGroup = getTransactionGroup(transactionId); 190 191 crtGroup.toBeInserted.add(ext); 193 194 Iterator i = ext.getCrosscuts().iterator(); 196 while (i.hasNext()) 197 { 198 Crosscut crtCrosscut = (Crosscut)i.next(); 199 crtCrosscut.associateToGroup(crtGroup.insertGroup); 200 } 201 } 202 203 private void prepareWithdrawExtension(Aspect ext, Object transactionId) 204 { 205 TransactionGroup crtGroup = getTransactionGroup(transactionId); 207 208 crtGroup.toBeWithdrawn.add(ext); 210 211 Iterator i = ext.getCrosscuts().iterator(); 213 while (i.hasNext()) 214 { 215 Crosscut crtCrosscut = (Crosscut)i.next(); 216 crtCrosscut.associateToGroup(crtGroup.withdrawGroup); 217 } 218 } 219 220 221 private void finishTransaction(Object transactionId, int commitOrAbort) 222 { 223 TransactionGroup crtGroup = getTransactionGroup(transactionId); 225 List extensionsToWithdraw = null; 226 227 if (commitOrAbort == COMMIT) 228 { 229 crtGroup.insertGroup.setExecuteAdvice(true); 230 crtGroup.withdrawGroup.setExecuteAdvice(false); 231 extensionsToWithdraw = crtGroup.toBeWithdrawn; 232 } 233 if (commitOrAbort == ABORT) 234 { 235 extensionsToWithdraw = crtGroup.toBeInserted; 236 } 237 238 Iterator i = extensionsToWithdraw.iterator(); 239 while (i.hasNext()) 240 doWithdrawExtension((Aspect)(i.next())); 241 242 txMap.remove(transactionId); 243 } 244 245 246 public void insert(Aspect x,Object txId) 247 { 248 if (txId == null) 249 throw new IllegalArgumentException ("txId must be non-null"); 250 prepareInsertExtension(x,txId); 251 doInsertExtension(x); 252 } 253 254 public void withdraw(Aspect x, Object txId) 255 { 256 if (txId == null || x == null) 257 throw new IllegalArgumentException ("txId must be non-null"); 258 prepareWithdrawExtension(x,txId); 259 } 260 261 262 public void insert(Aspect x) 263 { 264 Object txId = new Object (); 265 if (txId == null || x == null) 266 throw new IllegalArgumentException ("txId and x must be non-null"); 267 268 try 269 { 270 insert(x,txId); 271 finishTransaction(txId,COMMIT); 272 } 273 catch (RuntimeException e) 274 { 275 finishTransaction(txId,ABORT); 276 throw e; 277 } 278 279 } 280 281 public void withdraw(Aspect x) 282 { 283 Object txId = new Object (); 284 if (txId == null || x == null) 285 throw new IllegalArgumentException ("txId must be non-null"); 286 287 try 288 { 289 withdraw(x,txId); 290 finishTransaction(txId,COMMIT); 291 } 292 catch (RuntimeException e) 293 { 294 finishTransaction(txId,ABORT); 295 throw e; 296 } 297 } 298 299 public void commit(Object txId) 300 { 301 finishTransaction(txId,COMMIT); 302 } 303 304 public void abort(Object txId) 305 { 306 finishTransaction(txId,ABORT); 307 } 308 309 314 public synchronized void doInsertExtension(Aspect ext) throws AspectManagerException 315 { 316 317 318 jpm.suspendListenerNotification(Thread.currentThread()); 320 321 Logger.message("LocalAspectManager(" + isConnectedToVM + ").insertExtension: attempting insert, extension=" + ext); 322 try 323 { 324 ext.insertionAction(true); 325 } 326 catch (AspectInsertionException extDoesntLikeThisVM) 327 { 328 Logger.warning("LocalExtgensionManager(" + isConnectedToVM + 329 ").insertExtnesion:failed 'insertAction'",extDoesntLikeThisVM); 330 throw new AspectManagerException("Aspect ext does not wish to be inserted(" + 331 extDoesntLikeThisVM.toString()+")"); 332 } 333 334 if (theExtensions.contains(ext)) 336 { 337 Logger.message("LocalAspectManager(" + isConnectedToVM + 338 ").insertExtension: failed, ext. already existent, extension=" + ext); 339 throw new AspectManagerException("Aspect already available"); 340 } 341 342 registerCrosscuts(ext,null); 345 346 theExtensions.add(ext); 348 349 try 351 { 352 ext.insertionAction(false); 353 } 354 catch (Exception e) 355 { 356 Logger.warning("LocalAspectManager(" + isConnectedToVM 357 + ").insertExtension: insertAction failed, extension = " + ext); 358 } 359 360 jpm.resumeListenerNotification(Thread.currentThread()); 362 Logger.message("LocalAspectManager(" + isConnectedToVM + ").insertExtension: done"); 363 } 364 365 366 private void registerCrosscuts(Aspect ext, Class cls) 367 { 368 Iterator i = ext.getCrosscuts().iterator(); 369 while (i.hasNext()) 370 { 371 372 Crosscut crtCrosscut = (Crosscut)i.next(); 373 374 if ( (crtCrosscut instanceof Insertable) && cls == null) 375 ((Insertable)crtCrosscut).insertionAction(true); 376 377 CrosscutRequest crtRequest = null; 378 if (cls == null) 379 crtRequest = crtCrosscut.createRequest(); 380 else 381 crtRequest = crtCrosscut.createRequest(cls); 382 383 Iterator j = crtRequest.iterator(); 384 while (j.hasNext()) 385 { 386 JoinPointRequest crtJPR = (JoinPointRequest)(j.next()); 387 jpm.registerListener(crtCrosscut,crtJPR); 388 } 389 390 if ( (crtCrosscut instanceof Insertable) && cls == null) 391 ((Insertable)crtCrosscut).insertionAction(false); 392 393 } 394 } 395 396 400 public synchronized void doWithdrawExtension(Aspect ext) 401 { 402 Logger.message("LocalAspectManager(" + isConnectedToVM + ").withdrawExtension: withdrawing " + ext); 403 jpm.suspendListenerNotification(Thread.currentThread()); 404 405 try 406 { 407 ext.withdrawalAction(true); 408 } 409 catch (Exception e) 410 { 411 Logger.warning("Aspect does not wish withdrawal",e); 412 } 413 414 Iterator i = ext.getCrosscuts().iterator(); 415 while (i.hasNext()) 416 { 417 Crosscut crtCrosscut = (Crosscut)i.next(); 418 jpm.unregisterListener(crtCrosscut); 419 } 420 theExtensions.remove(ext); 421 422 try 423 { 424 ext.withdrawalAction(false); 425 } 426 catch (Exception e) 427 { 428 Logger.message("extension " + ext + " does not wish withdrawal (end)"); 429 } 430 431 jpm.resumeListenerNotification(Thread.currentThread()); 432 } 433 434 438 public List getAllAspects() 439 { 440 return new Vector (theExtensions); 441 } 442 443 444 447 public JoinPointManager getJoinPointManager() 448 { 449 return jpm; 450 } 451 452 453 457 public boolean isConnectedToVM() 458 { 459 return isConnectedToVM; 460 } 461 462 463 private void withdrawAll() 464 { 465 if (jpm == null) 466 return; 467 468 jpm.suspendListenerNotification(Thread.currentThread()); 469 470 if (getAllAspects() == null) 471 return; 472 473 Iterator i = new HashSet (getAllAspects()).iterator(); 474 while (i.hasNext()) 475 { 476 Aspect e = (Aspect)i.next(); 477 withdraw(e); 478 } 479 480 jpm.resumeListenerNotification(Thread.currentThread()); 481 } 482 483 484 485 486 487 491 protected void finalize() 492 { 493 494 if (jpm != null) 496 { 497 jpm.disconnectFromJVMAI(); 498 jpm = null; 499 } 500 501 502 } 503 } 504 505 506
| Popular Tags
|