1 22 package org.jboss.deployers.plugins.deployment; 23 24 import static org.jboss.deployers.spi.structure.DeploymentState.DEPLOYED; 25 import static org.jboss.deployers.spi.structure.DeploymentState.DEPLOYING; 26 import static org.jboss.deployers.spi.structure.DeploymentState.ERROR; 27 import static org.jboss.deployers.spi.structure.DeploymentState.UNDEPLOYED; 28 import static org.jboss.deployers.spi.structure.DeploymentState.UNDEPLOYING; 29 import static org.jboss.deployers.spi.structure.StructureDetermined.NO; 30 import static org.jboss.deployers.spi.structure.StructureDetermined.PREDETERMINED; 31 import static org.jboss.deployers.spi.structure.StructureDetermined.YES; 32 33 import java.util.ArrayList ; 34 import java.util.Collection ; 35 import java.util.Collections ; 36 import java.util.HashSet ; 37 import java.util.List ; 38 import java.util.Map ; 39 import java.util.Set ; 40 import java.util.SortedSet ; 41 import java.util.TreeSet ; 42 import java.util.concurrent.ConcurrentHashMap ; 43 import java.util.concurrent.CopyOnWriteArrayList ; 44 import java.util.concurrent.atomic.AtomicBoolean ; 45 46 import org.jboss.deployers.plugins.deployer.AbstractDeploymentUnit; 47 import org.jboss.deployers.plugins.deployer.DeployerWrapper; 48 import org.jboss.deployers.plugins.structure.BasicStructuredDeployers; 49 import org.jboss.deployers.plugins.structure.DefaultStructureBuilder; 50 import org.jboss.deployers.plugins.structure.StructureMetaDataImpl; 51 import org.jboss.deployers.spi.DeploymentException; 52 import org.jboss.deployers.spi.deployer.Deployer; 53 import org.jboss.deployers.spi.deployer.DeploymentUnit; 54 import org.jboss.deployers.spi.deployment.MainDeployer; 55 import org.jboss.deployers.spi.structure.DeploymentContext; 56 import org.jboss.deployers.spi.structure.vfs.StructureBuilder; 57 import org.jboss.deployers.spi.structure.vfs.StructureDeployer; 58 import org.jboss.deployers.spi.structure.vfs.StructureMetaData; 59 import org.jboss.logging.Logger; 60 import org.jboss.virtual.VirtualFile; 61 62 70 public class MainDeployerImpl implements MainDeployer 71 { 72 73 private static final Logger log = Logger.getLogger(MainDeployerImpl.class); 74 75 76 private AtomicBoolean shutdown = new AtomicBoolean (false); 77 78 79 private BasicStructuredDeployers structureDeployers = new BasicStructuredDeployers(); 80 81 82 private StructureBuilder structureBuilder = new DefaultStructureBuilder(); 83 84 85 private SortedSet <Deployer> deployers = new TreeSet <Deployer>(Deployer.COMPARATOR); 86 87 88 private Map <String , DeploymentContext> topLevelDeployments = new ConcurrentHashMap <String , DeploymentContext>(); 89 90 91 private Map <String , DeploymentContext> allDeployments = new ConcurrentHashMap <String , DeploymentContext>(); 92 93 94 private Map <String , DeploymentContext> errorDeployments = new ConcurrentHashMap <String , DeploymentContext>(); 95 96 97 private Map <String , DeploymentContext> missingDeployers = new ConcurrentHashMap <String , DeploymentContext>(); 98 99 100 private List <DeploymentContext> undeploy = new CopyOnWriteArrayList <DeploymentContext>(); 101 102 103 private List <DeploymentContext> deploy = new CopyOnWriteArrayList <DeploymentContext>(); 104 105 110 public synchronized Set <StructureDeployer> getStructureDeployers() 111 { 112 SortedSet <StructureDeployer> sdeployers = structureDeployers.getDeployers(); 113 return sdeployers; 114 } 115 116 122 public synchronized void setStructureDeployers(Set <StructureDeployer> deployers) 123 { 124 if (deployers == null) 125 throw new IllegalArgumentException ("Null deployers"); 126 structureDeployers.setDeployers(deployers); 127 } 128 129 134 public synchronized void addStructureDeployer(StructureDeployer deployer) 135 { 136 if (deployer == null) 137 throw new IllegalArgumentException ("Null deployer"); 138 structureDeployers.addDeployer(deployer); 139 log.debug("Added structure deployer: " + deployer); 141 } 142 143 148 public synchronized void removeStructureDeployer(StructureDeployer deployer) 149 { 150 if (deployer == null) 151 throw new IllegalArgumentException ("Null deployer"); 152 structureDeployers.removeDeployer(deployer); 153 log.debug("Remove structure deployer: " + deployer); 154 } 156 157 162 public synchronized Set <Deployer> getDeployers() 163 { 164 return new TreeSet <Deployer>(deployers); 165 } 166 167 173 public synchronized void setDeployers(Set <Deployer> deployers) 174 { 175 if (deployers == null) 176 throw new IllegalArgumentException ("Null deployers"); 177 178 HashSet <Deployer> oldDeployers = new HashSet <Deployer>(this.deployers); 180 oldDeployers.removeAll(deployers); 181 for (Deployer deployer : oldDeployers) 182 removeDeployer(deployer); 183 184 HashSet <Deployer> newDeployers = new HashSet <Deployer>(deployers); 186 newDeployers.removeAll(this.deployers); 187 for (Deployer deployer : newDeployers) 188 addDeployer(deployer); 189 } 190 191 196 public synchronized void addDeployer(Deployer deployer) 197 { 198 if (deployer == null) 199 throw new IllegalArgumentException ("Null deployer"); 200 DeployerWrapper wrapper = new DeployerWrapper(deployer); 201 deployers.add(wrapper); 202 log.debug("Added deployer: " + deployer); 203 } 205 206 211 public synchronized void removeDeployer(Deployer deployer) 212 { 213 if (deployer == null) 214 throw new IllegalArgumentException ("Null deployer"); 215 deployers.remove(deployer); 216 log.debug("Removed deployer: " + deployer); 217 } 219 220 public DeploymentContext getDeploymentContext(String name) 221 { 222 if (name == null) 223 throw new IllegalArgumentException ("Null name"); 224 return allDeployments.get(name); 225 } 226 227 public StructureBuilder getStructureBuilder() 228 { 229 return structureBuilder; 230 } 231 public void setStructureBuilder(StructureBuilder builder) 232 { 233 this.structureBuilder = builder; 234 } 235 236 public synchronized void addDeploymentContext(DeploymentContext context) throws DeploymentException 237 { 238 if (context == null) 239 throw new DeploymentException("Null context"); 240 241 if (shutdown.get()) 242 throw new DeploymentException("The main deployer is shutdown"); 243 244 log.debug("Add deployment context: " + context.getName()); 245 246 if (context.isTopLevel() == false) 247 throw new DeploymentException("Context is not a top level deployment: " + context.getName()); 248 249 String name = context.getName(); 250 DeploymentContext previous = topLevelDeployments.get(name); 251 boolean topLevelFound = false; 252 if (previous != null) 253 { 254 log.debug("Removing previous deployment: " + previous.getName()); 255 removeContext(previous); 256 topLevelFound = true; 257 } 258 259 if (topLevelFound == false) 260 { 261 previous = allDeployments.get(name); 262 if (previous != null) 263 throw new IllegalStateException ("Deployment already exists as a subdeployment: " + context.getName()); 264 } 265 266 reset(context); 267 268 topLevelDeployments.put(name, context); 269 try 270 { 271 determineStructure(context); 272 } 273 catch (Throwable t) 274 { 275 log.error("Unable to determine structure of deployment: " + name, t); 276 context.setState(ERROR); 277 context.setProblem(t); 278 errorDeployments.put(name, context); 279 } 280 281 addContext(context); 282 } 283 284 public synchronized boolean removeDeploymentContext(String name) throws DeploymentException 285 { 286 if (name == null) 287 throw new DeploymentException("Null name"); 288 289 if (shutdown.get()) 290 throw new IllegalStateException ("The main deployer is shutdown"); 291 292 log.debug("Remove deployment context: " + name); 293 294 DeploymentContext context = topLevelDeployments.remove(name); 295 if (context == null) 296 return false; 297 298 removeContext(context); 299 300 return true; 301 } 302 303 public Collection <DeploymentContext> getAll() 304 { 305 return Collections.unmodifiableCollection(allDeployments.values()); 306 } 307 308 public Collection <DeploymentContext> getErrors() 309 { 310 return Collections.unmodifiableCollection(errorDeployments.values()); 311 } 312 313 public Collection <DeploymentContext> getMissingDeployer() 314 { 315 return Collections.unmodifiableCollection(missingDeployers.values()); 316 } 317 318 public Collection <DeploymentContext> getTopLevel() 319 { 320 return Collections.unmodifiableCollection(topLevelDeployments.values()); 321 } 322 323 public void process() 324 { 325 if (shutdown.get()) 326 throw new IllegalStateException ("The main deployer is shutdown"); 327 328 List <DeploymentContext> undeployContexts = null; 329 List <DeploymentContext> deployContexts = null; 330 Deployer[] theDeployers; 331 synchronized (this) 332 { 333 if (deployers.isEmpty()) 334 throw new IllegalStateException ("No deployers"); 335 if (undeploy.isEmpty() == false) 336 { 337 undeployContexts = new ArrayList <DeploymentContext>(undeploy.size()); 339 for (int i = undeploy.size() -1; i >= 0; --i) 340 undeployContexts.add(undeploy.get(i)); 341 undeploy.clear(); 342 } 343 if (deploy.isEmpty() == false) 344 { 345 deployContexts = new ArrayList <DeploymentContext>(deploy); 346 deploy.clear(); 347 } 348 theDeployers = deployers.toArray(new Deployer[deployers.size()]); 349 } 350 351 if (undeployContexts != null) 352 { 353 for (int i = theDeployers.length-1; i >= 0; --i) 354 { 355 Deployer deployer = theDeployers[i]; 356 for (DeploymentContext context : undeployContexts) 357 prepareUndeploy(deployer, context, true); 358 } 359 for (DeploymentContext context : undeployContexts) 360 { 361 context.removeClassLoader(); 363 364 context.setState(UNDEPLOYED); 365 log.debug("Undeployed: " + context.getName()); 366 } 367 } 368 369 if (deployContexts != null) 370 { 371 for (int i = 0; i < theDeployers.length; ++i) 372 { 373 Deployer deployer = theDeployers[i]; 374 375 Set <DeploymentContext> errors = new HashSet <DeploymentContext>(); 376 for (DeploymentContext context : deployContexts) 377 { 378 try 379 { 380 Set <DeploymentContext> components = context.getComponents(); 381 commitDeploy(deployer, context, components); 382 } 383 catch (DeploymentException e) 384 { 385 context.setState(ERROR); 386 context.setProblem(e); 387 errors.add(context); 388 errorDeployments.put(context.getName(), context); 389 for (int j = i-1; j >= 0; --j) 391 { 392 Deployer other = theDeployers[j]; 393 prepareUndeploy(other, context, true); 394 } 395 context.removeClassLoader(); 396 } 397 } 398 deployContexts.removeAll(errors); 399 } 400 for (DeploymentContext context : deployContexts) 401 { 402 String name = context.getName(); 403 boolean isJar = false; 405 VirtualFile root = context.getRoot(); 406 if (root != null && root.getName().endsWith(".jar")) 407 isJar = true; 408 if (context.isDeployed() == false && isJar == false) 409 missingDeployers.put(name, context); 410 context.setState(DEPLOYED); 411 log.debug("Deployed: " + name); 412 } 413 } 414 } 415 416 private void prepareUndeploy(Deployer deployer, DeploymentContext context, boolean doComponents) 417 { 418 DeploymentUnit unit = context.getDeploymentUnit(); 419 deployer.prepareUndeploy(unit); 420 421 if (doComponents) 422 { 423 Set <DeploymentContext> components = context.getComponents(); 424 if (components != null && components.isEmpty() == false) 425 { 426 DeploymentContext[] theComponents = components.toArray(new DeploymentContext[components.size()]); 427 for (int i = theComponents.length-1; i >= 0; --i) 428 prepareUndeploy(deployer, theComponents[i], true); 429 } 430 } 431 } 432 433 private void commitDeploy(Deployer deployer, DeploymentContext context, Set <DeploymentContext> components) throws DeploymentException 434 { 435 DeploymentContext[] theComponents = null; 436 if (components != null && components.isEmpty() == false) 437 theComponents = components.toArray(new DeploymentContext[components.size()]); 438 439 DeploymentUnit unit = context.getDeploymentUnit(); 440 deployer.commitDeploy(unit); 441 442 try 443 { 444 if (theComponents != null) 445 { 446 for (int i = 0; i < theComponents.length; ++i) 447 { 448 try 449 { 450 Set <DeploymentContext> componentComponents = theComponents[i].getComponents(); 451 commitDeploy(deployer, theComponents[i], componentComponents); 452 } 453 catch (DeploymentException e) 454 { 455 for (int j = i-1; j >=0; --j) 457 prepareUndeploy(deployer, theComponents[j], true); 458 throw e; 459 } 460 } 461 } 462 } 463 catch (DeploymentException e) 464 { 465 prepareUndeploy(deployer, context, false); 466 throw e; 467 } 468 } 469 470 public void shutdown() 471 { 472 while (topLevelDeployments.isEmpty() == false) 473 { 474 for (DeploymentContext context : topLevelDeployments.values()) 476 { 477 topLevelDeployments.remove(context.getName()); 478 removeContext(context); 479 } 480 481 process(); 483 } 484 485 shutdown.set(true); 486 } 487 488 494 protected void reset(DeploymentContext context) 495 { 496 if (context == null) 497 throw new IllegalArgumentException ("Null context"); 498 499 if (context.getStructureDetermined() == YES) 500 context.setStructureDetermined(NO); 501 context.setProblem(null); 502 context.reset(); 503 } 504 505 510 private void determineStructure(DeploymentContext context) 511 throws DeploymentException 512 { 513 if (context.getStructureDetermined() == PREDETERMINED) 514 return; 515 516 if (context.getRoot() == null) 517 throw new DeploymentException("Unable to determine structure context has not root " + context.getName()); 518 519 synchronized (this) 520 { 521 if (structureDeployers.isEmpty()) 522 throw new IllegalStateException ("No structure deployers"); 523 } 524 VirtualFile root = context.getRoot(); 525 526 StructureMetaData metaData = new StructureMetaDataImpl(); 528 boolean result = structureDeployers.determineStructure(root, metaData); 529 if (result == false) 530 throw new DeploymentException("No structural deployer recognised the deployment. " + context.getName()); 531 structureBuilder.populateContext(context, metaData); 533 } 534 535 574 575 580 private void addContext(DeploymentContext context) 581 { 582 allDeployments.put(context.getName(), context); 583 if (context.getState() == ERROR) 584 { 585 log.debug("Not scheduling addition of context already in error: " + context.getName()); 586 return; 587 } 588 context.setDeploymentUnit(new AbstractDeploymentUnit(context)); 589 context.setState(DEPLOYING); 590 log.debug("Scheduling deployment: " + context.getName()); 591 deploy.add(context); 592 593 Set <DeploymentContext> children = context.getChildren(); 595 if (children != null) 596 { 597 for (DeploymentContext child : children) 598 addContext(child); 599 } 600 } 601 602 607 private void removeContext(DeploymentContext context) 608 { 609 String name = context.getName(); 610 allDeployments.remove(name); 611 errorDeployments.remove(name); 612 missingDeployers.remove(name); 613 if (context.getState() == ERROR) 614 { 615 log.debug("Not scheduling removal of context already in error: " + name); 616 return; 617 } 618 context.setState(UNDEPLOYING); 619 log.debug("Scheduling undeployment: " + name); 620 undeploy.add(context); 621 622 Set <DeploymentContext> children = context.getChildren(); 624 if (children != null) 625 { 626 for (DeploymentContext child : children) 627 removeContext(child); 628 } 629 } 630 } 631 | Popular Tags |