ServiceRefDesc.java

00001 
00024 package org.objectweb.jonas_ws.deployment.api;
00025 
00026 import java.io.File;
00027 import java.io.IOException;
00028 import java.io.InputStream;
00029 import java.net.URL;
00030 import java.util.HashMap;
00031 import java.util.Hashtable;
00032 import java.util.Iterator;
00033 import java.util.List;
00034 import java.util.Map;
00035 import java.util.Set;
00036 import java.util.Vector;
00037 
00038 import javax.xml.namespace.QName;
00039 
00040 import org.objectweb.jonas_ejb.lib.BeanNaming;
00041 
00042 import org.objectweb.jonas_lib.I18n;
00043 import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
00044 import org.objectweb.jonas_lib.deployment.api.HandlerDesc;
00045 import org.objectweb.jonas_lib.deployment.xml.Handler;
00046 import org.objectweb.jonas_lib.deployment.xml.JonasInitParam;
00047 import org.objectweb.jonas_lib.deployment.xml.JonasPortComponentRef;
00048 import org.objectweb.jonas_lib.deployment.xml.JonasServiceRef;
00049 import org.objectweb.jonas_lib.deployment.xml.PortComponentRef;
00050 import org.objectweb.jonas_lib.deployment.xml.ServiceRef;
00051 
00052 import org.objectweb.jonas_ws.deployment.lib.MappingFileManager;
00053 import org.objectweb.jonas_ws.deployment.lib.wrapper.MappingFileManagerWrapper;
00054 
00055 import org.objectweb.jonas.common.Log;
00056 import org.objectweb.jonas.service.ServiceManager;
00057 
00058 import org.objectweb.util.monolog.api.BasicLevel;
00059 import org.objectweb.util.monolog.api.Logger;
00060 
00069 public class ServiceRefDesc {
00070 
00074     private static final String JAVAX_XML_RPC_SERVICE = "javax.xml.rpc.Service";
00075 
00079     private static Logger logger = Log.getLogger(Log.JONAS_WS_PREFIX);
00080 
00084     private static I18n i18n = I18n.getInstance(ServiceRefDesc.class);
00085 
00087     private Hashtable params = new Hashtable();
00088 
00090     private Vector pcRefs = new Vector();
00091 
00093     private Vector hRefs = new Vector();
00094 
00096     private WSDLFile wsdl;
00097 
00099     private WSDLFile altWsdl;
00100 
00102     private MappingFile mapping;
00103 
00105     private String name;
00106 
00108     private Class serviceInterface;
00109 
00111     private QName serviceQName = null;
00112 
00114     private File moduleFile = null;
00115 
00117     private String wsdlFileName = null;
00118 
00120     private String mappingFileName = null;
00121 
00123     private URL alternateWSDL = null;
00124 
00126     private URL localWSDLURL = null;
00127 
00129     private URL mappingFileURL = null;
00130 
00141     public ServiceRefDesc(ClassLoader classLoader, ServiceRef sref, JonasServiceRef jsref, String filename)
00142             throws WSDeploymentDescException {
00143 
00144         if (filename != null) {
00145             moduleFile = new File(filename);
00146         }
00147 
00148         // setup the classloader
00149         ClassLoader loader = classLoader;
00150 
00151         // set ServiceRefDesc name
00152         name = sref.getServiceRefName();
00153 
00154         // set Service QName (if exists)
00155         if (sref.getServiceQname() != null) {
00156             serviceQName = sref.getServiceQname().getQName();
00157         }
00158 
00159         // set Service Interface
00160         String si = sref.getServiceInterface().trim();
00161 
00162         try {
00163             serviceInterface = loader.loadClass(si);
00164         } catch (ClassNotFoundException cnf) {
00165             throw new WSDeploymentDescException(getI18n().getMessage("ServiceRefDesc.serviceIntfNotFound", si), cnf); //$NON-NLS-1$
00166         }
00167 
00168         // this interface must implements javax.xml.rpc.Service
00169         if (!javax.xml.rpc.Service.class.isAssignableFrom(serviceInterface)) {
00170             String err = getI18n().getMessage("ServiceRefDesc.mustExtService", serviceInterface.getName()); //$NON-NLS-1$
00171             throw new WSDeploymentDescException(err);
00172         }
00173 
00174         // ServiceRefDesc init parameters : jonas specific deployment desc
00175         if (jsref != null) {
00176             List jipl = jsref.getJonasInitParamList();
00177 
00178             for (int i = 0; i < jipl.size(); i++) {
00179                 // add in params table each init parameter name and associated value
00180                 JonasInitParam p = (JonasInitParam) jipl.get(i);
00181                 params.put(p.getParamName().trim(), p.getParamValue().trim());
00182             }
00183         }
00184 
00185         // fill portComponentRef list
00186         Map links = linkPCR2JPCR(sref, jsref);
00187         List pcrl = sref.getPortComponentRefList();
00188 
00189         for (int i = 0; i < pcrl.size(); i++) {
00190             // for each reference, build and add a PortComponentRef Object
00191             PortComponentRef ref = (PortComponentRef) pcrl.get(i);
00192             JonasPortComponentRef jref = (JonasPortComponentRef) links.get(ref.getServiceEndpointInterface());
00193             pcRefs.add(new PortComponentRefDesc(loader, ref, jref));
00194         }
00195 
00196         // fill handlers list
00197         List hl = sref.getHandlerList();
00198         Handler h = null;
00199 
00200         for (int i = 0; i < hl.size(); i++) {
00201             // for each reference, build and add a HandlerRef Object
00202             // get the standard dd handler
00203             h = (Handler) hl.get(i);
00204             // build and add a new handler
00205             try {
00206                 hRefs.add(new HandlerDesc(loader, h));
00207             } catch (DeploymentDescException dde) {
00208                 throw new WSDeploymentDescException(dde);
00209             }
00210         }
00211 
00212         // if alt-wsdl defined AND running online
00213         if (jsref != null && jsref.getAltWsdl() != null && isJonasRuntime()) {
00214             logger.log(BasicLevel.DEBUG, "loading alt-wsdl : " + jsref.getAltWsdl());
00215             try {
00216                 alternateWSDL = new URL(jsref.getAltWsdl());
00217                 altWsdl = new WSDLFile(alternateWSDL, jsref.getAltWsdl());
00218             } catch (IOException e) {
00219                 String err = "Cannot load alternate WSDL Stream from " + jsref.getAltWsdl();
00220                 throw new WSDeploymentDescException(err);
00221             }
00222         }
00223 
00224         // get ServiceRefDesc WSDLFile name
00225         String wf = sref.getWsdlFile();
00226         if (wf != null) {
00227             this.wsdlFileName = wf.trim();
00228             wsdl = new WSDLFile(loader, wsdlFileName);
00229 
00230             localWSDLURL = loader.getResource(wsdlFileName);
00231         }
00232 
00233         if (getWSDLFile() != null) {
00234             if ((getWSDLFile().getNbServices() > 1) && (serviceQName == null)) {
00235                 String err = getI18n().getMessage("ServiceRefDesc.serviceQnameNotDef", wsdlFileName, name); //$NON-NLS-1$
00236                 throw new WSDeploymentDescException(err);
00237             } else if ((getWSDLFile().getNbServices() == 1) && (serviceQName == null)) {
00238                 // When the WSDL defines only 1 service, we can retrieve
00239                 // automatically the service QName for service-ref
00240                 serviceQName = getWSDLFile().getServiceQname();
00241             } else {
00242                 // serviceQName not null
00243                 // check service QName existence in WSDL
00244                 if (isJonasRuntime()) {
00245                     if (!getWSDLFile().hasService(serviceQName)) {
00246                         throw new WSDeploymentDescException(getI18n().getMessage(
00247                                 "ServiceRefDesc.serviceNotFoundInWSDL", serviceQName, wsdlFileName)); //$NON-NLS-1$
00248                     }
00249                 }
00250             }
00251 
00252         }
00253 
00254         // get ServiceRefDesc MappingFile name
00255         String mf = sref.getJaxrpcMappingFile();
00256 
00257         if (mf != null) {
00258             this.mappingFileName = mf.trim();
00259             this.mappingFileURL = loader.getResource(mappingFileName);
00260             setMappingFile(loader);
00261         }
00262 
00263         // mapping is required when generated service interface is specified
00264         if (!serviceInterface.getName().equals(JAVAX_XML_RPC_SERVICE) && (mapping == null)) {
00265             throw new WSDeploymentDescException(getI18n().getMessage(
00266                     "ServiceRefDesc.mappingRequired", serviceInterface.getName())); //$NON-NLS-1$
00267         }
00268 
00269         validate();
00270     }
00271 
00275     private boolean isJonasRuntime() {
00276         try {
00277             ServiceManager.getInstance();
00278         } catch (Throwable t) {
00279             // Cannot get the JMX Service
00280             // offline mode or client container
00281             ClassLoader cl = this.getClass().getClassLoader();
00282             try {
00283                 cl.loadClass("org.objectweb.jonas.server.Bootstrap");
00284             } catch (ClassNotFoundException e) {
00285                 // we're in client container
00286                 // => jonas runtime
00287                 return true;
00288             }
00289             // loading successful => we're not in client container
00290             return false;
00291         }
00292         // else we're in jonas runtime
00293         Throwable t = new Exception();
00294         StackTraceElement[] elem = t.getStackTrace();
00295         for (int i = 0; i < elem.length; i++) {
00296             if ("org.objectweb.jonas_ws.wsgen.wrapper.WsGenWrapper".equals(elem[i].getClassName())) {
00297                 return false;
00298             }
00299             if ("org.objectweb.jonas_lib.genclientstub.wrapper.ClientGenStubWrapper".equals(elem[i].getClassName())) {
00300                 return false;
00301             }
00302             if ("org.objectweb.jonas_ejb.genic.wrapper.GenicServiceWrapper".equals(elem[i].getClassName())) {
00303                 return false;
00304             }
00305         }
00306         return true;
00307 
00308     }
00309 
00315     private Map linkPCR2JPCR(ServiceRef sref, JonasServiceRef jsref) {
00316         Map res = new HashMap();
00317         // for each port-component-ref
00318         for (Iterator i = sref.getPortComponentRefList().iterator(); i.hasNext();) {
00319             PortComponentRef pcr = (PortComponentRef) i.next();
00320             res.put(pcr.getServiceEndpointInterface(), null);
00321         }
00322         // jonas-port-component-ref(s)
00323         if (jsref != null) {
00324 
00325             // get all jonas-port-component.sei
00326             Set keys = res.keySet();
00327 
00328             // for each jonas-port-component
00329             for (Iterator i = jsref.getJonasPortComponentRefList().iterator(); i.hasNext();) {
00330                 JonasPortComponentRef jpcr = (JonasPortComponentRef) i.next();
00331                 String sei = jpcr.getServiceEndpointInterface();
00332 
00333                 if ((sei != null) && (keys.contains(sei))) {
00334                     // jonas-port-component-ref linked to port-component-ref
00335                     res.put(sei, jpcr);
00336                 } else {
00337                     String err = "jonas-port-component-ref '" + sei + "' is not linked to any port-component-ref. It will be ignored.";
00338                     logger.log(BasicLevel.WARN, err);
00339                 }
00340             }
00341         }
00342         return res;
00343     }
00344 
00349     public List getPortComponentRefs() {
00350         return pcRefs;
00351     }
00352 
00357     public List getHandlerRefs() {
00358         return hRefs;
00359     }
00360 
00365     public String getServiceRefName() {
00366         return name;
00367     }
00368 
00373     public Class getServiceInterface() {
00374         return serviceInterface;
00375     }
00376 
00381     public WSDLFile getWSDLFile() {
00382         // if alt-wsdl is not set, use standard wsdl-file
00383         WSDLFile file = altWsdl;
00384         if (file == null) {
00385             file = wsdl;
00386         }
00387         return file;
00388     }
00389 
00394     public MappingFile getMappingFile() {
00395         return mapping;
00396     }
00397 
00402     public Hashtable getParams() {
00403         return params;
00404     }
00405 
00411     public String getParam(String name) {
00412         return (String) params.get(name);
00413     }
00414 
00419     public String getWsdlFileName() {
00420         return wsdlFileName;
00421     }
00422 
00429     public QName getServiceQName() {
00430         return serviceQName;
00431     }
00432 
00433 
00434 
00438     public int hashCode() {
00439         return this.name.hashCode();
00440     }
00447     public boolean equals(Object other) {
00448         if (other == null) {
00449             return false;
00450         }
00451 
00452         if (!(other instanceof ServiceRefDesc)) {
00453             return false;
00454         }
00455 
00456         ServiceRefDesc sr = (ServiceRefDesc) other;
00457 
00458         if (!mapping.equals(sr.getMappingFile())) {
00459             return false;
00460         }
00461 
00462         if (!wsdl.equals(sr.getWSDLFile())) {
00463             return false;
00464         }
00465 
00466         if (!params.equals(sr.getParams())) {
00467             return false;
00468         }
00469 
00470         for (Iterator i = sr.getPortComponentRefs().iterator(); i.hasNext();) {
00471             PortComponentRefDesc pcr = (PortComponentRefDesc) i.next();
00472 
00473             if (!pcRefs.contains(pcr)) {
00474                 return false;
00475             }
00476         }
00477 
00478         for (Iterator i = sr.getHandlerRefs().iterator(); i.hasNext();) {
00479             HandlerDesc hr = (HandlerDesc) i.next();
00480 
00481             if (!hRefs.contains(hr)) {
00482                 return false;
00483             }
00484         }
00485 
00486         return true;
00487     }
00488 
00494     private void setMappingFile(ClassLoader loader) throws WSDeploymentDescException {
00495 
00496         // build the MappingFile
00497         // Build Mapping file
00498         if (moduleFile != null) {
00499             if (isRunningInClientContainer()) {
00500                 mapping = MappingFileManager.getInstance(moduleFile, mappingFileName);
00501             } else {
00502                 mapping = MappingFileManagerWrapper.getMappingFile(moduleFile, mappingFileName);
00503             }
00504         } else {
00505             // Try to get the mapping from the ClassLoader
00506             InputStream is = null;
00507             if (loader != null) {
00508                 is = loader.getResourceAsStream(mappingFileName);
00509                 if (is != null) {
00510                     // build the MappingFile
00511                     if (isRunningInClientContainer()) {
00512                         mapping = MappingFileManager.getInstance(is, mappingFileName);
00513                     } else {
00514                         mapping = MappingFileManagerWrapper.getMappingFile(is, mappingFileName);
00515                     }
00516                 } else {
00517                     throw new WSDeploymentDescException(getI18n().getMessage(
00518                             "ServiceRefDesc.mappingFileNotFoundInLoader", mappingFileName)); //$NON-NLS-1$
00519                 }
00520             } else {
00521                 throw new WSDeploymentDescException(getI18n().getMessage("ServiceRefDesc.mappingFileNotFound")); //$NON-NLS-1$
00522             }
00523         }
00524     }
00525 
00530     private boolean isRunningInClientContainer() {
00531         return (System.getProperty("jonas.base") == null);
00532     }
00533 
00538     private void validate() throws WSDeploymentDescException {
00539         // validate informations :
00540         // TODO pcLinkExist
00541 
00542         // Port validity between handlers and wsdl
00543         for (int i = 0; i < hRefs.size(); i++) {
00544             HandlerDesc myHRef = (HandlerDesc) hRefs.get(i);
00545             List pnl = myHRef.getPortNames();
00546 
00547             for (int j = 0; j < pnl.size(); j++) {
00548                 if (!getWSDLFile().hasPort((String) pnl.get(j))) {
00549                     // the handler use a port undefined in the wsdl
00550                     throw new WSDeploymentDescException(getI18n().getMessage(
00551                             "ServiceRefDesc.undefinedPort", myHRef.getName(), pnl.get(j), wsdlFileName)); //$NON-NLS-1$
00552                 }
00553             }
00554         }
00555 
00556         // Check service-interface
00557         // if service interface is not generic, Full WSDL Knowledge is required
00558         if (!serviceInterface.equals(javax.xml.rpc.Service.class)) {
00559             if ((getWSDLFile() == null) || ((getWSDLFile() != null) && (getWSDLFile().getDefinition().getServices().values().size() == 0))) {
00560                 throw new WSDeploymentDescException(getI18n().getMessage(
00561                         "ServiceRefDesc.wsdlMissingInformation", serviceInterface.getName(), name)); //$NON-NLS-1$
00562             }
00563 
00564             // Check mapping for GeneratedServiceInterface
00565             String namespaceURI = serviceQName.getNamespaceURI();
00566             String realPackage = BeanNaming.getPackageName(serviceInterface.getName());
00567 
00568             // real != mapping provided package
00569             if (!realPackage.equals(mapping.getMapping(namespaceURI))) {
00570                 throw new WSDeploymentDescException(getI18n().getMessage(
00571                         "ServiceRefDesc.needPackageMapping", mappingFileName, realPackage)); //$NON-NLS-1$
00572             }
00573 
00574             /*
00575              * TODO : Uncomment this part will require substancial modification
00576              * to number of tests (integ + unit) // -> We need to create
00577              * generated clients interfaces for each endpoint ... // keep
00578              * service QName namespaceURI (targetNamespace) // check mapping for
00579              * ServiceEndpointInterface when having a generated
00580              * service-interface for (Iterator p = pcRefs.iterator() ;
00581              * p.hasNext() ; ) { PortComponentRef pcr = (PortComponentRef)
00582              * p.next(); String sei = pcr.getSei().getName(); realPackage =
00583              * BeanNaming.getPackageName(sei); if
00584              * (!realPackage.equals(mapping.getMapping(namespaceURI))) throw new
00585              * WSDeploymentDescException("jaxrpc-mapping-file '" +
00586              * mappingFileName + "' need a mapping for package '" + realPackage +
00587              * "'"); }
00588              */
00589         }
00590     }
00591 
00595     protected static I18n getI18n() {
00596         return i18n;
00597     }
00598 
00602     public URL getAlternateWsdlURL() {
00603         return alternateWSDL;
00604     }
00605 
00609     public URL getLocalWSDLURL() {
00610         return localWSDLURL;
00611     }
00612 
00616     public URL getMappingFileURL() {
00617         return mappingFileURL;
00618     }
00619 }

Generated on Tue Feb 15 15:05:59 2005 for JOnAS by  doxygen 1.3.9.1