/**
   * Build a persistence.xml file into a SEPersistenceUnitInfo object. May eventually change this to
   * use OX mapping as well.
   */
  private static List<SEPersistenceUnitInfo> processPersistenceXML(
      URL baseURL, InputStream input, ClassLoader loader) {
    SAXParserFactory spf = XMLHelper.createParserFactory(false);

    XMLReader xmlReader = null;
    SAXParser sp = null;
    XMLExceptionHandler xmlErrorHandler = new XMLExceptionHandler();
    // 247735 - remove the validation of XML.

    // create a SAX parser
    try {
      sp = spf.newSAXParser();
    } catch (ParserConfigurationException | SAXException exc) {
      throw XMLParseException.exceptionCreatingSAXParser(baseURL, exc);
    }

    // create an XMLReader
    try {
      xmlReader = sp.getXMLReader();
      xmlReader.setErrorHandler(xmlErrorHandler);
    } catch (org.xml.sax.SAXException exc) {
      throw XMLParseException.exceptionCreatingXMLReader(baseURL, exc);
    }

    PersistenceContentHandler myContentHandler = new PersistenceContentHandler();
    xmlReader.setContentHandler(myContentHandler);

    InputSource inputSource = new InputSource(input);
    try {
      xmlReader.parse(inputSource);
    } catch (IOException exc) {
      throw PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(baseURL, exc);
    } catch (org.xml.sax.SAXException exc) {
      // XMLErrorHandler will handle SAX exceptions
    }

    // handle any parse exceptions
    XMLException xmlError = xmlErrorHandler.getXMLException();
    if (xmlError != null) {
      throw PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(baseURL, xmlError);
    }

    Iterator<SEPersistenceUnitInfo> persistenceInfos =
        myContentHandler.getPersistenceUnits().iterator();
    while (persistenceInfos.hasNext()) {
      SEPersistenceUnitInfo info = persistenceInfos.next();
      info.setPersistenceUnitRootUrl(baseURL);
      info.setClassLoader(loader);
      info.setNewTempClassLoader(loader);
    }
    return myContentHandler.getPersistenceUnits();
  }
  /**
   * Return a list of Archives representing the root of the persistence descriptor. It is the
   * caller's responsibility to close all the archives.
   *
   * @param loader the class loader to get the class path from
   */
  public static Set<Archive> findPersistenceArchives(
      ClassLoader loader, String descriptorPath, List<URL> jarFileUrls) {
    Archive archive = null;

    Set<Archive> archives = new HashSet<Archive>();

    // See if we are talking about an embedded descriptor
    // If not embedded descriptor then just use the regular descriptor path
    int splitPosition = descriptorPath.indexOf("!/");
    if (splitPosition != -1) {
      // It is an embedded archive, so split up the parts
      descriptorPath = descriptorPath.substring(splitPosition + 2);
    }

    try {
      for (int i = 0; i < jarFileUrls.size(); i++) {
        URL puRootUrl = jarFileUrls.get(i);
        archive =
            PersistenceUnitProcessor.getArchiveFactory(loader)
                .createArchive(puRootUrl, descriptorPath, null);

        // archive = new BundleArchive(puRootUrl, descUrl);
        if (archive != null) {
          archives.add(archive);
        }
      }
    } catch (Exception ex) {
      // clean up first
      for (Archive a : archives) {
        a.close();
      }
      throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(loader, ex);
    }
    return archives;
  }
  /** Load the given class name with the given class loader. */
  public static Class loadClass(
      String className,
      ClassLoader loader,
      boolean throwExceptionIfNotFound,
      MetadataProject project) {
    Class candidateClass = null;

    try {
      candidateClass = loader.loadClass(className);
    } catch (ClassNotFoundException exc) {
      if (throwExceptionIfNotFound) {
        throw PersistenceUnitLoadingException.exceptionLoadingClassWhileLookingForAnnotations(
            className, exc);
      } else {
        AbstractSessionLog.getLog()
            .log(
                AbstractSessionLog.WARNING,
                "persistence_unit_processor_error_loading_class",
                exc.getClass().getName(),
                exc.getLocalizedMessage(),
                className);
      }
    } catch (NullPointerException npe) {
      // Bug 227630: If any weavable class is not found in the temporary
      // classLoader - disable weaving
      AbstractSessionLog.getLog()
          .log(
              AbstractSessionLog.WARNING,
              AbstractSessionLog.WEAVER,
              "persistence_unit_processor_error_loading_class_weaving_disabled",
              loader,
              project.getPersistenceUnitInfo().getPersistenceUnitName(),
              className);
      // Disable weaving (for 1->1 and many->1)only if the classLoader
      // returns a NPE on loadClass()
      project.disableWeaving();
    } catch (Exception exception) {
      AbstractSessionLog.getLog()
          .log(
              AbstractSessionLog.WARNING,
              AbstractSessionLog.WEAVER,
              "persistence_unit_processor_error_loading_class",
              exception.getClass().getName(),
              exception.getLocalizedMessage(),
              className);
    } catch (Error error) {
      AbstractSessionLog.getLog()
          .log(
              AbstractSessionLog.WARNING,
              AbstractSessionLog.WEAVER,
              "persistence_unit_processor_error_loading_class",
              error.getClass().getName(),
              error.getLocalizedMessage(),
              className);
      throw error;
    }

    return candidateClass;
  }
 /**
  * Go through the jar file for this PersistenceUnitProcessor and process any XML provided in it.
  */
 public static List<SEPersistenceUnitInfo> processPersistenceArchive(
     Archive archive, ClassLoader loader) {
   URL puRootURL = archive.getRootURL();
   try {
     return processPersistenceXML(puRootURL, archive.getDescriptorStream(), loader);
   } catch (Exception e) {
     throw PersistenceUnitLoadingException.exceptionLoadingFromUrl(puRootURL.toString(), e);
   }
 }
 /**
  * Build the unique persistence name by concatenating the decoded URL with the persistence unit
  * name. A decoded URL is required while persisting on a multi-bytes OS.
  *
  * @param URL
  * @param puName
  * @return String
  */
 public static String buildPersistenceUnitName(URL url, String puName) {
   String fullPuName = null;
   try {
     // append the persistence unit name to the decoded URL
     fullPuName = URLDecoder.decode(url.toString(), "UTF8") + "_" + puName;
   } catch (UnsupportedEncodingException e) {
     throw PersistenceUnitLoadingException.couldNotBuildPersistenceUntiName(
         e, url.toString(), puName);
   }
   return fullPuName;
 }
  public static ArchiveFactory getArchiveFactory(ClassLoader loader) {
    if (ARCHIVE_FACTORY != null) {
      return ARCHIVE_FACTORY;
    }

    ArchiveFactory factory = null;
    String factoryClassName = System.getProperty(SystemProperties.ARCHIVE_FACTORY, null);

    if (factoryClassName == null) {
      return new ArchiveFactoryImpl();
    } else {
      try {
        if (loader != null) {
          Class archiveClass = loader.loadClass(factoryClassName);
          if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
            try {
              factory =
                  (ArchiveFactory)
                      AccessController.doPrivileged(
                          new PrivilegedNewInstanceFromClass(archiveClass));
            } catch (PrivilegedActionException exception) {
              throw PersistenceUnitLoadingException.exceptionCreatingArchiveFactory(
                  factoryClassName, exception);
            }
          } else {
            factory = (ArchiveFactory) PrivilegedAccessHelper.newInstanceFromClass(archiveClass);
          }
        }
      } catch (ClassNotFoundException cnfe) {
        throw PersistenceUnitLoadingException.exceptionCreatingArchiveFactory(
            factoryClassName, cnfe);
      } catch (IllegalAccessException iae) {
        throw PersistenceUnitLoadingException.exceptionCreatingArchiveFactory(
            factoryClassName, iae);
      } catch (InstantiationException ie) {
        throw PersistenceUnitLoadingException.exceptionCreatingArchiveFactory(factoryClassName, ie);
      }
    }

    return factory;
  }
  /**
   * Return a list of Archives representing the root of the persistence descriptor. It is the
   * caller's responsibility to close all the archives.
   *
   * @param loader the class loader to get the class path from
   */
  public static Set<Archive> findPersistenceArchives(ClassLoader loader, String descriptorPath) {
    Archive archive = null;

    Set<Archive> archives = new HashSet<Archive>();

    // See if we are talking about an embedded descriptor
    int splitPosition = descriptorPath.indexOf("!/");

    try {
      // If not embedded descriptor then just use the regular descriptor path
      if (splitPosition == -1) {
        Enumeration<URL> resources = loader.getResources(descriptorPath);
        while (resources.hasMoreElements()) {

          URL descUrl = resources.nextElement();
          if (descUrl != null) {
            URL puRootUrl = computePURootURL(descUrl, descriptorPath);
            archive =
                PersistenceUnitProcessor.getArchiveFactory(loader)
                    .createArchive(puRootUrl, descriptorPath, null);

            // archive = new BundleArchive(puRootUrl, descUrl);
            if (archive != null) {
              archives.add(archive);
            }
          }
        }
      } else {
        // It is an embedded archive, so split up the parts
        String jarPrefixPath = descriptorPath.substring(0, splitPosition);
        String descPath = descriptorPath.substring(splitPosition + 2);
        // TODO This causes the bundle to be resolved (not what we want)!
        URL prefixUrl = loader.getResource(jarPrefixPath);
        archive =
            PersistenceUnitProcessor.getArchiveFactory(loader)
                .createArchive(prefixUrl, descPath, null);

        if (archive != null) {
          archives.add(archive);
        }
      }
    } catch (Exception ex) {
      // clean up first
      for (Archive a : archives) {
        a.close();
      }
      throw PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(loader, ex);
    }
    return archives;
  }
 /**
  * INTERNAL:
  * translate validation group specified as fully qualifed class names deliminated by ',' into Class[]
  * @param validationGroups Array of "," deliminated fully qualified class names
  * @param appClassLoader The classloader for application
  * @return Array of classes corresponding to classnames in given <code>validationGroups</code>.
  *         <code>null<code> if given <code>validationGroups</code> is null or empty
  */
 private Class[] translateValidationGroups(String validationGroups, ClassLoader appClassLoader) {
   Class[] validationGroupsClasses = null;
   if (validationGroups != null && validationGroups.length() != 0) {
     String[] validationGroupClassNames = validationGroups.split(",");
     validationGroupsClasses = new Class[validationGroupClassNames.length];
     for (int i = 0; i < validationGroupClassNames.length; i++) {
       String validationGroupClassName = validationGroupClassNames[i];
       try {
         validationGroupsClasses[i] = loadClass(validationGroupClassName, appClassLoader);
       } catch (Exception e) {
         throw PersistenceUnitLoadingException
             .exceptionLoadingClassWhileInitializingValidationGroups(
                 validationGroupClassName, e);
       }
     }
   }
   return validationGroupsClasses;
 }