/**
   * Finds a ejb-jar.xml (at WEB-INF of a .war or META-INF of a .jar) parses the file and creates
   * metadata out of it. The metadata is then attached to the deployment unit.
   *
   * @param deploymentPhase
   * @throws DeploymentUnitProcessingException
   */
  @Override
  public void deploy(DeploymentPhaseContext deploymentPhase)
      throws DeploymentUnitProcessingException {

    // get hold of the deployment unit.
    DeploymentUnit deploymentUnit = deploymentPhase.getDeploymentUnit();

    // get the root of the deployment unit
    VirtualFile deploymentRoot =
        deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();

    // Locate a ejb-jar.xml
    VirtualFile ejbJarXml = null;
    // EJB 3.1 FR 20.4 Enterprise Beans Packaged in a .war
    // TODO: Is there a better way to do this?
    if (deploymentRoot.getName().toLowerCase().endsWith(WAR_FILE_EXTENSION)) {
      // it's a .war file, so look for the ejb-jar.xml in WEB-INF
      ejbJarXml = deploymentRoot.getChild(EJB_JAR_XML_LOCATION_IN_WAR);
    } else if (deploymentRoot.getName().toLowerCase().endsWith(JAR_FILE_EXTENSION)) {
      ejbJarXml = deploymentRoot.getChild(EJB_JAR_XML_LOCATION_IN_JAR);
    } else {
      // neither a .jar nor a .war. Return
      return;
    }

    if (ejbJarXml == null || !ejbJarXml.exists()) {
      // no ejb-jar.xml found, nothing to do!
      return;
    }
    // Mark it as a EJB deployment
    EjbDeploymentMarker.mark(deploymentUnit);
    if (!deploymentUnit.hasAttachment(EjbDeploymentAttachmentKeys.EJB_JAR_DESCRIPTION)) {
      final EEModuleDescription moduleDescription =
          deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.EE_MODULE_DESCRIPTION);
      final EjbJarDescription ejbModuleDescription = new EjbJarDescription(moduleDescription);
      deploymentUnit.putAttachment(
          EjbDeploymentAttachmentKeys.EJB_JAR_DESCRIPTION, ejbModuleDescription);
    }

    // get the XMLStreamReader and parse the ejb-jar.xml
    MetaDataElementParser.DTDInfo dtdInfo = new MetaDataElementParser.DTDInfo();
    InputStream stream = null;
    try {
      stream = ejbJarXml.openStream();

      XMLStreamReader reader = this.getXMLStreamReader(stream, ejbJarXml, dtdInfo);

      EjbJarMetaData ejbJarMetaData = EjbJarMetaDataParser.parse(reader, dtdInfo);
      // attach the EjbJarMetaData to the deployment unit
      deploymentUnit.putAttachment(EjbDeploymentAttachmentKeys.EJB_JAR_METADATA, ejbJarMetaData);

    } catch (XMLStreamException xmlse) {
      throw new DeploymentUnitProcessingException(
          "Exception while parsing ejb-jar.xml: " + ejbJarXml.getPathName(), xmlse);
    } catch (IOException ioe) {
      throw new DeploymentUnitProcessingException(
          "Failed to create reader for ejb-jar.xml: " + ejbJarXml.getPathName(), ioe);
    } finally {
      try {
        if (stream != null) {
          stream.close();
        }
      } catch (IOException ioe) {
        logger.debug("Ignoring exception while closing the InputStream ", ioe);
      }
    }
  }
  private void processSessionBeans(
      final DeploymentUnit deploymentUnit,
      final List<AnnotationInstance> sessionBeanAnnotations,
      final SessionBeanComponentDescription.SessionBeanType annotatedSessionBeanType) {

    final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit);
    final ServiceName deploymentUnitServiceName = deploymentUnit.getServiceName();

    // process these session bean annotations and create component descriptions out of it
    for (final AnnotationInstance sessionBeanAnnotation : sessionBeanAnnotations) {
      final AnnotationTarget target = sessionBeanAnnotation.target();
      if (!(target instanceof ClassInfo)) {
        // Let's just WARN and move on. No need to throw an error
        logger.warn(
            sessionBeanAnnotation.name()
                + " annotation is expected to be applied on class level. "
                + target
                + " is not a class");
        continue;
      }
      final ClassInfo sessionBeanClassInfo = (ClassInfo) target;
      // skip if it's not a valid class for session bean
      if (!assertSessionBeanClassValidity(sessionBeanClassInfo)) {
        continue;
      }
      final String ejbName = sessionBeanClassInfo.name().local();
      final AnnotationValue nameValue = sessionBeanAnnotation.value("name");
      final String beanName =
          nameValue == null || nameValue.asString().isEmpty() ? ejbName : nameValue.asString();
      final EnterpriseBeanMetaData beanMetaData =
          getEnterpriseBeanMetaData(deploymentUnit, beanName);
      final SessionBeanComponentDescription.SessionBeanType sessionBeanType;
      final String beanClassName;
      if (beanMetaData != null && beanMetaData instanceof SessionBeanMetaData) {
        sessionBeanType =
            override(
                annotatedSessionBeanType,
                descriptionOf(((SessionBeanMetaData) beanMetaData).getSessionType()));
      } else {
        sessionBeanType = annotatedSessionBeanType;
      }
      if (beanMetaData != null) {
        beanClassName =
            override(sessionBeanClassInfo.name().toString(), beanMetaData.getEjbClass());
      } else {
        beanClassName = sessionBeanClassInfo.name().toString();
      }

      final SessionBeanComponentDescription sessionBeanDescription;
      switch (sessionBeanType) {
        case STATELESS:
          sessionBeanDescription =
              new StatelessComponentDescription(
                  beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName);
          break;
        case STATEFUL:
          sessionBeanDescription =
              new StatefulComponentDescription(
                  beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName);
          break;
        case SINGLETON:
          sessionBeanDescription =
              new SingletonComponentDescription(
                  beanName, beanClassName, ejbJarDescription, deploymentUnitServiceName);
          break;
        default:
          throw new IllegalArgumentException("Unknown session bean type: " + sessionBeanType);
      }

      if (appclient) {
        deploymentUnit.addToAttachmentList(
            Attachments.ADDITIONAL_RESOLVABLE_COMPONENTS, sessionBeanDescription);
      } else {
        // Add this component description to module description
        ejbJarDescription.getEEModuleDescription().addComponent(sessionBeanDescription);
      }
    }

    EjbDeploymentMarker.mark(deploymentUnit);
  }