1 26 27 package org.objectweb.jonas_ws.deployment.lib; 28 29 import java.io.File ; 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.io.InputStreamReader ; 33 import java.io.Reader ; 34 import java.net.MalformedURLException ; 35 import java.net.URL ; 36 import java.net.URLClassLoader ; 37 import java.net.URLConnection ; 38 import java.util.Enumeration ; 39 import java.util.HashMap ; 40 import java.util.Hashtable ; 41 import java.util.Iterator ; 42 import java.util.List ; 43 import java.util.Map ; 44 import java.util.StringTokenizer ; 45 import java.util.Vector ; 46 47 import org.objectweb.jonas_ejb.deployment.api.BeanDesc; 48 import org.objectweb.jonas_ejb.deployment.api.DeploymentDesc; 49 import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc; 50 import org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager; 51 52 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException; 53 import org.objectweb.jonas_lib.deployment.digester.JDigester; 54 import org.objectweb.jonas_lib.deployment.lib.AbsDeploymentDescManager; 55 56 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc; 57 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDescException; 58 import org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager; 59 60 import org.objectweb.jonas_ws.deployment.api.PortComponentDesc; 61 import org.objectweb.jonas_ws.deployment.api.ServiceDesc; 62 import org.objectweb.jonas_ws.deployment.api.WSDeploymentDesc; 63 import org.objectweb.jonas_ws.deployment.api.WSDeploymentDescException; 64 import org.objectweb.jonas_ws.deployment.rules.JonasWebservicesRuleSet; 65 import org.objectweb.jonas_ws.deployment.rules.WebservicesRuleSet; 66 import org.objectweb.jonas_ws.deployment.xml.JonasWebservices; 67 import org.objectweb.jonas_ws.deployment.xml.Webservices; 68 69 import org.objectweb.jonas.common.Log; 70 71 import org.objectweb.util.monolog.api.BasicLevel; 72 import org.objectweb.util.monolog.api.Logger; 73 74 81 public class WSDeploymentDescManager extends AbsDeploymentDescManager { 82 83 86 public static final String WS_EJBJAR_FILE_NAME = "META-INF/webservices.xml"; 87 88 91 public static final String JONAS_WS_EJBJAR_FILE_NAME = "META-INF/jonas-webservices.xml"; 92 93 96 public static final String WS_WEBAPP_FILE_NAME = "WEB-INF/webservices.xml"; 97 98 101 public static final String JONAS_WS_WEBAPP_FILE_NAME = "WEB-INF/jonas-webservices.xml"; 102 103 106 private static JDigester wsDigester = null; 107 108 111 private static JDigester jwsDigester = null; 112 113 116 private static WebservicesRuleSet wsRuleSet = new WebservicesRuleSet(); 117 118 121 private static JonasWebservicesRuleSet jwsRuleSet = new JonasWebservicesRuleSet(); 122 123 126 private static boolean parsingWithValidation = true; 127 128 131 private static WSDeploymentDescManager unique = null; 132 133 136 private static boolean isInstanciated = false; 137 138 141 private static Logger logger = Log.getLogger(Log.JONAS_WS_PREFIX); 142 143 146 private HashMap urlWsddBindings; 147 148 152 private Map classLoader2URLs; 153 154 157 private EjbDeploymentDescManager ejbManager = null; 158 159 162 private WebDeploymentDescManager webManager = null; 163 164 168 private WSDeploymentDescManager() { 169 urlWsddBindings = new HashMap (); 170 classLoader2URLs = new Hashtable (); 171 172 ejbManager = EjbDeploymentDescManager.getInstance(); 173 webManager = WebDeploymentDescManager.getInstance(); 174 } 175 176 180 public static WSDeploymentDescManager getInstance() { 181 if (!isInstanciated) { 182 isInstanciated = true; 183 unique = new WSDeploymentDescManager(); 184 185 } 186 return unique; 187 } 188 189 199 public static WSDeploymentDesc getDeploymentDesc(String file, ClassLoader jarCL) throws WSDeploymentDescException { 200 201 URL fileUrl = null; 202 try { 203 fileUrl = new File (file).toURL(); 204 } catch (MalformedURLException mue) { 205 throw new WSDeploymentDescException(mue); 206 } 207 208 WSDeploymentDesc wsdd = loadDeploymentDesc(fileUrl, jarCL); 209 210 if (wsdd == null) { 212 return null; 213 214 } 215 216 List sdl = wsdd.getServiceDescs(); 218 219 for (int i = 0; i < sdl.size(); i++) { 220 List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents(); 221 222 for (int j = 0; j < pcdl.size(); j++) { 223 PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j); 225 String sibLink = pcd.getSibLink(); 226 227 if (pcd.hasBeanImpl()) { 229 SessionStatelessDesc desc = getBeanDesc(file, sibLink, jarCL); 230 pcd.setDesc(desc); 231 232 } else if (pcd.hasJaxRpcImpl()) { 233 WebContainerDeploymentDesc desc = getWebDesc(file, sibLink, jarCL); 234 pcd.setDesc(desc); 235 236 } 237 } 238 } 239 240 return wsdd; 241 } 242 243 255 public WSDeploymentDesc getDeploymentDesc(URL url, ClassLoader jarCL, ClassLoader earCL) 256 throws WSDeploymentDescException { 257 return getDeploymentDesc(url, null, jarCL, earCL); 258 } 259 260 273 public WSDeploymentDesc getDeploymentDesc(URL url, URL unpackedURL, ClassLoader jarCL, ClassLoader earCL) 274 throws WSDeploymentDescException { 275 276 WSDeploymentDesc wsdd = null; 277 File moduleFile = new File (url.getFile()); 278 279 if (moduleFile.exists()) { 280 if (!urlWsddBindings.containsKey(url)) { 282 wsdd = getDeploymentDescriptor(url, unpackedURL, jarCL, earCL); 283 } else { wsdd = (WSDeploymentDesc) urlWsddBindings.get(url); 287 } 288 } else { 289 throw new WSDeploymentDescException("'" + moduleFile.getName() + "' doesn't exists"); 290 } 291 292 ClassLoader keyCL; 294 if (earCL != null) { 295 keyCL = earCL; 296 } else { 297 keyCL = jarCL; 298 } 299 List urls = (List ) classLoader2URLs.get(keyCL); 300 if (urls == null) { 301 urls = new Vector (); 302 classLoader2URLs.put(keyCL, urls); 303 } 304 urls.add(url); 305 306 return wsdd; 307 } 308 309 323 private WSDeploymentDesc getDeploymentDescriptor(URL url, URL unpackedURL, ClassLoader jarCL, ClassLoader earCL) 324 throws WSDeploymentDescException { 325 326 URL baseURL = url; 327 if (unpackedURL != null) { 328 baseURL = unpackedURL; 329 } 330 WSDeploymentDesc wsdd = loadDeploymentDesc(baseURL, jarCL); 331 332 urlWsddBindings.put(url, wsdd); 334 335 if (wsdd == null) { 337 return null; 338 } 339 340 List sdl = wsdd.getServiceDescs(); 342 343 for (int i = 0; i < sdl.size(); i++) { 344 List pcdl = ((ServiceDesc) sdl.get(i)).getPortComponents(); 345 346 for (int j = 0; j < pcdl.size(); j++) { 347 PortComponentDesc pcd = (PortComponentDesc) pcdl.get(j); 349 String sibLink = pcd.getSibLink(); 350 351 if (pcd.hasBeanImpl()) { 353 SessionStatelessDesc desc = getBeanDesc(url.getFile(), sibLink, jarCL, earCL); 354 pcd.setDesc(desc); 355 356 } else if (pcd.hasJaxRpcImpl()) { 357 WebContainerDeploymentDesc desc = getWebDesc(url.getFile(), sibLink, jarCL, earCL); 358 pcd.setDesc(desc); 359 360 } 361 } 362 } 363 364 return wsdd; 365 } 366 367 377 private static WSDeploymentDesc loadDeploymentDesc(URL url, ClassLoader cl) throws WSDeploymentDescException { 378 379 URLClassLoader ucl = (URLClassLoader ) cl; 380 381 InputStream isWebservices = null; 383 384 InputStream isJonasWebservices = null; 386 387 URL wsXml = null; 388 URL jwsXml = null; 389 390 try { 391 392 boolean foundInEjb = false; 393 for (Enumeration ejbWebservices = ucl.findResources("META-INF/webservices.xml"); ejbWebservices 394 .hasMoreElements() 395 && !foundInEjb;) { 396 wsXml = (URL ) ejbWebservices.nextElement(); 397 if (isResourceInFile(url, wsXml)) { 398 foundInEjb = true; 399 } 400 } 401 402 if (foundInEjb) { 404 isWebservices = openInputStream(wsXml); 405 406 foundInEjb = false; 407 for (Enumeration ejbJonasWebservices = ucl.findResources("META-INF/jonas-webservices.xml"); ejbJonasWebservices 409 .hasMoreElements() 410 && !foundInEjb;) { 411 jwsXml = (URL ) ejbJonasWebservices.nextElement(); 412 if (isResourceInFile(url, jwsXml)) { 413 foundInEjb = true; 414 } 415 } 416 if (foundInEjb) { 417 isJonasWebservices = openInputStream(jwsXml); 418 419 } 420 } 421 422 boolean foundInWeb = false; 423 for (Enumeration webWebservices = ucl.findResources("WEB-INF/webservices.xml"); webWebservices 424 .hasMoreElements() 425 && !foundInWeb;) { 426 wsXml = (URL ) webWebservices.nextElement(); 427 if (isResourceInFile(url, wsXml)) { 428 foundInWeb = true; 429 } 430 } 431 432 if (foundInWeb) { 434 isWebservices = openInputStream(wsXml); 435 436 foundInWeb = false; 437 for (Enumeration webJonasWebservices = ucl.findResources("WEB-INF/jonas-webservices.xml"); webJonasWebservices 439 .hasMoreElements() 440 && !foundInWeb;) { 441 jwsXml = (URL ) webJonasWebservices.nextElement(); 442 if (isResourceInFile(url, jwsXml)) { 443 foundInWeb = true; 444 } 445 } 446 if (foundInWeb) { 447 isJonasWebservices = openInputStream(jwsXml); 448 } 449 } 450 } catch (IOException ioe) { 451 String err = "Cannot open Streams on WebServices Deployment Descriptor for '" + url + "'"; 452 throw new WSDeploymentDescException(err, ioe); 453 } 454 455 if (isWebservices == null) { 457 return null; 458 } 459 460 Webservices webservices = loadWebservices(new InputStreamReader (isWebservices), wsXml.getFile()); 462 JonasWebservices jonasWebservices = null; 463 464 if (isJonasWebservices != null) { 465 jonasWebservices = loadJonasWebservices(new InputStreamReader (isJonasWebservices), jwsXml.getFile()); 466 } 467 468 try { 469 if (isWebservices != null) { 470 isWebservices.close(); 471 } 472 if (isJonasWebservices != null) { 473 isJonasWebservices.close(); 474 } 475 } catch (IOException ioe) { 476 String err = "Cannot close InputStreams for '" + url + "'"; 478 logger.log(BasicLevel.WARN, err); 479 } 480 481 WSDeploymentDesc wsdd = new WSDeploymentDesc(cl, logger, webservices, jonasWebservices); 483 484 return wsdd; 485 486 } 487 488 493 private static InputStream openInputStream(URL xml) throws IOException { 494 URLConnection conn = xml.openConnection(); 495 conn.setUseCaches(false); 496 conn.setDefaultUseCaches(false); 497 InputStream is = conn.getInputStream(); 498 499 return is; 500 } 501 502 508 private static boolean isResourceInFile(URL file, URL resource) { 509 510 boolean within = false; 511 512 File f = new File (file.getFile()); 513 if (f.isDirectory()) { 514 if (resource.toString().startsWith(file.toString())) { 518 within = true; 519 if (logger.isLoggable(BasicLevel.DEBUG)) { 520 logger.log(BasicLevel.DEBUG, "Directory case. found '" + resource + "' in '" + file + "'"); 521 } 522 } 523 } else if (f.isFile()) { 524 if (f.getPath().endsWith(".xml")) { 525 if (file.equals(resource)) { 529 within = true; 530 if (logger.isLoggable(BasicLevel.DEBUG)) { 531 logger.log(BasicLevel.DEBUG, "XML case. found '" + resource + "' in '" + file + "'"); 532 } 533 } 534 } else if ((f.getPath().endsWith(".war")) || (f.getPath().endsWith(".jar"))) { 535 int index = resource.toString().indexOf("!/"); 539 if (index != -1) { 540 if (resource.toString().startsWith(("jar:" + file.toString()))) { 541 within = true; 542 if (logger.isLoggable(BasicLevel.DEBUG)) { 543 logger.log(BasicLevel.DEBUG, "Archive case. found '" + resource + "' in '" + file + "'"); 544 } 545 } 546 } 547 } 548 } 549 return within; 550 } 551 552 560 public static Webservices loadWebservices(Reader reader, String fileName) throws WSDeploymentDescException { 561 562 Webservices ws = new Webservices(); 563 564 if (wsDigester == null) { 566 try { 567 wsDigester = new JDigester(wsRuleSet, getParsingWithValidation(), true, null, new WsSchemas()); 569 } catch (DeploymentDescException e) { 570 throw new WSDeploymentDescException(e); 571 } 572 } 573 574 try { 575 wsDigester.parse(reader, fileName, ws); 576 } catch (DeploymentDescException e) { 577 throw new WSDeploymentDescException(e); 578 } finally { 579 wsDigester.push(null); 580 } 581 582 return ws; 583 } 584 585 593 public static JonasWebservices loadJonasWebservices(Reader reader, String fileName) 594 throws WSDeploymentDescException { 595 596 JonasWebservices jws = new JonasWebservices(); 597 598 if (jwsDigester == null) { 600 try { 601 jwsDigester = new JDigester(jwsRuleSet, getParsingWithValidation(), true, null, new JonasWsSchemas()); 603 } catch (DeploymentDescException e) { 604 throw new WSDeploymentDescException(e); 605 } 606 } 607 608 try { 609 jwsDigester.parse(reader, fileName, jws); 610 } catch (DeploymentDescException e) { 611 throw new WSDeploymentDescException(e); 612 } finally { 613 jwsDigester.push(null); 614 } 615 616 return jws; 617 618 } 619 620 625 public int getCacheSize() { 626 return urlWsddBindings.size(); 627 628 } 629 630 633 public void clearCache() { 634 urlWsddBindings = new HashMap (); 635 } 636 637 641 public void removeCache(ClassLoader cl) { 642 List urls = (List ) classLoader2URLs.remove(cl); 643 if (urls != null) { 644 for (Iterator i = urls.iterator(); i.hasNext();) { 645 URL url = (URL ) i.next(); 646 urlWsddBindings.remove(url); 647 } 648 } 649 } 650 651 655 public String toString() { 656 return "" + getCacheSize(); 657 658 } 659 660 670 private static SessionStatelessDesc getBeanDesc(String filename, String link, ClassLoader cl) 671 throws WSDeploymentDescException { 672 673 BeanDesc bd = null; 674 675 try { 676 DeploymentDesc dd = org.objectweb.jonas_ejb.deployment.lib.EjbDeploymentDescManager.getDeploymentDesc( 682 filename, cl); 683 bd = dd.getBeanDesc(link); 684 685 } catch (DeploymentDescException dde) { 686 throw new WSDeploymentDescException("DeploymentDescException when searching '" + link + "' in '" + filename 687 + "'", dde); 688 } 689 690 if (bd == null) { 691 throw new WSDeploymentDescException("Unable to find the ejb-link '" + link + "' in '" + filename + "'"); 692 } 693 694 if (!(bd instanceof SessionStatelessDesc)) { 695 throw new WSDeploymentDescException("ejb-link '" + link + "' must be a Stateless Session Bean not a '" 696 + bd.getClass().getName() + "'"); 697 } 698 699 return (SessionStatelessDesc) bd; 700 701 } 702 703 714 private SessionStatelessDesc getBeanDesc(String filename, String link, ClassLoader jarCL, ClassLoader earCL) 715 throws WSDeploymentDescException { 716 URL url; 717 718 try { 719 url = new File (filename).toURL(); 720 721 } catch (MalformedURLException mue) { 722 throw new WSDeploymentDescException("Url Error with '" + filename + "'", mue); 723 } 724 725 BeanDesc bd = null; 726 727 try { 728 DeploymentDesc dd = ejbManager.getDeploymentDesc(url, jarCL, earCL); 729 bd = dd.getBeanDesc(link); 730 731 } catch (DeploymentDescException dde) { 732 throw new WSDeploymentDescException("Unable to load EjbJar '" + url + "'", dde); 733 } 734 735 if (bd == null) { 737 throw new WSDeploymentDescException("Unable to find the ejb-link '" + link + "' in '" + filename + "'"); 738 } 739 740 if (!(bd instanceof SessionStatelessDesc)) { 741 throw new WSDeploymentDescException("ejb-link '" + link + "' must be a Stateless Session Bean"); 742 } 743 744 return (SessionStatelessDesc) bd; 745 746 } 747 748 757 private static WebContainerDeploymentDesc getWebDesc(String filename, String link, ClassLoader cl) 758 throws WSDeploymentDescException { 759 760 WebContainerDeploymentDesc wd = null; 761 762 try { 763 wd = org.objectweb.jonas_web.deployment.lib.WebDeploymentDescManager.getDeploymentDesc(filename, cl); 769 } catch (WebContainerDeploymentDescException wcdde) { 770 throw new WSDeploymentDescException("Error while reading/parsing " + filename, wcdde); 771 } 772 773 if (wd.getServletClassname(link) == null) { 775 throw new WSDeploymentDescException("Unable to find the servlet-link '" + link + "' in '" + filename + "'"); 776 } 777 778 return wd; 779 780 } 781 782 793 private WebContainerDeploymentDesc getWebDesc(String filename, String link, ClassLoader jarCL, ClassLoader earCL) 794 throws WSDeploymentDescException { 795 796 URL url; 797 798 try { 799 url = new File (filename).toURL(); 800 } catch (MalformedURLException mue) { 801 throw new WSDeploymentDescException("Url Error with '" + filename + "'", mue); 802 } 803 804 WebContainerDeploymentDesc wd = null; 805 806 try { 807 wd = webManager.getDeploymentDesc(url, jarCL, earCL); 808 } catch (DeploymentDescException wcdde) { 809 throw new WSDeploymentDescException("Error while reading/parsing " + filename, wcdde); 810 } 811 812 if (wd.getServletClassname(link) == null) { 814 throw new WSDeploymentDescException("Unable to find the servlet-link '" + link + "' in '" + filename + "'"); 815 } 816 817 return wd; 818 819 } 820 821 825 public static boolean getParsingWithValidation() { 826 return parsingWithValidation; 827 } 828 829 833 public static void setParsingWithValidation(boolean validation) { 834 WSDeploymentDescManager.parsingWithValidation = validation; 835 } 836 837 849 public PortComponentDesc getPortComponentDesc(URL callerURL, String portComponentLinkName, ClassLoader moduleLoader, ClassLoader earLoader) 850 throws WSDeploymentDescException { 851 852 String moduleLink = null; 856 String pcNameLink = null; 857 URL moduleLinkUrl = null; 858 URLClassLoader loaderForCls = null; 859 860 if (!portComponentLinkName.matches(".*#.*")) { 863 pcNameLink = portComponentLinkName; 866 867 moduleLinkUrl = callerURL; 868 loaderForCls = (URLClassLoader ) moduleLoader; 869 } else { 870 872 if ((portComponentLinkName.toLowerCase().indexOf(".war" + AbsDeploymentDescManager.LINK_SEPARATOR) == -1) && (portComponentLinkName.toLowerCase().indexOf(".jar" + AbsDeploymentDescManager.LINK_SEPARATOR) == -1)) { 874 String err = "PC-link " + portComponentLinkName + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName"; 876 throw new WSDeploymentDescException(err); 877 } 878 StringTokenizer st = new StringTokenizer (portComponentLinkName, LINK_SEPARATOR); 879 880 if (st.countTokens() != 2 || portComponentLinkName.startsWith(AbsDeploymentDescManager.LINK_SEPARATOR) 883 || portComponentLinkName.endsWith(AbsDeploymentDescManager.LINK_SEPARATOR)) { 884 String err = "PC-link " + portComponentLinkName + " has a bad format. Correct format : filename.[jar or war]#portComponentName or just portComponentName"; 885 throw new WSDeploymentDescException(err); 886 } 887 888 moduleLink = st.nextToken(); 890 pcNameLink = st.nextToken(); 891 892 try { 895 moduleLinkUrl = new File (new File (callerURL.getFile()).getParent() + File.separator + moduleLink).getCanonicalFile().toURL(); 896 } catch (MalformedURLException mue) { 897 String err = "Error when creating an url for the module filename. Error :" + mue.getMessage(); 898 throw new WSDeploymentDescException(err, mue); 899 } catch (IOException ioe) { 900 String err = "Error when creating/accessing a file. Error :" + ioe.getMessage(); 901 throw new WSDeploymentDescException(err, ioe); 902 } 903 904 if (!new File (moduleLinkUrl.getFile()).exists()) { 906 String err = "Cannot get the deployment descriptor for '" + moduleLinkUrl.getFile() + "'. The file doesn't exist."; 907 throw new WSDeploymentDescException(err); 908 } 909 910 URL [] ddURL = new URL [1]; 911 ddURL[0] = moduleLinkUrl; 912 loaderForCls = new URLClassLoader (ddURL, earLoader); 913 914 } 915 916 WSDeploymentDesc wsDD = null; 919 920 try { 921 wsDD = getDeploymentDesc(moduleLinkUrl, loaderForCls, earLoader); 922 } catch (DeploymentDescException e) { 923 String err = "Cannot get the deployment descriptor for '" + moduleLinkUrl.getFile() + "'."; 924 throw new WSDeploymentDescException(err, e); 925 } 926 if (wsDD == null) { 927 String err = "Port component link " + pcNameLink + " not found in " + moduleLinkUrl.getFile(); 929 throw new WSDeploymentDescException(err); 930 } 931 932 List sdl = wsDD.getServiceDescs(); 934 boolean isFound = false; 935 PortComponentDesc pcd = null; 936 for (int i = 0; (i < sdl.size()) && !isFound; i++) { 937 if (sdl.get(i) != null) { 938 pcd = ((ServiceDesc) sdl.get(i)).getPortComponent(pcNameLink); 939 isFound = (pcd != null); 940 } 942 } 943 if (!isFound) { 944 String err = "the port component link " + pcNameLink + " doesn't exist in " + moduleLinkUrl.getFile(); 946 throw new WSDeploymentDescException(err); 947 } 948 949 return pcd; 950 } 951 } | Popular Tags |