private void prepareProperties(PersistenceParser parser) {
    final Enumeration<?> e = System.getProperties().propertyNames();

    while (e.hasMoreElements()) {
      final Object key = e.nextElement();
      if (key instanceof String) {
        this.properties.put((String) key, System.getProperties().get(key));
      }
    }

    this.properties.putAll(parser.getProperties());
  }
  private Class<?>[] getValidatorsFor(PersistenceParser parser, String group) {

    final String groups = (String) parser.getProperties().get(group);
    if (StringUtils.isBlank(groups)) {
      return new Class[] {Default.class};
    }

    final Set<Class<?>> validationGroups = Sets.newHashSet();
    final Iterator<String> i = Splitter.on(",").trimResults().split(groups).iterator();
    while (i.hasNext()) {
      final String className = i.next();
      try {
        validationGroups.add(this.classloader.loadClass(className));
      } catch (final ClassNotFoundException e) {
        throw new PersistenceException("Cannot load class for validation group: " + className);
      }
    }

    return validationGroups.toArray(new Class[validationGroups.size()]);
  }
  private DataSourceProxy createDatasourceProxy(
      PersistenceParser parser,
      SqlLoggingType sqlLogging,
      long slowSqlThreshold,
      int jdbcFetchSize) {
    final boolean external =
        (parser.getJtaDataSource() != null) || (parser.getNonJtaDataSource() != null);
    if (parser.getJtaDataSource() != null) {
      return new DataSourceProxy(
          parser.getJtaDataSource(), external, sqlLogging, slowSqlThreshold, jdbcFetchSize);
    }
    if (parser.getNonJtaDataSource() != null) {
      return new DataSourceProxy(
          parser.getNonJtaDataSource(), external, sqlLogging, slowSqlThreshold, jdbcFetchSize);
    }

    if (this.dataSourcePool != null) {
      return new DataSourceProxy(
          this.dataSourcePool, external, sqlLogging, slowSqlThreshold, jdbcFetchSize);
    }
    return new DataSourceProxy(
        this.createDatasource0(parser), external, sqlLogging, slowSqlThreshold, jdbcFetchSize);
  }
  /**
   * @param name the name of the entity manager factory
   * @param parser the persistence parser
   * @since 2.0.0
   */
  public EntityManagerFactoryImpl(String name, PersistenceParser parser) {
    super();

    this.classloader = parser.getClassloader();
    this.prepareProperties(parser);

    final boolean hasValidators = parser.hasValidators();
    if (hasValidators) {
      this.validationFactory = this.createValidationFactory();
      this.persistValidators = this.getValidatorsFor(parser, JPASettings.PERSIST_VALIDATION_GROUP);
      this.updateValidators = this.getValidatorsFor(parser, JPASettings.UPDATE_VALIDATION_GROUP);
      this.removeValidators = this.getValidatorsFor(parser, JPASettings.REMOVE_VALIDATION_GROUP);
    } else {
      this.validationFactory = null;
      this.persistValidators = null;
      this.updateValidators = null;
      this.removeValidators = null;
    }

    try {
      this.maxFetchJoinDepth =
          this.getProperty(BJPASettings.MAX_FETCH_JOIN_DEPTH) != null
              ? //
              Integer.valueOf(((String) this.getProperty(BJPASettings.MAX_FETCH_JOIN_DEPTH)))
              : //
              BJPASettings.DEFAULT_MAX_FETCH_JOIN_DEPTH;
    } catch (final Exception e) {
      throw new IllegalArgumentException(
          "Illegal value "
              + this.getProperty(BJPASettings.SQL_LOGGING)
              + " for "
              + BJPASettings.SQL_LOGGING);
    }

    this.dataSource = this.createDatasource(name, parser);

    this.ddlMode = this.readDdlMode();

    this.jdbcAdaptor = this.createJdbcAdaptor();
    this.metamodel = new MetamodelImpl(this, this.jdbcAdaptor, parser.getMetadata());

    LinkManager.perform(this.metamodel);

    this.metamodel.checkTables();

    // drop all tables if ddl mode is drop
    if (this.ddlMode == DDLMode.DROP) {
      this.metamodel.dropAllTables(this.dataSource);
    }

    DdlManager.perform(this.dataSource, this.metamodel, this.ddlMode);

    this.metamodel.performSequencesDdl(this.dataSource, this.ddlMode);
    this.metamodel.performTableGeneratorsDdl(this.dataSource, this.ddlMode);

    this.metamodel.preFillGenerators(this.dataSource);
    this.criteriaBuilder = new CriteriaBuilderImpl(this.metamodel);

    NamedQueriesManager.perform(this.metamodel, this.criteriaBuilder);

    this.persistenceUtil = new PersistenceUnitUtilImpl(this);

    this.jdbcAdaptor.importSql(
        this.classloader,
        this.dataSource,
        (String) this.getProperties().get(BJPASettings.IMPORT_SQL));

    this.open = true;
  }