1 9 10 package org.jboss.deployment.scanner; 11 12 import java.io.File ; 13 import java.io.FileFilter ; 14 import java.io.IOException ; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.net.URLConnection ; 18 import java.util.Arrays ; 19 import java.util.ArrayList ; 20 import java.util.Comparator ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import javax.management.MBeanServer ; 24 import javax.management.ObjectName ; 25 import org.w3c.dom.Element ; 26 import org.w3c.dom.NamedNodeMap ; 27 import org.w3c.dom.Node ; 28 import org.w3c.dom.NodeList ; 29 30 import org.jboss.deployment.Deployer; 31 import org.jboss.deployment.DeploymentException; 32 import org.jboss.system.server.ServerConfigLocator; 33 34 46 public class URLDirectoryScanner extends AbstractDeploymentScanner 47 implements DeploymentScanner, URLDirectoryScannerMBean 48 { 49 50 51 private FileFilter defaultFilter; 52 53 54 private Comparator defaultComparator; 55 56 57 private ArrayList scanners = new ArrayList (); 58 59 60 private HashMap urlScannerMap = new HashMap (); 61 62 63 private File serverHome; 64 65 68 public void addScanURL(URL url) 69 { 70 Scanner scanner = new Scanner(url); 71 addScanner(scanner); 72 } 73 74 77 public void addScanURL(String url) throws MalformedURLException 78 { 79 addScanURL(toUrl(url)); 80 } 81 82 85 public void addScanDir(URL url, Comparator comp, FileFilter filter) 86 { 87 Scanner scanner = new DirScanner(url, comp, filter); 88 addScanner(scanner); 89 } 90 91 94 public void addScanDir(String urlSpec, String compClassName, String filterClassName) 95 throws MalformedURLException 96 { 97 98 URL url = toUrl(urlSpec); 99 Comparator comp = null; 101 if (compClassName != null) 102 { 103 try 104 { 105 Class compClass = Thread.currentThread().getContextClassLoader().loadClass("compClassName"); 106 comp = (Comparator )compClass.newInstance(); 107 } catch (Exception e) 108 { 109 log.warn("Unable to create instance of Comparator. Ignoring.", e); 110 } 111 } 112 FileFilter filter = null; 114 if (filterClassName != null) 115 { 116 try 117 { 118 Class filterClass = Thread.currentThread().getContextClassLoader().loadClass(filterClassName); 119 filter = (FileFilter )filterClass.newInstance(); 120 } catch (Exception e) 121 { 122 log.warn("Unable to create instance of Filter. Ignoring.", e); 123 } 124 } 125 126 addScanDir(url, comp, filter); 127 } 128 129 private void addScanner(Scanner scanner) 130 { 131 synchronized (scanners) 132 { 133 if (isScanEnabled()) 134 { 135 ArrayList localScanners = new ArrayList (scanners); 138 HashMap localMap = new HashMap (urlScannerMap); 139 140 localScanners.add(scanner); 141 localMap.put(scanner.url, scanner); 142 143 scanners = localScanners; 144 urlScannerMap = localMap; 145 } else 146 { 147 scanners.add(scanner); 149 urlScannerMap.put(scanner.url, scanner); 150 } 151 } 152 } 153 154 157 public void removeScanURL(URL url) 158 { 159 synchronized (scanners) 160 { 161 if (isScanEnabled()) 162 { 163 ArrayList localScanners = new ArrayList (scanners); 166 HashMap localMap = new HashMap (urlScannerMap); 167 168 Scanner scanner = (Scanner)localMap.remove(url); 169 if (scanner != null) 170 { 171 localScanners.remove(scanner); 172 } 173 174 scanners = localScanners; 175 urlScannerMap = localMap; 176 } else 177 { 178 Scanner scanner = (Scanner)urlScannerMap.remove(url); 180 if (scanner != null) 181 { 182 scanners.remove(scanner); 183 } 184 } 185 } 186 } 187 188 191 public void setURLs(Element elem) 192 { 193 ArrayList localScanners = new ArrayList (); 195 HashMap localMap = new HashMap (); 196 197 NodeList list = elem.getChildNodes(); 198 synchronized (scanners) 199 { 200 scanners.clear(); 202 urlScannerMap.clear(); 203 204 for (int i = 0; i < list.getLength(); i++) 206 { 207 Node node = list.item(i); 208 if (node.getNodeType() == Node.ELEMENT_NODE) { 209 NamedNodeMap nodeMap = node.getAttributes(); 210 String name = getNodeValue(nodeMap.getNamedItem("name")); 211 if (name == null) 212 { 213 log.warn("No name specified in URLDirectoryScanner config: " + 214 node + ". Ignoring"); 215 continue; 216 } 217 218 try 219 { 220 if (node.getNodeName().equals("dir")) 221 { 222 String filter = getNodeValue(nodeMap.getNamedItem("filter")); 224 String comp = getNodeValue(nodeMap.getNamedItem("comparator")); 225 226 addScanDir(name, comp, filter); 227 } else if (node.getNodeName().equals("url")) 228 { 229 addScanURL(name); 230 } 231 } catch (MalformedURLException e) 232 { 233 log.warn("Invalid url in DeploymentScanner. Ignoring.", e); 234 } 235 } 236 } 237 } 238 } 239 240 243 private String getNodeValue(Node node) 244 { 245 if (node == null) 246 { 247 return null; 248 } 249 String val = node.getNodeValue(); 250 if (val == null) 251 { 252 return null; 253 } 254 if ((val = val.trim()).length() == 0) 255 { 256 return null; 257 } 258 return val; 259 } 260 261 265 private URL toUrl(String value) throws MalformedURLException 266 { 267 try 268 { 269 return new URL (value); 270 } catch (MalformedURLException e) 271 { 272 File file = new File (value); 273 if (!file.isAbsolute()) 274 { 275 file = new File (serverHome, value); 276 } 277 278 try 279 { 280 file = file.getCanonicalFile(); 281 } catch (IOException ioe) 282 { 283 throw new MalformedURLException ("Can not obtain file: " + ioe); 284 } 285 286 return file.toURL(); 287 } 288 } 289 290 293 public void setURLComparator(String comparatorClassName) 294 { 295 log.debug("Setting Comparator: " + comparatorClassName); 296 try 297 { 298 defaultComparator = (Comparator )Thread.currentThread().getContextClassLoader().loadClass(comparatorClassName).newInstance(); 299 } catch (Exception e) 300 { 301 log.warn("Unable to create URLComparator.", e); 302 } 303 } 304 305 308 public String getURLComparator() 309 { 310 if (defaultComparator == null) 311 { 312 return null; 313 } 314 return defaultComparator.getClass().getName(); 315 } 316 317 320 public void setFilter(String filterClassName) 321 { 322 log.debug("Setting Filter: " + filterClassName); 323 try 324 { 325 defaultFilter = (FileFilter )Thread.currentThread().getContextClassLoader().loadClass(filterClassName).newInstance(); 326 } catch (Exception e) 327 { 328 log.warn("Unable to create URLComparator.", e); 329 } 330 } 331 332 335 public String getFilter() 336 { 337 if (defaultFilter == null) 338 { 339 return null; 340 } 341 return defaultFilter.getClass().getName(); 342 } 343 344 349 Deployer getDeployerObj() 350 { 351 return deployer; 352 } 353 354 358 private class Scanner 359 { 360 361 protected URL url; 362 363 364 private URL watchUrl; 365 366 367 private long lastModified; 368 369 370 private boolean deployed; 371 372 375 public Scanner(URL url) 376 { 377 this.url = url; 378 } 379 380 384 public void scan() 385 { 386 if (getLog().isTraceEnabled()) { 387 getLog().trace("Scanning url: " + url); 388 } 389 if (lastModified != getLastModified()) 391 { 392 if (exists()) 393 { 394 try 396 { 397 getLog().debug("Deploying Modified (or new) url: " + url); 398 deploy(); 399 } catch (DeploymentException e) 400 { 401 getLog().error("Failed to (re)deploy url: " + url, e); 402 } 403 } else 404 { 405 try 407 { 408 getLog().debug("Undeploying url: " + url); 409 undeploy(); 410 } catch (DeploymentException e) 411 { 412 getLog().error("Failed to undeploy url: " + url, e); 413 } 414 } 415 } 416 } 417 418 421 private boolean exists() 422 { 423 try 424 { 425 if (url.getProtocol().equals("file")) { 426 File file = new File (url.getPath()); 427 return file.exists(); 428 } else { 429 url.openStream().close(); 430 return true; 431 } 432 } catch (IOException e) 433 { 434 return false; 435 } 436 } 437 440 private long getLastModified() 441 { 442 try 443 { 444 URL lmUrl = watchUrl == null ? url : watchUrl; 445 return lmUrl.openConnection().getLastModified(); 446 } catch (IOException e) 447 { 448 return 0L; 449 } 450 } 451 455 private void deploy() throws DeploymentException 456 { 457 if (deployed) 458 { 459 getDeployerObj().undeploy(url); 461 } 462 getDeployerObj().deploy(url); 463 464 try 466 { 467 Object o = getServer().invoke(getDeployer(), "getWatchUrl", 468 new Object [] 469 { url }, 470 new String [] 471 { URL .class.getName() }); 472 watchUrl = o == null ? url : (URL )o; 473 474 getLog().debug("Watch URL for: " + url + " -> " + watchUrl); 475 } catch (Exception e) 476 { 477 watchUrl = url; 478 getLog().debug("Unable to obtain watchUrl from deployer. " + 479 "Use url: " + url, e); 480 } 481 482 lastModified = getLastModified(); 484 485 deployed = true; 487 } 488 491 private void undeploy() throws DeploymentException 492 { 493 if (!deployed) 494 { 495 return; 496 } 497 getDeployerObj().undeploy(url); 498 deployed = false; 500 lastModified = 0L; 501 watchUrl = null; 502 } 503 } 504 505 508 private class DirScanner extends Scanner 509 { 510 511 private File dir; 512 513 514 private FileFilter filter; 515 516 517 private Comparator comp; 518 519 520 private ArrayList deployed = new ArrayList (); 521 522 523 public DirScanner(URL url, Comparator comp, FileFilter filter) 524 { 525 super(url); 526 if (!url.getProtocol().equals("file")) 527 { 528 throw new IllegalArgumentException ("Urls for directory " + 529 "scanning must use the file: protocol."); 530 } 531 dir = new File (url.getPath()).getAbsoluteFile(); 532 533 this.filter = filter == null ? defaultFilter : filter; 534 this.comp = new FileComparator(comp == null ? defaultComparator : comp); 535 } 536 537 540 public void scan() 541 { 542 if (!dir.exists()) 544 { 545 getLog().warn("The director to scan does not exist: " + dir); 546 return; 547 } 548 if (!dir.isDirectory()) 549 { 550 getLog().warn("The directory to scan is not a directory: " + dir); 551 return; 552 } 553 554 File [] files; 556 if (filter == null) 557 { 558 files = dir.listFiles(); 559 } else 560 { 561 files = dir.listFiles(filter); 562 } 563 Arrays.sort(files, comp); 564 565 int deployedIndex = 0; 567 int fileIndex = 0; 568 569 while (true) 570 { 571 Scanner scanner = null; 573 if (deployedIndex < deployed.size()) 574 { 575 scanner = (Scanner)deployed.get(deployedIndex); 576 } 577 File file = null; 578 if (fileIndex < files.length) 579 { 580 file = files[fileIndex]; 581 } 582 583 if (scanner == null && file == null) 585 { 586 break; 587 } 588 589 switch (comp.compare(file, scanner == null ? null : scanner.url)) 592 { 593 case -1: getLog().debug("Found new deployable application in directory " + 595 dir + ": " + file); 596 try { 597 scanner = new Scanner(file.toURL()); 598 deployed.add(deployedIndex, scanner); 599 } catch (MalformedURLException e) { 600 getLog().warn("Unable to obtain URL for file: " + file, e); 601 fileIndex++; 602 } 603 case 0: scanner.scan(); 606 deployedIndex++; 607 fileIndex++; 608 break; 609 case 1: getLog().debug("Deployed application removed from directory " + 611 dir + ": " + file); 612 scanner.scan(); 613 if (!scanner.deployed) 614 { 615 deployed.remove(deployedIndex); 617 } else 618 { 619 deployedIndex++; 620 } 621 break; 622 } 623 } 624 } 625 } 626 627 634 private static class FileComparator implements Comparator 635 { 636 637 private Comparator urlComparator; 638 639 640 public FileComparator(Comparator urlComparator) 641 { 642 this.urlComparator = urlComparator; 643 } 644 645 650 public int compare(Object o1, Object o2) 651 { 652 if (o1 == o2) 654 { 655 return 0; 656 } 657 if (o1 == null) 658 { 659 return 1; 660 } 661 if (o2 == null) 662 { 663 return -1; 664 } 665 666 File file1; 668 File file2; 669 URL url1; 670 URL url2; 671 672 if (o1 instanceof URL ) 673 { 674 url1 = (URL )o1; 675 file1 = new File (url1.getPath()); 676 } else 677 { 678 file1 = (File )o1; 679 try 680 { 681 url1 = file1.toURL(); 682 } catch (MalformedURLException e) 683 { 684 throw new IllegalStateException ("Unable to create file url: " + 685 file1 + ": " + e); 686 } 687 } 688 if (o2 instanceof URL ) 689 { 690 url2 = (URL )o2; 691 file2 = new File (url2.getPath()); 692 } else 693 { 694 file2 = (File )o2; 695 try 696 { 697 url2 = file2.toURL(); 698 } catch (MalformedURLException e) 699 { 700 throw new IllegalStateException ("Unable to create file url: " + 701 file2 + ": " + e); 702 } 703 } 704 705 int comp = 0; 707 if (urlComparator != null) 708 { 709 comp = urlComparator.compare(url1, url2); 710 } 711 712 if (comp == 0) 714 { 715 comp = file1.compareTo(file2); 716 } 717 718 return comp < 0 ? -1 : comp > 0 ? 1 : 0; 720 } 721 } 722 723 726 public void scan() 727 { 728 log.trace("Scanning urls..."); 729 730 for (Iterator iter = scanners.iterator(); iter.hasNext(); ) 732 { 733 ((Scanner)iter.next()).scan(); 734 } 735 } 736 737 741 public ObjectName preRegister(MBeanServer server, ObjectName name) 742 throws Exception 743 { 744 745 serverHome = ServerConfigLocator.locate().getServerHomeDir(); 748 749 return super.preRegister(server, name); 750 } 751 } 752 | Popular Tags |