1 22 package org.jboss.deployment.scanner; 23 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.net.MalformedURLException ; 27 import java.net.URL ; 28 import java.net.URLConnection ; 29 import java.util.ArrayList ; 30 import java.util.Collections ; 31 import java.util.Comparator ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.LinkedList ; 35 import java.util.List ; 36 import java.util.Set ; 37 import java.util.StringTokenizer ; 38 39 import javax.management.MBeanServer ; 40 import javax.management.ObjectName ; 41 42 import org.jboss.deployment.DefaultDeploymentSorter; 43 import org.jboss.deployment.IncompleteDeploymentException; 44 import org.jboss.mx.util.JMXExceptionDecoder; 45 import org.jboss.net.protocol.URLLister; 46 import org.jboss.net.protocol.URLListerFactory; 47 import org.jboss.net.protocol.URLLister.URLFilter; 48 import org.jboss.system.server.ServerConfig; 49 import org.jboss.system.server.ServerConfigLocator; 50 import org.jboss.util.NullArgumentException; 51 import org.jboss.util.StringPropertyReplacer; 52 53 63 public class URLDeploymentScanner extends AbstractDeploymentScanner 64 implements DeploymentScanner, URLDeploymentScannerMBean 65 { 66 67 protected Set skipSet = Collections.synchronizedSet(new HashSet ()); 68 69 70 protected List urlList = Collections.synchronizedList(new ArrayList ()); 71 72 73 protected Set deployedSet = Collections.synchronizedSet(new HashSet ()); 74 75 76 protected URLListerFactory listerFactory = new URLListerFactory(); 77 78 79 protected File serverHome; 80 81 protected URL serverHomeURL; 82 83 86 protected Comparator sorter; 87 88 89 protected URLFilter filter; 90 91 protected IncompleteDeploymentException lastIncompleteDeploymentException; 92 93 94 protected boolean doRecursiveSearch = true; 95 96 99 public void setRecursiveSearch (boolean recurse) 100 { 101 doRecursiveSearch = recurse; 102 } 103 104 107 public boolean getRecursiveSearch () 108 { 109 return doRecursiveSearch; 110 } 111 112 115 public void setURLList(final List list) 116 { 117 if (list == null) 118 throw new NullArgumentException("list"); 119 120 urlList.clear(); 122 123 Iterator iter = list.iterator(); 124 while (iter.hasNext()) 125 { 126 URL url = (URL )iter.next(); 127 if (url == null) 128 throw new NullArgumentException("list element"); 129 130 addURL(url); 131 } 132 133 log.debug("URL list: " + urlList); 134 } 135 136 141 public void setURLComparator(String classname) 142 throws ClassNotFoundException , IllegalAccessException , 143 InstantiationException 144 { 145 sorter = (Comparator )Thread.currentThread().getContextClassLoader().loadClass(classname).newInstance(); 146 } 147 148 151 public String getURLComparator() 152 { 153 if (sorter == null) 154 return null; 155 return sorter.getClass().getName(); 156 } 157 158 163 public void setFilter(String classname) 164 throws ClassNotFoundException , IllegalAccessException , InstantiationException 165 { 166 Class filterClass = Thread.currentThread().getContextClassLoader().loadClass(classname); 167 filter = (URLFilter) filterClass.newInstance(); 168 } 169 170 173 public String getFilter() 174 { 175 if (filter == null) 176 return null; 177 return filter.getClass().getName(); 178 } 179 180 181 186 public void setFilterInstance(URLFilter filter) 187 { 188 this.filter = filter; 189 } 190 191 194 public URLFilter getFilterInstance() 195 { 196 return filter; 197 } 198 199 202 public List getURLList() 203 { 204 return new ArrayList (urlList); 206 } 207 208 211 public void addURL(final URL url) 212 { 213 if (url == null) 214 throw new NullArgumentException("url"); 215 216 try 217 { 218 url.openConnection().connect(); 220 } 221 catch (IOException e) 222 { 223 log.warn("addURL(), caught " + e.getClass().getName() + ": " + e.getMessage()); 225 } 226 urlList.add(url); 227 228 log.debug("Added url: " + url); 229 } 230 231 234 public void removeURL(final URL url) 235 { 236 if (url == null) 237 throw new NullArgumentException("url"); 238 239 boolean success = urlList.remove(url); 240 if (success) 241 { 242 log.debug("Removed url: " + url); 243 } 244 } 245 246 249 public boolean hasURL(final URL url) 250 { 251 if (url == null) 252 throw new NullArgumentException("url"); 253 254 return urlList.contains(url); 255 } 256 257 268 public void suspendDeployment(URL url) 269 { 270 if (url == null) 271 throw new NullArgumentException("url"); 272 273 if (skipSet.add(url)) 274 log.debug("Deployment URL added to skipSet: " + url); 275 else 276 throw new IllegalStateException ("Deployment URL already suspended: " + url); 277 } 278 279 288 public void resumeDeployment(URL url, boolean markUpToDate) 289 { 290 if (url == null) 291 throw new NullArgumentException("url"); 292 293 if (skipSet.contains(url)) 294 { 295 if (markUpToDate) 296 { 297 for (Iterator i = deployedSet.iterator(); i.hasNext(); ) 299 { 300 DeployedURL deployedURL = (DeployedURL)i.next(); 301 if (deployedURL.url.equals(url)) 302 { 303 log.debug("Marking up-to-date: " + url); 305 deployedURL.deployed(); 306 break; 307 } 308 } 309 } 310 skipSet.remove(url); 312 log.debug("Deployment URL removed from skipSet: " + url); 313 } 314 else 315 { 316 throw new IllegalStateException ("Deployment URL not suspended: " + url); 317 } 318 } 319 320 325 public String listDeployedURLs() 326 { 327 StringBuffer sbuf = new StringBuffer (); 328 for (Iterator i = deployedSet.iterator(); i.hasNext(); ) 329 { 330 URL url = ((DeployedURL)i.next()).url; 331 if (sbuf.length() > 0) 332 { 333 sbuf.append("\n").append(url); 334 } 335 else 336 { 337 sbuf.append(url); 338 } 339 } 340 return sbuf.toString(); 341 } 342 343 347 350 public void setURLs(final String listspec) throws MalformedURLException 351 { 352 if (listspec == null) 353 throw new NullArgumentException("listspec"); 354 355 List list = new LinkedList (); 356 357 StringTokenizer stok = new StringTokenizer (listspec, ","); 358 while (stok.hasMoreTokens()) 359 { 360 String urlspec = stok.nextToken().trim(); 361 log.debug("Adding URL from spec: " + urlspec); 362 363 URL url = makeURL(urlspec); 364 log.debug("URL: " + url); 365 366 list.add(url); 367 } 368 369 setURLList(list); 370 } 371 372 375 protected URL makeURL(String urlspec) throws MalformedURLException 376 { 377 urlspec = StringPropertyReplacer.replaceProperties (urlspec); 380 return new URL (serverHomeURL, urlspec); 381 } 382 383 386 public void addURL(final String urlspec) throws MalformedURLException 387 { 388 addURL(makeURL(urlspec)); 389 } 390 391 394 public void removeURL(final String urlspec) throws MalformedURLException 395 { 396 removeURL(makeURL(urlspec)); 397 } 398 399 402 public boolean hasURL(final String urlspec) throws MalformedURLException 403 { 404 return hasURL(makeURL(urlspec)); 405 } 406 407 410 protected void deploy(final DeployedURL du) 411 { 412 if (deployer == null) 414 return; 415 416 try 417 { 418 if (log.isTraceEnabled()) 419 log.trace("Deploying: " + du); 420 421 deployer.deploy(du.url); 422 } 423 catch (IncompleteDeploymentException e) 424 { 425 lastIncompleteDeploymentException = e; 426 } 427 catch (Exception e) 428 { 429 log.debug("Failed to deploy: " + du, e); 430 } 431 432 du.deployed(); 433 434 if (!deployedSet.contains(du)) 435 { 436 deployedSet.add(du); 437 } 438 } 439 440 443 protected void undeploy(final DeployedURL du) 444 { 445 try 446 { 447 if (log.isTraceEnabled()) 448 log.trace("Undeploying: " + du); 449 450 deployer.undeploy(du.url); 451 deployedSet.remove(du); 452 } 453 catch (Exception e) 454 { 455 log.error("Failed to undeploy: " + du, e); 456 } 457 } 458 459 462 protected boolean isDeployed(final URL url) 463 { 464 DeployedURL du = new DeployedURL(url); 465 return deployedSet.contains(du); 466 } 467 468 public synchronized void scan() throws Exception 469 { 470 lastIncompleteDeploymentException = null; 471 if (urlList == null) 472 throw new IllegalStateException ("not initialized"); 473 474 updateSorter(); 475 476 boolean trace = log.isTraceEnabled(); 477 List urlsToDeploy = new LinkedList (); 478 479 if (trace) 481 { 482 log.trace("Scanning for new deployments"); 483 } 484 synchronized (urlList) 485 { 486 for (Iterator i = urlList.iterator(); i.hasNext();) 487 { 488 URL url = (URL ) i.next(); 489 try 490 { 491 if (url.toString().endsWith("/")) 492 { 493 URLLister lister = listerFactory.createURLLister(url); 495 496 urlsToDeploy.addAll(lister.listMembers(url, filter, doRecursiveSearch)); 498 } 499 else 500 { 501 503 url.openConnection().connect(); 505 urlsToDeploy.add(url); 506 } 507 } 508 catch (IOException e) 509 { 510 log.warn("Scan URL, caught " + e.getClass().getName() + ": " + e.getMessage()); 515 516 return; 523 } 524 } 525 } 526 527 if (trace) 528 { 529 log.trace("Updating existing deployments"); 530 } 531 LinkedList urlsToRemove = new LinkedList (); 532 LinkedList urlsToCheckForUpdate = new LinkedList (); 533 synchronized (deployedSet) 534 { 535 for (Iterator i = deployedSet.iterator(); i.hasNext();) 537 { 538 DeployedURL deployedURL = (DeployedURL) i.next(); 539 540 if (skipSet.contains(deployedURL.url)) 541 { 542 if (trace) 543 log.trace("Skipping update/removal check for: " + deployedURL.url); 544 } 545 else 546 { 547 if (urlsToDeploy.contains(deployedURL.url)) 548 { 549 urlsToCheckForUpdate.add(deployedURL); 550 } 551 else 552 { 553 urlsToRemove.add(deployedURL); 554 } 555 } 556 } 557 } 558 559 563 for (Iterator i = urlsToRemove.iterator(); i.hasNext();) 564 { 565 DeployedURL deployedURL = (DeployedURL) i.next(); 566 if (trace) 567 { 568 log.trace("Removing " + deployedURL.url); 569 } 570 undeploy(deployedURL); 571 } 572 573 577 ArrayList urlsToUpdate = new ArrayList (urlsToCheckForUpdate.size()); 579 for (Iterator i = urlsToCheckForUpdate.iterator(); i.hasNext();) 580 { 581 DeployedURL deployedURL = (DeployedURL) i.next(); 582 if (deployedURL.isModified()) 583 { 584 if (trace) 585 { 586 log.trace("Re-deploying " + deployedURL.url); 587 } 588 urlsToUpdate.add(deployedURL); 589 } 590 } 591 592 Collections.sort(urlsToUpdate, new Comparator () 594 { 595 public int compare(Object o1, Object o2) 596 { 597 return sorter.compare(((DeployedURL) o1).url, ((DeployedURL) o2).url); 598 } 599 }); 600 601 for (int i = urlsToUpdate.size() - 1; i >= 0;i--) 603 { 604 undeploy((DeployedURL) urlsToUpdate.get(i)); 605 } 606 607 for (int i = 0; i < urlsToUpdate.size();i++) 609 { 610 deploy((DeployedURL) urlsToUpdate.get(i)); 611 } 612 613 617 Collections.sort(urlsToDeploy, sorter); 618 for (Iterator i = urlsToDeploy.iterator(); i.hasNext();) 619 { 620 URL url = (URL ) i.next(); 621 DeployedURL deployedURL = new DeployedURL(url); 622 if (deployedSet.contains(deployedURL) == false) 623 { 624 if (skipSet.contains(url)) 625 { 626 if (trace) 627 log.trace("Skipping deployment of: " + url); 628 } 629 else 630 { 631 if (trace) 632 log.trace("Deploying " + deployedURL.url); 633 634 deploy(deployedURL); 635 } 636 } 637 i.remove(); 638 if (i.hasNext() && updateSorter()) 641 { 642 Collections.sort(urlsToDeploy, sorter); 643 i = urlsToDeploy.iterator(); 644 } 645 } 646 647 if (lastIncompleteDeploymentException != null) 649 { 650 try 651 { 652 Object [] args = {}; 653 String [] sig = {}; 654 getServer().invoke(getDeployer(), 655 "checkIncompleteDeployments", args, sig); 656 } 657 catch (Exception e) 658 { 659 Throwable t = JMXExceptionDecoder.decode(e); 660 log.error(t); 661 } 662 } 663 } 664 665 protected boolean updateSorter() 666 { 667 if (sorter instanceof DefaultDeploymentSorter) 669 { 670 DefaultDeploymentSorter defaultSorter = (DefaultDeploymentSorter)sorter; 671 if (defaultSorter.getSuffixOrder() != mainDeployer.getSuffixOrder()) 672 { 673 defaultSorter.setSuffixOrder(mainDeployer.getSuffixOrder()); 674 return true; 675 } 676 } 677 return false; 678 } 679 680 684 public ObjectName preRegister(MBeanServer server, ObjectName name) 685 throws Exception 686 { 687 ServerConfig serverConfig = ServerConfigLocator.locate(); 690 serverHome = serverConfig.getServerHomeDir(); 691 serverHomeURL = serverConfig.getServerHomeURL(); 692 693 return super.preRegister(server, name); 694 } 695 696 protected void createService() throws Exception 697 { 698 if (this.filter == null) 700 { 701 throw new IllegalStateException ("'FilterInstance' attribute not configured"); 702 } 703 if (this.sorter == null) 704 { 705 throw new IllegalStateException ("'URLComparator' attribute not configured"); 706 } 707 super.createService(); 709 } 710 711 715 719 protected class DeployedURL 720 { 721 public URL url; 722 723 public URL watchUrl; 724 725 public long deployedLastModified; 726 727 public DeployedURL(final URL url) 728 { 729 this.url = url; 730 } 731 732 public void deployed() 733 { 734 deployedLastModified = getLastModified(); 735 } 736 public boolean isFile() 737 { 738 return url.getProtocol().equals("file"); 739 } 740 741 public File getFile() 742 { 743 return new File (url.getFile()); 744 } 745 746 public boolean isRemoved() 747 { 748 if (isFile()) 749 { 750 File file = getFile(); 751 return !file.exists(); 752 } 753 return false; 754 } 755 756 public long getLastModified() 757 { 758 if (watchUrl == null) 759 { 760 try 761 { 762 Object o = getServer().invoke( 763 getDeployer(), 764 "getWatchUrl", 765 new Object [] { url }, 766 new String [] { URL .class.getName() } 767 ); 768 watchUrl = o == null ? url : (URL )o; 769 getLog().debug("Watch URL for: " + url + " -> " + watchUrl); 770 } 771 catch (Exception e) 772 { 773 watchUrl = url; 774 getLog().debug("Unable to obtain watchUrl from deployer. Use url: " + url, e); 775 } 776 } 777 778 try 779 { 780 URLConnection connection; 781 if (watchUrl != null) 782 { 783 connection = watchUrl.openConnection(); 784 } 785 else 786 { 787 connection = url.openConnection(); 788 } 789 long lastModified = connection.getLastModified(); 793 794 return lastModified; 795 } 796 catch (java.io.IOException e) 797 { 798 log.warn("Failed to check modification of deployed url: " + url, e); 799 } 800 return -1; 801 } 802 803 public boolean isModified() 804 { 805 long lastModified = getLastModified(); 806 if (lastModified == -1) 807 { 808 return false; 810 } 811 return deployedLastModified != lastModified; 812 } 813 814 public int hashCode() 815 { 816 return url.hashCode(); 817 } 818 819 public boolean equals(final Object other) 820 { 821 if (other instanceof DeployedURL) 822 { 823 return ((DeployedURL)other).url.equals(this.url); 824 } 825 return false; 826 } 827 828 public String toString() 829 { 830 return super.toString() + 831 "{ url=" + url + 832 ", deployedLastModified=" + deployedLastModified + 833 " }"; 834 } 835 } 836 } 837 | Popular Tags |