/**
   * Check the autoCommit and Transaction Isolation levels of the DataSource.
   *
   * <p>If autoCommit is true this could be a real problem.
   *
   * <p>If the Isolation level is not READ_COMMITED then optimistic concurrency checking may not
   * work as expected.
   */
  private boolean checkDataSource(ServerConfig serverConfig) {

    if (serverConfig.getDataSource() == null) {
      if (serverConfig.getDataSourceConfig().isOffline()) {
        // this is ok - offline DDL generation etc
        return false;
      }
      throw new RuntimeException("DataSource not set?");
    }

    Connection c = null;
    try {
      c = serverConfig.getDataSource().getConnection();

      if (c.getAutoCommit()) {
        String m = "DataSource [" + serverConfig.getName() + "] has autoCommit defaulting to true!";
        logger.warning(m);
      }

      return true;

    } catch (SQLException ex) {
      throw new PersistenceException(ex);

    } finally {
      if (c != null) {
        try {
          c.close();
        } catch (SQLException ex) {
          logger.log(Level.SEVERE, null, ex);
        }
      }
    }
  }
  private SpiBackgroundExecutor createBackgroundExecutor(
      ServerConfig serverConfig, int uniqueServerId) {

    String namePrefix = "Ebean-" + serverConfig.getName();

    // the size of the pool for executing periodic tasks (such as cache
    // flushing)
    int schedulePoolSize = GlobalProperties.getInt("backgroundExecutor.schedulePoolsize", 1);

    // the side of the main pool for immediate background task execution
    int minPoolSize = GlobalProperties.getInt("backgroundExecutor.minPoolSize", 1);
    int poolSize = GlobalProperties.getInt("backgroundExecutor.poolsize", 20);
    int maxPoolSize = GlobalProperties.getInt("backgroundExecutor.maxPoolSize", poolSize);

    int idleSecs = GlobalProperties.getInt("backgroundExecutor.idlesecs", 60);
    int shutdownSecs = GlobalProperties.getInt("backgroundExecutor.shutdownSecs", 30);

    boolean useTrad = GlobalProperties.getBoolean("backgroundExecutor.traditional", true);

    if (useTrad) {
      // this pool will use Idle seconds between min and max so I think it is
      // better
      // as it will let the thread count float between the min and max
      ThreadPool pool = ThreadPoolManager.getThreadPool(namePrefix);
      pool.setMinSize(minPoolSize);
      pool.setMaxSize(maxPoolSize);
      pool.setMaxIdleTime(idleSecs * 1000);
      return new TraditionalBackgroundExecutor(pool, schedulePoolSize, shutdownSecs, namePrefix);
    } else {
      return new DefaultBackgroundExecutor(
          poolSize, schedulePoolSize, idleSecs, shutdownSecs, namePrefix);
    }
  }
  /** Set the DatabasePlatform if it has not already been set. */
  private void setDatabasePlatform(ServerConfig config) {

    DatabasePlatform dbPlatform = config.getDatabasePlatform();
    if (dbPlatform == null) {

      DatabasePlatformFactory factory = new DatabasePlatformFactory();

      DatabasePlatform db = factory.create(config);
      config.setDatabasePlatform(db);
      logger.info("DatabasePlatform name:" + config.getName() + " platform:" + db.getName());
    }
  }
  private DataSource getDataSourceFromConfig(ServerConfig config) {

    DataSource ds = null;

    if (config.getDataSourceJndiName() != null) {
      ds = jndiDataSourceFactory.lookup(config.getDataSourceJndiName());
      if (ds == null) {
        String m =
            "JNDI lookup for DataSource " + config.getDataSourceJndiName() + " returned null.";
        throw new PersistenceException(m);
      } else {
        return ds;
      }
    }

    DataSourceConfig dsConfig = config.getDataSourceConfig();
    if (dsConfig == null) {
      String m = "No DataSourceConfig definded for " + config.getName();
      throw new PersistenceException(m);
    }

    if (dsConfig.isOffline()) {
      if (config.getDatabasePlatformName() == null) {
        String m = "You MUST specify a DatabasePlatformName on ServerConfig when offline";
        throw new PersistenceException(m);
      }
      return null;
    }

    if (dsConfig.getHeartbeatSql() == null) {
      // use default heartbeatSql from the DatabasePlatform
      String heartbeatSql = getHeartbeatSql(dsConfig.getDriver());
      dsConfig.setHeartbeatSql(heartbeatSql);
    }

    return DataSourceGlobalManager.getDataSource(config.getName(), dsConfig);
  }
  /** Create using the ServerConfig object to configure the server. */
  public static EbeanServer create(ServerConfig config) {

    if (config.getName() == null) {
      throw new PersistenceException("The name is null (it is required)");
    }

    EbeanServer server = serverFactory.createServer(config);

    if (config.isDefaultServer()) {
      GlobalProperties.setSkipPrimaryServer(true);
    }
    if (config.isRegister()) {
      Ebean.register(server, config.isDefaultServer());
    }

    return server;
  }