private static PersistenceUnitMetadata getPersistenceUnit(
      DeploymentUnit current, final String absolutePath, String puName) {
    final String path;
    if (absolutePath.startsWith("../")) {
      path = absolutePath.substring(3);
    } else {
      path = absolutePath;
    }
    final VirtualFile parent =
        current.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot().getParent();
    final VirtualFile resolvedPath = parent.getChild(path);

    List<ResourceRoot> resourceRoots =
        DeploymentUtils.allResourceRoots(DeploymentUtils.getTopDeploymentUnit(current));

    for (ResourceRoot resourceRoot : resourceRoots) {
      if (resourceRoot.getRoot().equals(resolvedPath)) {
        PersistenceUnitMetadataHolder holder =
            resourceRoot.getAttachment(PersistenceUnitMetadataHolder.PERSISTENCE_UNITS);
        if (holder != null) {
          for (PersistenceUnitMetadata pu : holder.getPersistenceUnits()) {
            if (traceEnabled) {
              ROOT_LOGGER.tracef(
                  "getPersistenceUnit check '%s' against pu '%s'",
                  puName, pu.getPersistenceUnitName());
            }
            if (pu.getPersistenceUnitName().equals(puName)) {
              if (traceEnabled) {
                ROOT_LOGGER.tracef(
                    "getPersistenceUnit matched '%s' against pu '%s'",
                    puName, pu.getPersistenceUnitName());
              }
              return pu;
            }
          }
        }
      }
    }

    throw MESSAGES.persistenceUnitNotFound(absolutePath, puName, current);
  }
  /*
   * When finding the default persistence unit, the first persistence unit encountered is returned.
   */
  private static PersistenceUnitMetadata findWithinDeployment(
      DeploymentUnit unit, String persistenceUnitName) {
    if (traceEnabled) {
      ROOT_LOGGER.tracef("pu findWithinDeployment searching for %s", persistenceUnitName);
    }

    for (ResourceRoot root : DeploymentUtils.allResourceRoots(unit)) {
      PersistenceUnitMetadataHolder holder =
          root.getAttachment(PersistenceUnitMetadataHolder.PERSISTENCE_UNITS);
      if (holder == null || holder.getPersistenceUnits() == null) {
        if (traceEnabled) {
          ROOT_LOGGER.tracef(
              "pu findWithinDeployment skipping empty pu holder for %s", persistenceUnitName);
        }
        continue;
      }

      ambiguousPUError(unit, persistenceUnitName, holder);
      persistenceUnitName = defaultPersistenceUnitName(persistenceUnitName, holder);

      for (PersistenceUnitMetadata persistenceUnit : holder.getPersistenceUnits()) {
        if (traceEnabled) {
          ROOT_LOGGER.tracef(
              "findWithinDeployment check '%s' against pu '%s'",
              persistenceUnitName, persistenceUnit.getPersistenceUnitName());
        }
        if (persistenceUnitName == null
            || persistenceUnitName.length() == 0
            || persistenceUnit.getPersistenceUnitName().equals(persistenceUnitName)) {
          if (traceEnabled) {
            ROOT_LOGGER.tracef(
                "findWithinDeployment matched '%s' against pu '%s'",
                persistenceUnitName, persistenceUnit.getPersistenceUnitName());
          }
          return persistenceUnit;
        }
      }
    }
    return null;
  }
  /**
   * We only allow a single deployment at a time to be run through the class path processor.
   *
   * <p>This is because if multiple sibling deployments reference the same item we need to make sure
   * that they end up with the same external module, and do not both create an external module with
   * the same name.
   */
  public synchronized void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();

    final DeploymentUnit parent = deploymentUnit.getParent();
    final DeploymentUnit topLevelDeployment = parent == null ? deploymentUnit : parent;
    final VirtualFile topLevelRoot =
        topLevelDeployment.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();
    final ExternalModuleService externalModuleService =
        topLevelDeployment.getAttachment(Attachments.EXTERNAL_MODULE_SERVICE);
    final ResourceRoot deploymentRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT);

    // These are resource roots that are already accessible by default
    // such as ear/lib jars an web-inf/lib jars
    final Set<VirtualFile> existingAccessibleRoots = new HashSet<VirtualFile>();

    final Map<VirtualFile, ResourceRoot> subDeployments = new HashMap<VirtualFile, ResourceRoot>();
    for (ResourceRoot root : DeploymentUtils.allResourceRoots(topLevelDeployment)) {
      if (SubDeploymentMarker.isSubDeployment(root)) {
        subDeployments.put(root.getRoot(), root);
      } else if (ModuleRootMarker.isModuleRoot(root)) {
        // top level module roots are already accessible, as they are either
        // ear/lib jars, or jars that are already part of the deployment
        existingAccessibleRoots.add(root.getRoot());
      }
    }

    final ArrayDeque<RootEntry> resourceRoots = new ArrayDeque<RootEntry>();
    if (deploymentUnit.getParent() != null) {
      // top level deployments already had their exiting roots processed above
      for (ResourceRoot root : DeploymentUtils.allResourceRoots(deploymentUnit)) {

        if (ModuleRootMarker.isModuleRoot(root)) {
          // if this is a sub deployment of an ear we need to make sure we don't
          // re-add existing module roots as class path entries
          // this will mainly be WEB-INF/(lib|classes) entries
          existingAccessibleRoots.add(root.getRoot());
        }
      }
    }

    for (ResourceRoot root : DeploymentUtils.allResourceRoots(deploymentUnit)) {
      // add this to the list of roots to be processed
      resourceRoots.add(new RootEntry(deploymentUnit, root));
    }

    // build a map of the additional module locations
    // note that if a resource root has been added to two different additional modules
    // and is then referenced via a Class-Path entry the behaviour is undefined
    final Map<VirtualFile, AdditionalModuleSpecification> additionalModules =
        new HashMap<VirtualFile, AdditionalModuleSpecification>();
    for (AdditionalModuleSpecification module :
        topLevelDeployment.getAttachmentList(Attachments.ADDITIONAL_MODULES)) {
      for (ResourceRoot additionalModuleResourceRoot : module.getResourceRoots()) {
        additionalModules.put(additionalModuleResourceRoot.getRoot(), module);
      }
    }

    // additional resource roots may be added as
    while (!resourceRoots.isEmpty()) {
      final RootEntry entry = resourceRoots.pop();
      final ResourceRoot resourceRoot = entry.resourceRoot;
      final Attachable target = entry.target;

      // if this is a top level deployment we do not want to process sub deployments
      if (SubDeploymentMarker.isSubDeployment(resourceRoot) && resourceRoot != deploymentRoot) {
        continue;
      }

      final String[] items = getClassPathEntries(resourceRoot);
      for (final String item : items) {
        if (item.isEmpty()) {
          continue;
        }
        // first try and resolve relative to the manifest resource root
        final VirtualFile classPathFile = resourceRoot.getRoot().getParent().getChild(item);
        // then resolve relative to the deployment root
        final VirtualFile topLevelClassPathFile =
            deploymentRoot.getRoot().getParent().getChild(item);
        if (item.startsWith("/")) {
          if (externalModuleService.isValid(item)) {
            final ModuleIdentifier moduleIdentifier = externalModuleService.addExternalModule(item);
            target.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, moduleIdentifier);
            ServerLogger.DEPLOYMENT_LOGGER.debugf(
                "Resource %s added as external jar %s", classPathFile, resourceRoot.getRoot());
          } else {
            ServerLogger.DEPLOYMENT_LOGGER.classPathEntryNotValid(
                item, resourceRoot.getRoot().getPathName());
          }
        } else {
          if (classPathFile.exists()) {
            // we need to check that this class path item actually lies within the deployment
            boolean found = false;
            VirtualFile file = classPathFile.getParent();
            while (file != null) {
              if (file.equals(topLevelRoot)) {
                found = true;
              }
              file = file.getParent();
            }
            if (!found) {
              ServerLogger.DEPLOYMENT_LOGGER.classPathEntryNotValid(
                  item, resourceRoot.getRoot().getPathName());
            } else {
              handlingExistingClassPathEntry(
                  deploymentUnit,
                  resourceRoots,
                  topLevelDeployment,
                  topLevelRoot,
                  subDeployments,
                  additionalModules,
                  existingAccessibleRoots,
                  resourceRoot,
                  target,
                  classPathFile);
            }
          } else if (topLevelClassPathFile.exists()) {
            boolean found = false;
            VirtualFile file = topLevelClassPathFile.getParent();
            while (file != null) {
              if (file.equals(topLevelRoot)) {
                found = true;
              }
              file = file.getParent();
            }
            if (!found) {
              ServerLogger.DEPLOYMENT_LOGGER.classPathEntryNotValid(
                  item, resourceRoot.getRoot().getPathName());
            } else {
              handlingExistingClassPathEntry(
                  deploymentUnit,
                  resourceRoots,
                  topLevelDeployment,
                  topLevelRoot,
                  subDeployments,
                  additionalModules,
                  existingAccessibleRoots,
                  resourceRoot,
                  target,
                  topLevelClassPathFile);
            }
          } else {
            ServerLogger.DEPLOYMENT_LOGGER.classPathEntryNotValid(
                item, resourceRoot.getRoot().getPathName());
          }
        }
      }
    }
  }
 /** {@inheritDoc} */
 public void deploy(final DeploymentPhaseContext phaseContext)
     throws DeploymentUnitProcessingException {
   final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
   final List<ResourceRoot> resourceRoots = DeploymentUtils.allResourceRoots(deploymentUnit);
   for (ResourceRoot resourceRoot : resourceRoots) {
     final Manifest manifest = resourceRoot.getAttachment(Attachments.MANIFEST);
     if (manifest == null) {
       // no class path to process!
       continue;
     }
     final Attributes mainAttributes = manifest.getMainAttributes();
     final String extensionListString = mainAttributes.getValue(EXTENSION_LIST);
     if (extensionListString == null) {
       // no entry
       continue;
     }
     final String[] items = extensionListString.split("\\s+");
     boolean added = false;
     for (String item : items) {
       final String extensionName = mainAttributes.getValue(item + "-" + EXTENSION_NAME);
       if (extensionName == null) {
         ServerLogger.DEPLOYMENT_LOGGER.extensionMissingManifestAttribute(
             item, item, EXTENSION_NAME);
         continue;
       }
       final String specificationVersion =
           mainAttributes.getValue(item + "-" + SPECIFICATION_VERSION);
       final String implementationVersion =
           mainAttributes.getValue(item + "-" + IMPLEMENTATION_VERSION);
       final String implementationVendorId =
           mainAttributes.getValue(item + "-" + IMPLEMENTATION_VENDOR_ID);
       final String implementationUrl = mainAttributes.getValue(item + "-" + IMPLEMENTATION_URL);
       URI implementationUri = null;
       if (implementationUrl == null) {
         ServerLogger.DEPLOYMENT_LOGGER.debugf(
             "Extension %s is missing the required manifest attribute %s-%s",
             item, item, IMPLEMENTATION_URL);
       } else {
         try {
           implementationUri = new URI(implementationUrl);
         } catch (URISyntaxException e) {
           ServerLogger.DEPLOYMENT_LOGGER.invalidExtensionURI(item, e);
         }
       }
       resourceRoot.addToAttachmentList(
           Attachments.EXTENSION_LIST_ENTRIES,
           new ExtensionListEntry(
               item,
               extensionName,
               specificationVersion,
               implementationVersion,
               implementationVendorId,
               implementationUri));
       added = true;
     }
     if (added) {
       // Require the extension list before we proceed
       phaseContext.addToAttachmentList(
           Attachments.NEXT_PHASE_DEPS, Services.JBOSS_DEPLOYMENT_EXTENSION_INDEX);
     }
   }
 }
  /** {@inheritDoc} */
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final List<ResourceRoot> resourceRoots = DeploymentUtils.allResourceRoots(deploymentUnit);

    if (!DeploymentTypeMarker.isType(DeploymentType.EAR, deploymentUnit)) {
      return;
    }

    final DeploymentUnit parent = deploymentUnit.getParent();
    final DeploymentUnit topLevelDeployment = parent == null ? deploymentUnit : parent;
    final VirtualFile toplevelRoot =
        topLevelDeployment.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot();
    final ExternalModuleService externalModuleService =
        topLevelDeployment.getAttachment(Attachments.EXTERNAL_MODULE_SERVICE);

    final Map<VirtualFile, ResourceRoot> files = new HashMap<VirtualFile, ResourceRoot>();
    for (ResourceRoot resourceRoot : resourceRoots) {
      files.put(resourceRoot.getRoot(), resourceRoot);
    }
    final Deque<ResourceRoot> libResourceRoots = new ArrayDeque<ResourceRoot>();
    // scan /lib entries for class-path items
    for (ResourceRoot resourceRoot : resourceRoots) {
      if (ModuleRootMarker.isModuleRoot(resourceRoot)
          && !SubDeploymentMarker.isSubDeployment(resourceRoot)) {
        libResourceRoots.add(resourceRoot);
      }
    }
    while (!libResourceRoots.isEmpty()) {
      final ResourceRoot resourceRoot = libResourceRoots.pop();
      final String[] items = getClassPathEntries(resourceRoot);
      for (String item : items) {
        final VirtualFile classPathFile = resourceRoot.getRoot().getParent().getChild(item);
        if (!classPathFile.exists()) {
          log.warnf("Class Path entry %s in %s not found. ", item, resourceRoot.getRoot());
        } else if (isInside(classPathFile, toplevelRoot)) {
          if (!files.containsKey(classPathFile)) {
            log.warnf(
                "Class Path entry %s in %s does not point to a valid jar for a Class-Path reference.",
                item, resourceRoot.getRoot());
          } else {
            final ResourceRoot target = files.get(classPathFile);
            if (SubDeploymentMarker.isSubDeployment(target)) {
              // for now we do not allow ear Class-Path references to subdeployments
              log.warnf(
                  "Class Path entry  in "
                      + resourceRoot.getRoot()
                      + "  may not point to a sub deployment.");
            } else if (!ModuleRootMarker.isModuleRoot(target)) {
              // otherwise just add it to the lib dir
              ModuleRootMarker.mark(target);
              libResourceRoots.push(target);
              log.debugf(
                  "Resource %s added to logical lib directory due to Class-Path entry in %s",
                  classPathFile, target.getRoot());
            }
            // otherwise it is already part of lib, so we leave it alone for now
          }
        } else if (item.startsWith("/")) {
          ModuleIdentifier moduleIdentifier = externalModuleService.addExternalModule(item);
          deploymentUnit.addToAttachmentList(Attachments.CLASS_PATH_ENTRIES, moduleIdentifier);
          log.debugf("Resource %s added as external jar %s", classPathFile, resourceRoot.getRoot());
        } else {
          // this is a dep on another deployment
          deploymentUnit.addToAttachmentList(
              Attachments.CLASS_PATH_ENTRIES,
              ModuleIdentifier.create(ServiceModuleLoader.MODULE_PREFIX + classPathFile.getName()));
        }
      }
    }
  }