/**
   * Creates the group in the database using the given group instance. The group instance can
   * include sub items such as sections and questions. Those sub items will be persisted as well.
   * The operator parameter is used as the creation/modification user of the group and its subitems.
   * The creation date and modification date will be the current date time when the group is
   * created.
   *
   * @param group The group instance to be created in the database.
   * @param order the sort order of this group.
   * @param operator The creation user of this group.
   * @param parentId The id of the scorecard that contains this.
   * @throws IllegalArgumentException if any input is null or the operator is empty string.
   * @throws PersistenceException if error occurred while accessing the database.
   */
  public void createGroup(Group group, int order, String operator, long parentId)
      throws PersistenceException {
    if (group == null) {
      throw new IllegalArgumentException("group cannot be null.");
    }
    if (operator == null) {
      throw new IllegalArgumentException("operator cannot be null.");
    }

    if (operator.trim().length() == 0) {
      throw new IllegalArgumentException("operator cannot be empty String.");
    }

    logger.log(
        Level.INFO,
        new LogMessage(
            "Group",
            null,
            operator,
            "create new Group with order:" + order + " and parentId:" + parentId));
    // get next id
    long groupId = DBUtils.nextId(IdGeneratorUtility.getGroupIdGenerator());
    Timestamp time = new Timestamp(System.currentTimeMillis());
    // create section persistence
    InformixSectionPersistence sectionPersistence = new InformixSectionPersistence(connection);
    PreparedStatement pstmt = null;

    logger.log(Level.INFO, "insert record into scorecard_group with group_id:" + groupId);
    try {
      // create statement
      pstmt = connection.prepareStatement(INSERT_SCORECARD_GROUP);

      // set the variables
      pstmt.setLong(1, groupId);
      pstmt.setLong(2, parentId);
      pstmt.setString(3, group.getName());
      pstmt.setFloat(4, group.getWeight());
      pstmt.setInt(5, order);

      pstmt.setString(6, operator);
      pstmt.setTimestamp(7, time);
      pstmt.setString(8, operator);
      pstmt.setTimestamp(9, time);

      // create group and create the sections
      pstmt.executeUpdate();
      sectionPersistence.createSections(group.getAllSections(), operator, groupId);
    } catch (SQLException ex) {
      logger.log(
          Level.ERROR,
          new LogMessage("Group", new Long(groupId), operator, "Fail to create Group.", ex));
      throw new PersistenceException("Error occur while creating the scorecard group.", ex);
    } finally {
      DBUtils.close(pstmt);
    }

    // set the group id.
    group.setId(groupId);
  }
  /**
   * Updates the group (the scorecard_group table) in the database.
   *
   * @param conn the database connection to be used.
   * @param group the groupt to update.
   * @param operator the update operator name.
   * @param parentId the parent of this group (scorecard id).
   * @param order the order of this group in the database.
   * @throws PersistenceException if any database error occurs.
   */
  private static void updateGroup(
      Connection conn, Group group, String operator, long parentId, int order)
      throws PersistenceException {

    logger.log(Level.INFO, "update scorecard_group with groupId:" + group.getId());
    PreparedStatement pstmt = null;
    try {
      // prepare the statement
      pstmt = conn.prepareStatement(UPDATE_SCORECARD_GROUP);

      // set the variables
      pstmt.setLong(1, parentId);
      pstmt.setString(2, group.getName());
      pstmt.setFloat(3, group.getWeight());
      pstmt.setInt(4, order);

      // set the modification user and time
      Timestamp time = new Timestamp(System.currentTimeMillis());
      pstmt.setString(5, operator);
      pstmt.setTimestamp(6, time);
      pstmt.setLong(7, group.getId());

      if (pstmt.executeUpdate() != 1) {
        logger.log(Level.ERROR, "No group with id = " + group.getId());
        throw new PersistenceException("No group with id = " + group.getId());
      }
    } catch (SQLException ex) {
      logger.log(
          Level.ERROR,
          new LogMessage(
              "Group",
              new Long(group.getId()),
              operator,
              "Error occurs while updating the group.",
              ex));
      throw new PersistenceException("Error occurs while updating the group.", ex);
    } finally {
      DBUtils.close(pstmt);
    }
  }