/**
  * Find PersistenceUnitInfo corresponding to the persistence unit name. Returns null if either
  * persistence unit either not found or provider is not supported.
  */
 protected SEPersistenceUnitInfo findPersistenceUnitInfoInArchives(String puName, Map m) {
   SEPersistenceUnitInfo persistenceUnitInfo = null;
   // mkeith - get resource name from prop and include in subsequent call
   String descriptorPath = (String) m.get(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML);
   final Set<Archive> pars;
   if (descriptorPath != null) {
     pars =
         PersistenceUnitProcessor.findPersistenceArchives(
             initializationClassloader, descriptorPath);
   } else {
     pars = PersistenceUnitProcessor.findPersistenceArchives(initializationClassloader);
   }
   try {
     for (Archive archive : pars) {
       persistenceUnitInfo = findPersistenceUnitInfoInArchive(puName, archive, m);
       if (persistenceUnitInfo != null) {
         break;
       }
     }
   } finally {
     for (Archive archive : pars) {
       archive.close();
     }
   }
   return persistenceUnitInfo;
 }
 /**
  * This method initializes the container. Essentially, it will try to load the class that contains
  * the list of entities and reflectively call the method that contains that list. It will then
  * initialize the container with that list.
  */
 public void initialize(Map m) {
   boolean keepInitialMaps = keepAllPredeployedPersistenceUnits();
   if (keepInitialMaps) {
     this.initialPuInfos = new HashMap();
   }
   // always create initialEmSetupImpls - it's used to check for puName uniqueness in
   // initPersistenceUnits
   this.initialEmSetupImpls = new HashMap();
   // ailitchev - copied from findPersistenceUnitInfoInArchives: mkeith - get resource name from
   // prop and include in subsequent call
   String descriptorPath = (String) m.get(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML);
   final Set<Archive> pars;
   if (descriptorPath != null) {
     pars =
         PersistenceUnitProcessor.findPersistenceArchives(
             initializationClassloader, descriptorPath);
   } else {
     pars = PersistenceUnitProcessor.findPersistenceArchives(initializationClassloader);
   }
   try {
     for (Archive archive : pars) {
       AbstractSessionLog.getLog().log(SessionLog.FINER, "cmp_init_initialize", archive);
       initPersistenceUnits(archive, m);
     }
   } finally {
     for (Archive archive : pars) {
       archive.close();
     }
     this.initialEmSetupImpls = null;
   }
 }
  /**
   * 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;
  }
  public static Set<String> getClassNamesFromURL(URL url, ClassLoader loader, Map properties) {
    Set<String> classNames = new HashSet<String>();
    Archive archive = null;
    try {
      archive = PersistenceUnitProcessor.getArchiveFactory(loader).createArchive(url, properties);

      if (archive != null) {
        for (Iterator<String> entries = archive.getEntries(); entries.hasNext(); ) {
          String entry = entries.next();
          if (entry.endsWith(".class")) { // NOI18N
            classNames.add(buildClassNameFromEntryString(entry));
          }
        }
      }
    } catch (URISyntaxException e) {
      throw new RuntimeException("url = [" + url + "]", e); // NOI18N
    } catch (IOException e) {
      throw new RuntimeException("url = [" + url + "]", e); // NOI18N
    } finally {
      if (archive != null) {
        archive.close();
      }
    }
    return classNames;
  }
  /**
   * 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;
  }
  /** This is our chance to initialize any EclipseLink specific stuff */
  public void initialize() {
    // Set the static so initializer instances can get stuff from it
    GeminiOSGiInitializer.setManager(mgr);

    // Set to our own archive factory
    PersistenceUnitProcessor.setArchiveFactory(new OSGiArchiveFactoryImpl());

    // If EL logging property was specified then open the log now?
    openEclipseLinkLogFileIfSpecified();
  }
 /**
  * Find PersistenceUnitInfo corresponding to the persistence unit name in the archive. Returns
  * null if either persistence unit either not found or provider is not supported.
  */
 protected SEPersistenceUnitInfo findPersistenceUnitInfoInArchive(
     String puName, Archive archive, Map m) {
   Iterator<SEPersistenceUnitInfo> persistenceUnits =
       PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader).iterator();
   while (persistenceUnits.hasNext()) {
     SEPersistenceUnitInfo persistenceUnitInfo = persistenceUnits.next();
     if (isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName())
         && persistenceUnitInfo.getPersistenceUnitName().equals(puName)) {
       return persistenceUnitInfo;
     }
   }
   return null;
 }
  /**
   * Initialize all persistence units found on initializationClassLoader. Initialization is a two
   * phase process. First the predeploy process builds the metadata and creates any required
   * transformers. Second the deploy process creates an EclipseLink session based on that metadata.
   */
  protected void initPersistenceUnits(Archive archive, Map m) {
    Iterator<SEPersistenceUnitInfo> persistenceUnits =
        PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader).iterator();
    while (persistenceUnits.hasNext()) {
      SEPersistenceUnitInfo persistenceUnitInfo = persistenceUnits.next();
      if (isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName())) {
        // puName uniquely defines the pu on a class loader
        String puName = persistenceUnitInfo.getPersistenceUnitName();

        // don't add puInfo that could not be used standalone (only as composite member).
        if (EntityManagerSetupImpl.mustBeCompositeMember(persistenceUnitInfo)) {
          continue;
        }

        // If puName is already in the map then there are two jars containing persistence units with
        // the same name.
        // Because both are loaded from the same classloader there is no way to distinguish between
        // them - throw exception.
        EntityManagerSetupImpl anotherEmSetupImpl = null;
        if (initialEmSetupImpls != null) {
          anotherEmSetupImpl = this.initialEmSetupImpls.get(puName);
        }
        if (anotherEmSetupImpl != null) {
          EntityManagerSetupImpl.throwPersistenceUnitNameAlreadyInUseException(
              puName, persistenceUnitInfo, anotherEmSetupImpl.getPersistenceUnitInfo());
        }

        // Note that session name is extracted only from puInfo, the passed properties ignored.
        String sessionName =
            EntityManagerSetupImpl.getOrBuildSessionName(
                Collections.emptyMap(), persistenceUnitInfo, puName);
        EntityManagerSetupImpl emSetupImpl =
            callPredeploy(persistenceUnitInfo, m, puName, sessionName);
        if (initialEmSetupImpls != null) {
          this.initialEmSetupImpls.put(puName, emSetupImpl);
        }
        if (initialPuInfos != null) {
          this.initialPuInfos.put(puName, persistenceUnitInfo);
        }
      }
    }
  }
  /**
   * predeploy (with deploy) is one of the two steps required in deployment of entities This method
   * will prepare to call predeploy, call it and finally register the transformer returned to be
   * used for weaving.
   */
  public EntityManagerSetupImpl callPredeploy(
      SEPersistenceUnitInfo persistenceUnitInfo,
      Map m,
      String persistenceUnitUniqueName,
      String sessionName) {
    AbstractSessionLog.getLog()
        .log(
            SessionLog.FINER,
            "cmp_init_invoke_predeploy",
            persistenceUnitInfo.getPersistenceUnitName());
    Map mergedProperties =
        EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties());
    // Bug#4452468  When globalInstrumentation is null, there is no weaving
    checkWeaving(mergedProperties);

    Set tempLoaderSet = PersistenceUnitProcessor.buildClassSet(persistenceUnitInfo, m);
    // Create the temp loader that will not cache classes for entities in our persistence unit
    ClassLoader tempLoader = createTempLoader(tempLoaderSet);
    persistenceUnitInfo.setNewTempClassLoader(tempLoader);

    EntityManagerSetupImpl emSetupImpl =
        new EntityManagerSetupImpl(persistenceUnitUniqueName, sessionName);

    // A call to predeploy will partially build the session we will use
    final ClassTransformer transformer =
        emSetupImpl.predeploy(persistenceUnitInfo, mergedProperties);

    // After preDeploy it's impossible to weave again - so may substitute the temporary classloader
    // with the real one.
    // The temporary classloader could be garbage collected even if the puInfo is cached for the
    // future use by other emSetupImpls.
    persistenceUnitInfo.setNewTempClassLoader(persistenceUnitInfo.getClassLoader());

    registerTransformer(transformer, persistenceUnitInfo, m);
    return emSetupImpl;
  }
  @Override
  public void buildSessions() {
    XRDynamicClassLoader xrdecl = new XRDynamicClassLoader(parentClassLoader);
    DatasourceLogin login = new DatabaseLogin();
    login.setUserName(username);
    login.setPassword(password);
    ((DatabaseLogin) login).setConnectionString(url);
    ((DatabaseLogin) login).setDriverClassName(DATABASE_PLATFORM);
    Platform platform = builder.getDatabasePlatform();
    ConversionManager conversionManager = platform.getConversionManager();
    if (conversionManager != null) {
      conversionManager.setLoader(xrdecl);
    }
    login.setDatasourcePlatform(platform);
    ((DatabaseLogin) login).bindAllParameters();
    ((DatabaseLogin) login).setUsesStreamsForBinding(true);

    Project orProject = null;
    if (DBWS_OR_STREAM.size() != 0) {
      MetadataProcessor processor =
          new MetadataProcessor(
              new XRPersistenceUnitInfo(xrdecl),
              new DatabaseSessionImpl(login),
              xrdecl,
              false,
              true,
              false,
              false,
              false,
              null,
              null);
      processor.setMetadataSource(
          new JPAMetadataSource(xrdecl, new StringReader(DBWS_OR_STREAM.toString())));
      PersistenceUnitProcessor.processORMetadata(
          processor, true, PersistenceUnitProcessor.Mode.ALL);
      processor.addNamedQueries();
      orProject = processor.getProject().getProject();
    } else {
      orProject = new Project();
    }
    orProject.setName(builder.getProjectName().concat(OR_PRJ_SUFFIX));
    orProject.setDatasourceLogin(login);
    DatabaseSession databaseSession = orProject.createDatabaseSession();
    if ("off".equalsIgnoreCase(builder.getLogLevel())) {
      databaseSession.dontLogMessages();
    } else {
      databaseSession.setLogLevel(
          AbstractSessionLog.translateStringToLoggingLevel(builder.getLogLevel()));
    }
    xrService.setORSession(databaseSession);
    orProject.convertClassNamesToClasses(xrdecl);

    Project oxProject = null;
    Map<String, OXMMetadataSource> metadataMap = new HashMap<String, OXMMetadataSource>();
    StreamSource xml = new StreamSource(new StringReader(DBWS_OX_STREAM.toString()));
    try {
      JAXBContext jc = JAXBContext.newInstance(XmlBindingsModel.class);
      Unmarshaller unmarshaller = jc.createUnmarshaller();

      JAXBElement<XmlBindingsModel> jaxbElt = unmarshaller.unmarshal(xml, XmlBindingsModel.class);
      XmlBindingsModel model = jaxbElt.getValue();
      for (XmlBindings xmlBindings : model.getBindingsList()) {
        metadataMap.put(xmlBindings.getPackageName(), new OXMMetadataSource(xmlBindings));
      }
    } catch (JAXBException jaxbex) {
      jaxbex.printStackTrace();
    }

    Map<String, Map<String, OXMMetadataSource>> properties =
        new HashMap<String, Map<String, OXMMetadataSource>>();
    properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataMap);
    try {
      org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext jCtx =
          org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory.createContextFromOXM(
              parentClassLoader, properties);
      oxProject = jCtx.getXMLContext().getSession(0).getProject();
    } catch (JAXBException e) {
      e.printStackTrace();
    }
    ((XMLLogin) oxProject.getDatasourceLogin()).setPlatformClassName(DOM_PLATFORM_CLASSNAME);
    ((XMLLogin) oxProject.getDatasourceLogin()).setEqualNamespaceResolvers(false);

    prepareDescriptors(oxProject, orProject, xrdecl);
    ProjectHelper.fixOROXAccessors(orProject, oxProject);
    xrService.setORSession(databaseSession);
    xrService.setXMLContext(new XMLContext(oxProject));
    xrService.setOXSession(xrService.getXMLContext().getSession(0));
  }
 /**
  * In case persistence unit is not uniquely defined by name this method is called to generate a
  * unique name.
  */
 public String createUniquePersistenceUnitName(PersistenceUnitInfo puInfo) {
   return PersistenceUnitProcessor.buildPersistenceUnitName(
       puInfo.getPersistenceUnitRootUrl(), puInfo.getPersistenceUnitName());
 }
  /** INTERNAL: The method performs weaving function */
  private void process() throws IOException, URISyntaxException {
    // Instantiate output handler.
    AbstractStaticWeaveOutputHandler swoh;
    if (isDirectory(this.target)) {
      swoh = new StaticWeaveDirectoryOutputHandler(this.source, this.target);
    } else {
      swoh =
          new StaticWeaveJAROutputHandler(
              new JarOutputStream(new FileOutputStream(new File(Helper.toURI(this.target)))));
    }

    // Instantiate classloader.
    this.classLoader =
        (this.classLoader == null)
            ? Thread.currentThread().getContextClassLoader()
            : this.classLoader;
    this.classLoader = new URLClassLoader(getURLs(), this.classLoader);

    // Instantiate the classtransformer, we check if the persistenceinfo URL has been specified.
    StaticWeaveClassTransformer classTransformer = null;
    if (persistenceInfo != null) {
      classTransformer =
          new StaticWeaveClassTransformer(
              persistenceInfo,
              persistenceXMLLocation,
              this.classLoader,
              this.logWriter,
              this.logLevel);
    } else {
      classTransformer =
          new StaticWeaveClassTransformer(
              source, persistenceXMLLocation, this.classLoader, this.logWriter, this.logLevel);
    }

    // Starting process.
    Archive sourceArchive = (new ArchiveFactoryImpl()).createArchive(source, null, null);
    if (sourceArchive != null) {
      try {
        Iterator entries = sourceArchive.getEntries();
        while (entries.hasNext()) {
          String entryName = (String) entries.next();
          InputStream entryInputStream = sourceArchive.getEntry(entryName);

          // Add a directory entry
          swoh.addDirEntry(getDirectoryFromEntryName(entryName));

          // Add a regular entry
          JarEntry newEntry = new JarEntry(entryName);

          // Ignore non-class files.
          if (!(entryName.endsWith(".class"))) {
            swoh.addEntry(entryInputStream, newEntry);
            continue;
          }

          String className = PersistenceUnitProcessor.buildClassNameFromEntryString(entryName);

          byte[] originalClassBytes = null;
          byte[] transferredClassBytes = null;
          try {
            Class thisClass = this.classLoader.loadClass(className);
            // If the class is not in the classpath, we simply copy the entry
            // to the target(no weaving).
            if (thisClass == null) {
              swoh.addEntry(entryInputStream, newEntry);
              continue;
            }

            // Try to read the loaded class bytes, the class bytes is required for
            // classtransformer to perform transfer. Simply copy entry to the target(no weaving)
            // if the class bytes can't be read.
            InputStream is = this.classLoader.getResourceAsStream(entryName);
            if (is != null) {
              ByteArrayOutputStream baos = null;
              try {
                baos = new ByteArrayOutputStream();
                byte[] bytes = new byte[NUMBER_OF_BYTES];
                int bytesRead = is.read(bytes, 0, NUMBER_OF_BYTES);
                while (bytesRead >= 0) {
                  baos.write(bytes, 0, bytesRead);
                  bytesRead = is.read(bytes, 0, NUMBER_OF_BYTES);
                }
                originalClassBytes = baos.toByteArray();
              } finally {
                baos.close();
              }
            } else {
              swoh.addEntry(entryInputStream, newEntry);
              continue;
            }

            // If everything is OK so far, we perform the weaving. we need three parameters in order
            // to
            // class to perform weaving for that class, the class name,the class object and class
            // bytes.
            transferredClassBytes =
                classTransformer.transform(
                    className.replace('.', '/'), thisClass, originalClassBytes);

            // If transferredClassBytes is null means the class dose not get woven.
            if (transferredClassBytes != null) {
              swoh.addEntry(newEntry, transferredClassBytes);
            } else {
              swoh.addEntry(entryInputStream, newEntry);
            }
          } catch (IllegalClassFormatException e) {
            AbstractSessionLog.getLog().logThrowable(AbstractSessionLog.WARNING, e);
            // Anything went wrong, we need log a warning message, copy the entry to the target and
            // process next entry.
            swoh.addEntry(entryInputStream, newEntry);
            continue;
          } catch (ClassNotFoundException e) {
            AbstractSessionLog.getLog().logThrowable(AbstractSessionLog.WARNING, e);
            swoh.addEntry(entryInputStream, newEntry);
            continue;
          } finally {
            // Need close the inputstream for current entry before processing next one.
            entryInputStream.close();
          }
        }
      } finally {
        sourceArchive.close();
        swoh.closeOutputStream();
      }
    }
  }