/**
   * Ultimately, the container name should come from the <code>sessionBeanMetadata</code>. However
   * because of the current behaviour where the container on its start sets the containername in the
   * metadata, its not possible to get this information even before the container is started.
   *
   * <p>Hence let's for the time being create the container name from all the information that we
   * have in the <code>unit</code>
   *
   * @param unit The deployment unit
   * @param sessionBeanMetadata Session bean metadata
   * @return Returns the container name for the bean corresponding to the <code>sessionBeanMetadata
   *     </code> in the <code>unit</code>
   * @throws MalformedObjectNameException
   */
  private String getContainerName(DeploymentUnit unit, JBossSessionBeanMetaData sessionBeanMetadata)
      throws MalformedObjectNameException {
    // TODO the base ejb3 jmx object name comes from Ejb3Module.BASE_EJB3_JMX_NAME, but
    // we don't need any reference to ejb3-core. Right now just hard code here, we need
    // a better way/place for this later
    StringBuilder containerName = new StringBuilder("jboss.j2ee:service=EJB3" + ",");

    // Get the top level unit for this unit (ex: the top level might be an ear and this unit might
    // be the jar
    // in that ear
    DeploymentUnit toplevelUnit = unit.getTopLevel();
    if (toplevelUnit != null) {
      // if top level is an ear, then create the name with the ear reference
      if (isEar(toplevelUnit)) {
        containerName.append("ear=");
        containerName.append(toplevelUnit.getSimpleName());
        containerName.append(",");
      }
    }
    // now work on the passed unit, to get the jar name
    if (unit.getSimpleName() == null) {
      containerName.append("*");
    } else {
      containerName.append("jar=");
      containerName.append(unit.getSimpleName());
    }
    // now the ejbname
    containerName.append(",name=");
    containerName.append(sessionBeanMetadata.getEjbName());

    if (logger.isTraceEnabled()) {
      logger.trace(
          "Container name generated for ejb = "
              + sessionBeanMetadata.getEjbName()
              + " in unit "
              + unit
              + " is "
              + containerName);
    }
    ObjectName containerJMXName = new ObjectName(containerName.toString());
    return containerJMXName.getCanonicalName();
  }
  /**
   * A template pattern implementation of the deploy() method. This method calls the {@link
   * #performDeploy(WebApplication, String, WebDescriptorParser) performDeploy()} method to perform
   * the container specific deployment steps and registers the returned WebApplication in the
   * deployment map. The steps performed are:
   *
   * <p>ClassLoader appClassLoader = thread.getContextClassLoader(); URLClassLoader warLoader =
   * URLClassLoader.newInstance(empty, appClassLoader); thread.setContextClassLoader(warLoader);
   * WebDescriptorParser webAppParser = ...; WebMetaData metaData = di.metaData; // Create JACC
   * permissions, contextID, etc. ... WebApplication warInfo = new WebApplication(metaData);
   * performDeploy(warInfo, warUrl, webAppParser); deploymentMap.put(warUrl, warInfo);
   * thread.setContextClassLoader(appClassLoader);
   *
   * <p>The subclass performDeploy() implementation needs to invoke processEnc(loader, warInfo) to
   * have the JNDI java:comp/env namespace setup before any web app component can access this
   * namespace.
   *
   * <p>Also, an MBean for each servlet deployed should be created and its JMX ObjectName placed
   * into the DeploymentInfo.mbeans list so that the JSR77 layer can create the approriate model
   * view. The servlet MBean needs to provide access to the min, max and total time in milliseconds.
   * Expose this information via MinServiceTime, MaxServiceTime and TotalServiceTime attributes to
   * integrate seemlessly with the JSR77 factory layer.
   *
   * @param unit The deployment info that contains the context-root element value from the J2EE
   *     application/module/web application.xml descriptor. This may be null if war was is not being
   *     deployed as part of an enterprise application. It also contains the URL of the web
   *     application war.
   */
  public synchronized WebApplication start(DeploymentUnit unit, JBossWebMetaData metaData)
      throws Exception {
    Thread thread = Thread.currentThread();
    ClassLoader appClassLoader = thread.getContextClassLoader();
    WebApplication webApp = null;
    try {
      // Create a classloader for the war to ensure a unique ENC
      ClassLoader warLoader = unit.getClassLoader();
      thread.setContextClassLoader(warLoader);
      String webContext = metaData.getContextRoot();

      // Get the war URL
      URL warUrl = unit.getAttachment("org.jboss.web.expandedWarURL", URL.class);
      if (warUrl == null && unit instanceof VFSDeploymentUnit) {
        VFSDeploymentUnit vdu = VFSDeploymentUnit.class.cast(unit);
        warUrl = VFSUtils.getRealURL(vdu.getRoot());
      }

      // Dynamic WebMetaData deployments might not provide an URL
      // We use the DEploymentUnit name as identifier instead.
      // The JAXWS Endpoint API for example does this.
      String warURLString = (warUrl != null ? warUrl.toExternalForm() : unit.getName());

      // Strip any jar: url syntax. This should be be handled by the vfs
      if (warURLString.startsWith("jar:"))
        warURLString = warURLString.substring(4, warURLString.length() - 2);

      log.debug("webContext: " + webContext);
      log.debug("warURL: " + warURLString);

      // Register the permissions with the JACC layer
      String contextID = metaData.getJaccContextID();
      if (contextID == null) contextID = unit.getSimpleName();
      metaData.setJaccContextID(contextID);

      webApp = new WebApplication(metaData);
      webApp.setClassLoader(warLoader);
      webApp.setDeploymentUnit(unit);
      performDeploy(webApp, warURLString);
    } finally {
      thread.setContextClassLoader(appClassLoader);
    }
    return webApp;
  }
 public static String getBeanName(DeploymentUnit unit, String serviceName) {
   return PREFIX + unit.getSimpleName() + "." + serviceName;
 }
 /**
  * Returns true if this <code>unit</code> represents an .ear deployment
  *
  * @param unit
  * @return
  */
 private boolean isEar(DeploymentUnit unit) {
   return unit.getSimpleName().endsWith(".ear")
       || unit.getAttachment(JBossAppMetaData.class) != null;
 }