1 19 20 21 package org.netbeans.modules.j2ee.deployment.impl; 22 23 import java.util.concurrent.CountDownLatch ; 24 import java.util.concurrent.TimeUnit ; 25 import java.util.concurrent.atomic.AtomicBoolean ; 26 import org.openide.filesystems.FileUtil; 27 28 import javax.enterprise.deploy.shared.ModuleType ; 29 import javax.enterprise.deploy.shared.StateType ; 30 import javax.enterprise.deploy.spi.*; 31 import javax.enterprise.deploy.spi.status.*; 32 import javax.enterprise.deploy.spi.exceptions.*; 33 import org.netbeans.modules.j2ee.deployment.plugins.api.*; 34 import org.netbeans.modules.j2ee.deployment.devmodules.api.*; 35 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; 36 import org.openide.ErrorManager; 37 import org.netbeans.modules.j2ee.deployment.execution.DeploymentTarget; 38 import org.netbeans.modules.j2ee.deployment.execution.DeploymentConfigurationProvider; 39 import org.openide.util.NbBundle; 40 import org.openide.filesystems.FileObject; 41 42 import java.util.*; 43 import java.io.*; 44 import javax.enterprise.deploy.model.DeployableObject ; 45 import org.netbeans.modules.j2ee.deployment.impl.ui.ProgressUI; 46 47 59 public class TargetServer { 60 61 private static final long DISTRIBUTE_TIMEOUT = 120000; 62 private static final long INCREMENTAL_TIMEOUT = 60000; 63 private static final long TIMEOUT = 60000; 64 65 private Target[] targets; 66 private final ServerInstance instance; 67 private final DeploymentTarget dtarget; 68 private IncrementalDeployment incremental; private boolean debugMode = false; 70 private Map availablesMap = null; 71 private Set deployedRootTMIDs = new HashSet(); private Set undeployTMIDs = new HashSet(); private Set distributeTargets = new HashSet(); private TargetModule[] redeployTargetModules = null; 75 private File application = null; 76 private File currentContentDir = null; 77 private String contextRoot = null; 78 79 public TargetServer(DeploymentTarget target) { 80 this.dtarget = target; 81 this.instance = dtarget.getServer().getServerInstance(); 82 } 83 84 private void init(ProgressUI ui) throws ServerException { 85 if (targets == null) { 86 instance.start(ui); 87 targets = dtarget.getServer().toTargets(); 88 } 89 incremental = instance.getIncrementalDeployment(); 90 if (incremental != null && ! checkServiceImplementations()) 91 incremental = null; 92 93 try { 94 FileObject contentFO = dtarget.getModule().getContentDirectory(); 95 if (contentFO != null) { 96 currentContentDir = FileUtil.toFile(contentFO); 97 } 98 99 } catch (IOException ioe) { 100 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe); 101 } 102 103 J2eeModuleProvider.ConfigSupport configSupport = dtarget.getConfigSupport(); 104 if (J2eeModule.WAR.equals(dtarget.getModule().getModuleType())) { 105 contextRoot = configSupport.getWebContextRoot(); 106 } 107 108 processLastTargetModules(); 109 } 110 111 private boolean canFileDeploy(Target[] targetz, DeployableObject deployable) { 112 if (targetz == null || targetz.length != 1) { 113 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, NbBundle.getMessage( 114 TargetServer.class, "MSG_MoreThanOneIncrementalTargets")); 115 return false; 116 } 117 118 if (deployable == null || !instance.getIncrementalDeployment().canFileDeploy(targetz[0], deployable)) 119 return false; 120 121 return true; 122 } 123 124 private boolean canFileDeploy(TargetModule[] targetModules, DeployableObject deployable) { 125 if (targetModules == null || targetModules.length != 1) { 126 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, NbBundle.getMessage( 127 TargetServer.class, "MSG_MoreThanOneIncrementalTargets")); 128 return false; 129 } 130 131 if (deployable == null || !instance.getIncrementalDeployment().canFileDeploy(targetModules[0].getTarget(), deployable)) 132 return false; 133 134 return true; 135 } 136 137 private AppChangeDescriptor distributeChanges(TargetModule targetModule, ProgressUI ui) throws IOException { 138 ServerFileDistributor sfd = new ServerFileDistributor(instance, dtarget); 139 try { 140 ui.setProgressObject(sfd); 141 ModuleChangeReporter mcr = dtarget.getModuleChangeReporter(); 142 AppChangeDescriptor acd = sfd.distribute(targetModule, mcr); 143 return acd; 144 } finally { 145 ui.setProgressObject(null); 146 } 147 } 148 149 private File initialDistribute(Target target, ProgressUI ui) { 150 InitialServerFileDistributor sfd = new InitialServerFileDistributor(dtarget, target); 151 try { 152 ui.setProgressObject(sfd); 153 return sfd.distribute(); 154 } finally { 155 ui.setProgressObject(null); 156 } 157 } 158 159 private boolean checkServiceImplementations() { 160 String missing = null; 161 if (instance.getServer().getConfigurationSupport() == null) { 162 missing = ConfigurationSupport.class.getName(); 163 } 164 165 if (missing != null) { 166 String msg = NbBundle.getMessage(ServerFileDistributor.class, "MSG_MissingServiceImplementations", missing); 167 ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, msg); 168 return false; 169 } 170 171 return true; 172 } 173 174 private TargetModule[] checkUndeployForChangedReferences(Set toRedeploy) { 176 if (dtarget.getModule().getModuleType() == J2eeModule.WAR) { 178 for (Iterator j=toRedeploy.iterator(); j.hasNext();) { 179 TargetModule deployed = (TargetModule) j.next(); 180 File lastContentDir = (deployed.getContentDirectory() == null) ? null : new File(deployed.getContentDirectory()); 181 182 if ((currentContentDir != null && ! currentContentDir.equals(lastContentDir)) || 184 (contextRoot != null && ! contextRoot.equals(deployed.getContextRoot()))) { 185 186 distributeTargets.add(deployed.findTarget()); 187 undeployTMIDs.add(deployed.delegate()); 188 deployed.remove(); 189 j.remove(); 190 } 191 } 192 } 193 194 return (TargetModule[]) toRedeploy.toArray(new TargetModule[toRedeploy.size()]); 195 } 196 197 private TargetModule[] checkUndeployForSharedReferences(Target[] toDistribute) { 199 Set distSet = new HashSet(Arrays.asList(toDistribute)); 200 return checkUndeployForSharedReferences(Collections.EMPTY_SET, distSet); 201 } 202 private TargetModule[] checkUndeployForSharedReferences(Set toRedeploy, Set toDistribute) { 203 return checkUndeployForSharedReferences(toRedeploy, toDistribute, null); 204 } 205 private TargetModule[] checkUndeployForSharedReferences(Set toRedeploy, Set toDistribute, Map queryInfo) { 206 if (contextRoot == null || (toRedeploy.isEmpty() && toDistribute.isEmpty())) { 208 return (TargetModule[]) toRedeploy.toArray(new TargetModule[toRedeploy.size()]); 209 } 210 211 Set allTargets = new HashSet(Arrays.asList(TargetModule.toTarget((TargetModule[]) toRedeploy.toArray(new TargetModule[toRedeploy.size()])))); 212 allTargets.addAll(toDistribute); 213 Target[] targs = (Target[]) allTargets.toArray(new Target[allTargets.size()]); 214 215 boolean shared = false; 216 List addToDistributeWhenSharedDetected = new ArrayList(); 217 List removeFromRedeployWhenSharedDetected = new ArrayList(); 218 List addToUndeployWhenSharedDetected = new ArrayList(); 219 List sharerTMIDs; 220 221 TargetModuleIDResolver tmidResolver = instance.getTargetModuleIDResolver(); 222 if (tmidResolver != null) { 223 if (queryInfo == null) { 224 queryInfo = new HashMap(); 225 queryInfo.put(TargetModuleIDResolver.KEY_CONTEXT_ROOT, contextRoot); 226 } 227 228 TargetModuleID[] haveSameReferences = TargetModule.EMPTY_TMID_ARRAY; 229 if (targs.length > 0) { 230 haveSameReferences = tmidResolver.lookupTargetModuleID(queryInfo, targs); 231 } 232 for (int i=0; i<haveSameReferences.length; i++) { 233 haveSameReferences[i] = new TargetModule(keyOf(haveSameReferences[i]), haveSameReferences[i]); 234 } 235 sharerTMIDs = Arrays.asList(haveSameReferences); 236 237 for (Iterator i=sharerTMIDs.iterator(); i.hasNext();) { 238 TargetModule sharer = (TargetModule) i.next(); 239 if ((toRedeploy.size() > 0 && ! toRedeploy.contains(sharer)) || 240 toDistribute.contains(sharer.getTarget())) { 241 shared = true; 242 addToUndeployWhenSharedDetected.add(sharer.delegate()); 243 } else { 244 removeFromRedeployWhenSharedDetected.add(sharer); 245 addToDistributeWhenSharedDetected.add(sharer.getTarget()); 246 } 247 } 248 } 249 250 if (!shared) { 253 sharerTMIDs = TargetModule.findByContextRoot(dtarget.getServer(), contextRoot); 254 sharerTMIDs = TargetModule.initDelegate(sharerTMIDs, getAvailableTMIDsMap()); 255 256 for (Iterator i=sharerTMIDs.iterator(); i.hasNext();) { 257 TargetModule sharer = (TargetModule) i.next(); 258 boolean redeployHasSharer = false; 259 for (Iterator j=toRedeploy.iterator(); j.hasNext();) { 260 TargetModule redeploying = (TargetModule) j.next(); 261 if (redeploying.equals(sharer) && redeploying.getContentDirectory().equals(sharer.getContentDirectory())) { 262 redeployHasSharer = true; 263 break; 264 } 265 } 266 if (! redeployHasSharer || 267 toDistribute.contains(sharer.getTarget())) { 268 shared = true; 269 addToUndeployWhenSharedDetected.add(sharer.delegate()); 270 } else { 271 removeFromRedeployWhenSharedDetected.add(sharer); 272 addToDistributeWhenSharedDetected.add(sharer.getTarget()); 273 } 274 } 275 } 276 277 if (shared) { 278 undeployTMIDs.addAll(addToUndeployWhenSharedDetected); 279 TargetModule.removeByContextRoot(dtarget.getServer(), contextRoot); 281 toRedeploy.removeAll(removeFromRedeployWhenSharedDetected); 283 distributeTargets.addAll(addToDistributeWhenSharedDetected); 284 } 285 286 return (TargetModule[]) toRedeploy.toArray(new TargetModule[toRedeploy.size()]); 287 } 288 289 private Map getAvailableTMIDsMap() { 290 if (availablesMap != null) 291 return availablesMap; 292 293 DeploymentManager dm = instance.getDeploymentManager(); 295 availablesMap = new HashMap(); 296 try { 297 ModuleType type = (ModuleType ) dtarget.getModule().getModuleType(); 298 TargetModuleID[] ids = dm.getAvailableModules(type, targets); 299 if (ids == null) { 300 return availablesMap; 301 } 302 for (int i=0; i<ids.length; i++) { 303 availablesMap.put(keyOf(ids[i]), ids[i]); 304 } 305 } catch (TargetException te) { 306 throw (IllegalArgumentException ) ErrorManager.getDefault().annotate(new IllegalArgumentException (), te); 307 } 308 return availablesMap; 309 } 310 311 314 private void processLastTargetModules() { 315 TargetModule[] targetModules = dtarget.getTargetModules(); 316 317 if (targetModules == null || targetModules.length == 0) { 319 distributeTargets.addAll(Arrays.asList(targets)); 320 checkUndeployForSharedReferences(targets); 321 return; 322 } 323 324 Set targetNames = new HashSet(); 325 for (int i=0; i<targets.length; i++) targetNames.add(targets[i].getName()); 326 327 Set toRedeploy = new HashSet(); for (int i=0; i<targetModules.length; i++) { 329 if (! targetModules[i].getInstanceUrl().equals(instance.getUrl()) || 331 ! targetNames.contains(targetModules[i].getTargetName())) 332 continue; 333 334 TargetModuleID tmID = (TargetModuleID) getAvailableTMIDsMap().get(targetModules[i].getId()); 335 336 if (tmID == null) { 338 Target target = targetModules[i].findTarget(); 339 if (target != null) 340 distributeTargets.add(target); 341 } else { 342 targetModules[i].initDelegate(tmID); 343 toRedeploy.add(targetModules[i]); 344 } 345 } 346 347 DeploymentManager dm = instance.getDeploymentManager(); 348 349 if (incremental == null && getApplication() == null) { 351 toRedeploy = Collections.EMPTY_SET; 352 } else if (incremental == null) { 353 long lastModified = getApplication().lastModified(); 354 for (Iterator j=toRedeploy.iterator(); j.hasNext();) { 355 TargetModule deployed = (TargetModule) j.next(); 356 if (lastModified >= deployed.getTimestamp()) { 357 if (! dm.isRedeploySupported()) { 359 distributeTargets.add(deployed.findTarget()); 360 undeployTMIDs.add(deployed.delegate()); 361 j.remove(); 362 } 363 } else { 364 j.remove(); 366 } 367 } 368 } 369 370 redeployTargetModules = checkUndeployForChangedReferences(toRedeploy); 371 Set targetSet = new HashSet(distributeTargets); 372 redeployTargetModules = checkUndeployForSharedReferences(toRedeploy, targetSet); 373 } 374 375 private File getApplication() { 376 if (application != null) return application; 377 try { 378 FileObject archiveFO = dtarget.getModule().getArchive(); 379 if (archiveFO == null) return null; 380 application = FileUtil.toFile(archiveFO); 381 return application; 382 } catch (IOException ioe) { 383 ErrorManager.getDefault().log(ErrorManager.EXCEPTION, ioe.getMessage()); 384 return null; 385 } 386 } 387 388 public void startTargets(boolean debugMode, ProgressUI ui) throws ServerException { 389 this.debugMode = debugMode; 390 if (instance.getStartServer().isAlsoTargetServer(null)) { 391 if (debugMode) { 392 instance.startDebug(ui); 393 } else { 394 instance.start(ui); 395 } 396 this.targets = dtarget.getServer().toTargets(); 397 return; 398 } 399 instance.start(ui); 400 this.targets = dtarget.getServer().toTargets(); 401 if (debugMode) { 402 for (int i=0; i<targets.length; i++) { 403 instance.startDebugTarget(targets[i], ui); 404 } 405 } else { 406 for (int i=0; i<targets.length; i++) { 407 instance.startTarget(targets[i], ui); 408 } 409 } 410 } 411 412 private static String keyOf(TargetModuleID tmid) { 413 418 return tmid.toString(); 419 } 420 421 private TargetModuleID[] saveRootTargetModules(TargetModuleID [] modules) { 423 long timestamp = System.currentTimeMillis(); 424 425 Set originals = new HashSet(); 426 for (int i=0; i<modules.length; i++) { 427 if (modules[i].getParentTargetModuleID() == null) { 428 String id = keyOf(modules[i]); 429 String targetName = modules[i].getTarget().getName(); 430 String fromDir = ""; 431 if (null != currentContentDir) 432 fromDir = currentContentDir.getAbsolutePath(); 433 TargetModule tm = new TargetModule(id, instance.getUrl(), timestamp, fromDir, contextRoot, modules[i]); 434 deployedRootTMIDs.add(tm); 435 originals.add(modules[i]); 436 } 437 } 438 return (TargetModuleID[]) originals.toArray(new TargetModuleID[originals.size()]); 439 } 440 441 public TargetModule[] deploy(ProgressUI ui, boolean forceRedeploy) throws IOException, ServerException { 442 ProgressObject po = null; 443 boolean hasActivities = false; 444 445 init(ui); 446 if (forceRedeploy) { 447 if (redeployTargetModules == null) { 448 } else { 449 for (int i = 0; i < redeployTargetModules.length; i++) { 450 distributeTargets.add(redeployTargetModules [i].findTarget ()); 451 undeployTMIDs.add(redeployTargetModules [i].delegate()); 452 redeployTargetModules [i].remove(); 453 } 454 redeployTargetModules = null; 455 } 456 } 457 458 File plan = null; 459 DeployableObject deployable = null; 460 DeploymentConfigurationProvider dcp = dtarget.getDeploymentConfigurationProvider(); 461 if (dcp != null) 462 deployable = dcp.getDeployableObject(null); 463 boolean hasDirectory = (dtarget.getModule().getContentDirectory() != null); 464 465 if (undeployTMIDs.size() > 0) { 467 TargetModuleID[] tmIDs = (TargetModuleID[]) undeployTMIDs.toArray(new TargetModuleID[undeployTMIDs.size()]); 468 ui.progress(NbBundle.getMessage(TargetServer.class, "MSG_Undeploying")); 469 ProgressObject undeployPO = instance.getDeploymentManager().undeploy(tmIDs); 470 trackProgressObject(ui, undeployPO, TIMEOUT); 471 } 472 473 if (distributeTargets.size() > 0) { 475 hasActivities = true; 476 Target[] targetz = (Target[]) distributeTargets.toArray(new Target[distributeTargets.size()]); 477 478 if (incremental != null && hasDirectory && canFileDeploy(targetz, deployable)) { 479 DeploymentConfiguration cfg = dtarget.getDeploymentConfigurationProvider().getDeploymentConfiguration(); 480 File dir = initialDistribute(targetz[0], ui); 481 po = incremental.initialDeploy(targetz[0], deployable, cfg, dir); 482 trackDeployProgressObject(ui, po, false); 483 } else { if (getApplication() == null) { 485 throw new RuntimeException (NbBundle.getMessage(TargetServer.class, "MSG_NoArchive")); 486 } 487 488 ui.progress(NbBundle.getMessage(TargetServer.class, "MSG_Distributing", application, Arrays.asList(targetz))); 489 plan = dtarget.getConfigurationFile(); 490 po = instance.getDeploymentManager().distribute(targetz, getApplication(), plan); 491 trackDeployProgressObject(ui, po, false); 492 } 493 } 494 495 if (redeployTargetModules != null && redeployTargetModules.length > 0) { 497 hasActivities = true; 498 if (incremental != null && hasDirectory && canFileDeploy(redeployTargetModules, deployable)) { 499 AppChangeDescriptor acd = distributeChanges(redeployTargetModules[0], ui); 500 if (anyChanged(acd)) { 501 ui.progress(NbBundle.getMessage(TargetServer.class, "MSG_IncrementalDeploying", redeployTargetModules[0])); 502 po = incremental.incrementalDeploy(redeployTargetModules[0].delegate(), acd); 503 trackDeployProgressObject(ui, po, true); 504 505 } else { return dtarget.getTargetModules(); 507 } 508 } else { if (getApplication() == null) 510 throw new IllegalArgumentException (NbBundle.getMessage(TargetServer.class, "MSG_NoArchive")); 511 512 ui.progress(NbBundle.getMessage(TargetServer.class, "MSG_Redeploying", application)); 513 TargetModuleID[] tmids = TargetModule.toTargetModuleID(redeployTargetModules); 514 if (plan == null) plan = dtarget.getConfigurationFile(); 515 po = instance.getDeploymentManager().redeploy(tmids, getApplication(), plan); 516 trackDeployProgressObject(ui, po, false); 517 } 518 } 519 520 if (hasActivities) { 521 return (TargetModule[]) deployedRootTMIDs.toArray(new TargetModule[deployedRootTMIDs.size()]); 522 } else { 523 return dtarget.getTargetModules(); 524 } 525 } 526 527 533 public void notifyIncrementalDeployment(TargetModuleID[] modules) { 534 if (modules != null && incremental != null) { 535 for (int i = 0; i < modules.length; i++) { 536 incremental.notifyDeployment(modules[i]); 537 } 538 } 539 } 540 541 public static boolean anyChanged(AppChangeDescriptor acd) { 542 return (acd.manifestChanged() || acd.descriptorChanged() || acd.classesChanged() 543 || acd.ejbsChanged() || acd.serverDescriptorChanged()); 544 } 545 546 555 private void trackDeployProgressObject(ProgressUI ui, ProgressObject po, boolean incremental) { 556 boolean completed = trackProgressObject(ui, po, incremental ? INCREMENTAL_TIMEOUT : DISTRIBUTE_TIMEOUT); 557 if (completed) { 558 TargetModuleID[] modules = po.getResultTargetModuleIDs(); 559 modules = saveRootTargetModules(modules); 560 if (!incremental) { 561 ProgressObject startPO = instance.getDeploymentManager().start(modules); 563 trackProgressObject(ui, startPO, TIMEOUT); 564 } 565 } 566 } 567 568 578 private boolean trackProgressObject(ProgressUI ui, final ProgressObject po, long timeout) { 579 final AtomicBoolean completed = new AtomicBoolean (); 580 ui.setProgressObject(po); 581 try { 582 final CountDownLatch progressFinished = new CountDownLatch (1); 583 ProgressListener listener = new ProgressListener() { 584 public void handleProgressEvent(ProgressEvent progressEvent) { 585 DeploymentStatus status = progressEvent.getDeploymentStatus(); 586 if (status.isCompleted()) { 587 completed.set(true); 588 } 589 if (status.isCompleted() || status.isFailed()) { 590 progressFinished.countDown(); 591 } 592 } 593 }; 594 po.addProgressListener(listener); 595 try { 596 DeploymentStatus status = po.getDeploymentStatus(); 599 if (!status.isCompleted() && !status.isFailed()) { 600 try { 601 progressFinished.await(timeout, TimeUnit.MILLISECONDS); 602 } catch (InterruptedException e) { 603 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 604 } 605 } else if (status.isCompleted()) { 606 completed.set(true); 607 } 608 } finally { 609 po.removeProgressListener(listener); 610 } 611 } finally { 612 ui.setProgressObject(null); 613 } 614 return completed.get(); 615 } 616 } 617 | Popular Tags |