/**
   * @param group
   * @return
   * @throws Exception
   */
  @Override
  public String createGroup(Group group) throws Exception {
    Group specificGroup = new Group(group);
    try {
      // Set supergroup specific Id
      if (StringUtil.isDefined(group.getSuperGroupId())) {
        // Get the user information
        GroupRow gr = getOrganization().group.getGroup(idAsInt(group.getSuperGroupId()));
        if (gr == null) {
          throw new AdminException(
              "DomainDriverManager.createGroup",
              SilverpeasException.ERROR,
              "admin.EX_ERR_GROUP_NOT_FOUND",
              "group Id: '" + group.getSuperGroupId() + "'");
        }
        specificGroup.setSuperGroupId(gr.specificId);
      }
      // Set subUsers specific Id
      specificGroup.setUserIds(
          translateUserIdsToSpecificIds(idAsInt(group.getDomainId()), group.getUserIds()));
      // Get a DomainDriver instance
      DomainDriver domainDriver = this.getDomainDriver(idAsInt(group.getDomainId()));

      // Update Group in specific domain
      return domainDriver.createGroup(specificGroup);
    } catch (AdminException e) {
      throw new AdminException(
          "DomainDriverManager.createGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_UPDATE_GROUP",
          "group Id: '" + group.getId() + "'",
          e);
    }
  }
  public void updateGroup(Connection c, Group g) throws AdminException {
    PreparedStatement statement = null;
    String theQuery =
        "update "
            + drvSettings.getGroupTableName()
            + " set "
            + drvSettings.getGroupNameColumnName()
            + " = ?,"
            + drvSettings.getGroupDescriptionColumnName()
            + " = ?"
            + " where "
            + drvSettings.getGroupSpecificIdColumnName()
            + " = ?";

    try {
      SilverTrace.debug("admin", "SQLGroupTable.updateGroup", "root.MSG_QUERY", theQuery);
      statement = c.prepareStatement(theQuery);
      statement.setString(1, drvSettings.trunc(g.getName(), 100));
      statement.setString(2, drvSettings.trunc(g.getDescription(), 400));
      statement.setInt(3, Integer.parseInt(g.getSpecificId()));
      statement.executeUpdate();
    } catch (Exception e) {
      throw new AdminException(
          "SQLGroupTable.updateGroup",
          SilverpeasException.ERROR,
          "root.EX_SQL_QUERY_FAILED",
          "Query = " + theQuery,
          e);
    } finally {
      DBUtil.close(statement);
    }
  }
  /**
   * Get group information with the given group name
   *
   * @param ddManager
   * @param sGroupName
   * @param sDomainFatherId
   * @return
   * @throws AdminException
   */
  public Group getGroupByNameInDomain(
      DomainDriverManager ddManager, String sGroupName, String sDomainFatherId)
      throws AdminException {
    try {
      ddManager.getOrganizationSchema();
      Group group = ddManager.getGroupByNameInDomain(sGroupName, sDomainFatherId);

      if (group != null) {
        String specificId = group.getSpecificId();
        GroupRow gr =
            ddManager
                .getOrganization()
                .group
                .getGroupBySpecificId(idAsInt(sDomainFatherId), specificId);
        if (gr != null) {
          group.setId(idAsString(gr.id));
          // Get the selected users for this group
          setDirectUsersOfGroup(ddManager, group);
        } else {
          return null;
        }
      }
      return group;
    } catch (Exception e) {
      throw new AdminException(
          "GroupManager.getGroupByNameInDomain",
          SilverpeasException.ERROR,
          "admin.EX_ERR_GET_GROUP",
          "group Name: '" + sGroupName + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
 private void setDirectUsersOfGroup(final DomainDriverManager ddManager, final Group group)
     throws AdminPersistenceException {
   String[] asUsersId =
       ddManager.getOrganization().user.getDirectUserIdsOfGroup(idAsInt(group.getId()));
   if (asUsersId != null) {
     group.setUserIds(asUsersId);
   }
 }
 private List<String> getSubGroupIds(Connection con, String groupId) throws SQLException {
   List<String> groupIds = new ArrayList<String>();
   List<Group> groups = groupDao.getSubGroups(con, groupId);
   for (Group group : groups) {
     groupIds.add(group.getId());
     groupIds.addAll(getSubGroupIds(con, group.getId()));
   }
   return groupIds;
 }
  /**
   * Get group information with the given id from Silverpeas
   *
   * @param ddManager
   * @param sGroupId
   * @return
   * @throws AdminException
   */
  public Group getGroup(DomainDriverManager ddManager, String sGroupId) throws AdminException {
    try {
      ddManager.getOrganizationSchema();
      GroupRow gr = ddManager.getOrganization().group.getGroup(idAsInt(sGroupId));

      Group group = new Group();

      if (gr != null) {
        group.setId(idAsString(gr.id));
        group.setSpecificId(gr.specificId);
        group.setDomainId(idAsString(gr.domainId));
        group.setSuperGroupId(idAsString(gr.superGroupId));
        group.setName(gr.name);
        group.setDescription(gr.description);
        group.setRule(gr.rule);
      }
      // Get the selected users for this group
      setDirectUsersOfGroup(ddManager, group);

      return group;
    } catch (Exception e) {
      throw new AdminException(
          "GroupManager.getGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_GET_GROUP",
          "group Id: '" + sGroupId + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
  /** Get the list of children groups of the given group */
  private ArrayList<AdminGroupInst> getChildrenGroupInst(
      DomainDriverManager ddManager, String sFatherGroupId, Group[] aGroup) {
    ArrayList<AdminGroupInst> alChildrenGroupInst = new ArrayList<AdminGroupInst>();

    // Search the children group
    for (Group anAGroup : aGroup) {
      if (anAGroup.getSuperGroupId() != null && anAGroup.getSuperGroupId().equals(sFatherGroupId)) {
        AdminGroupInst adminGroupInst = new AdminGroupInst();
        adminGroupInst.setGroup(anAGroup);
        adminGroupInst.setChildrenAdminGroupInst(
            this.getChildrenGroupInst(ddManager, adminGroupInst.getGroup().getId(), aGroup));
        alChildrenGroupInst.add(adminGroupInst);
      }
    }

    return alChildrenGroupInst;
  }
  /**
   * Delete the group with the given Id The delete is apply recursively to the sub-groups
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String deleteGroupById(
      DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas) throws AdminException {
    try {
      ddManager.getOrganizationSchema();
      if (group.getDomainId() != null && !onlyInSilverpeas) {
        ddManager.deleteGroup(group.getId());
      }
      // Delete the group node from Silverpeas
      ddManager.getOrganization().group.removeGroup(idAsInt(group.getId()));

      // Delete index of group information
      ddManager.unindexGroup(group.getId());

      return group.getId();
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.deleteGroupById()",
          "problème lors de la suppression du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.deleteGroupById",
          SilverpeasException.ERROR,
          "admin.EX_ERR_DELETE_GROUP",
          "group Id: '" + group.getId() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
  public String[] searchGroupsIds(
      DomainDriverManager ddManager,
      boolean isRootGroup,
      String componentId,
      String[] aProfileId,
      Group modelGroup)
      throws AdminException {
    try {
      // Get organization
      ddManager.getOrganizationSchema();
      GroupRow model = group2GroupRow(modelGroup);
      // The Ids could be equal to -1 !!!! Put it to -2 if null
      if (!StringUtil.isDefined(modelGroup.getId())) {
        model.id = -2;
      }
      if (!StringUtil.isDefined(modelGroup.getDomainId())) {
        model.domainId = -2;
      }
      if (!StringUtil.isDefined(modelGroup.getSuperGroupId())) {
        model.superGroupId = -2;
      }

      int[] aRoleId = null;
      if (aProfileId != null) {
        aRoleId = new int[aProfileId.length];
        for (int i = 0; i < aProfileId.length; i++) {
          aRoleId[i] = idAsInt(aProfileId[i]);
        }
      }
      // Get groups
      return ddManager
          .getOrganization()
          .group
          .searchGroupsIds(isRootGroup, idAsInt(componentId), aRoleId, model);
    } catch (Exception e) {
      throw new AdminException(
          "GroupManager.searchGroupsIdsInGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_GET_GROUPS_OF_DOMAIN",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
  /**
   * Gets the groups that match the specified criteria.
   *
   * @param criteria the criteria in searching of user groups.
   * @return an array of user groups matching the criteria or an empty array of no ones are found.
   * @throws AdminException if an error occurs while getting the user groups.
   */
  public Group[] getGroupsMatchingCriteria(final GroupSearchCriteriaForDAO criteria)
      throws AdminException {
    Connection connection = null;
    try {
      connection = DBUtil.makeConnection(JNDINames.ADMIN_DATASOURCE);

      List<Group> groups =
          groupDao.getGroupsByCriteria(connection, (GroupSearchCriteriaForDAO) criteria);

      String domainIdConstraint = null;
      List<String> domainIds = criteria.getCriterionOnDomainIds();
      for (String domainId : domainIds) {
        if (!domainId.equals(Domain.MIXED_DOMAIN_ID)) {
          domainIdConstraint = domainId;
          break;
        }
      }

      SearchCriteriaDAOFactory factory = SearchCriteriaDAOFactory.getFactory();
      for (Group group : groups) {
        List<String> groupIds = getAllSubGroupIdsRecursively(group.getId());
        groupIds.add(group.getId());
        UserSearchCriteriaForDAO criteriaOnUsers = factory.getUserSearchCriteriaDAO();
        List<UserDetail> users =
            userDao.getUsersByCriteria(
                connection,
                criteriaOnUsers
                    .onDomainId(domainIdConstraint)
                    .and()
                    .onGroupIds(groupIds.toArray(new String[groupIds.size()])));
        group.setTotalNbUsers(users.size());
      }
      return groups.toArray(new Group[groups.size()]);
    } catch (Exception e) {
      throw new AdminException(
          "GroupManager.getGroupsMatchingCriteria",
          SilverpeasException.ERROR,
          "admin.EX_ERR_GET_USER_GROUPS",
          e);
    } finally {
      DBUtil.close(connection);
    }
  }
 @Override
 public boolean equals(Object obj) {
   if (obj == null) {
     return false;
   }
   if (getClass() != obj.getClass()) {
     return false;
   }
   final Group other = (Group) obj;
   if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
     return false;
   }
   if ((this.specificId == null)
       ? (other.specificId != null)
       : !this.specificId.equals(other.specificId)) {
     return false;
   }
   if ((this.domainId == null)
       ? (other.domainId != null)
       : !this.domainId.equals(other.domainId)) {
     return false;
   }
   if ((this.superGroupId == null)
       ? (other.superGroupId != null)
       : !this.superGroupId.equals(other.superGroupId)) {
     return false;
   }
   if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
     return false;
   }
   if ((this.description == null)
       ? (other.description != null)
       : !this.description.equals(other.description)) {
     return false;
   }
   if ((this.rule == null) ? (other.rule != null) : !this.rule.equals(other.rule)) {
     return false;
   }
   if (this.getNbUsers() != other.getNbUsers()) {
     return false;
   }
   return true;
 }
  /** Convert GroupRow to Group */
  private Group groupRow2Group(GroupRow gr) {
    Group group = new Group();

    if (gr != null) {
      group.setId(idAsString(gr.id));
      group.setSpecificId(gr.specificId);
      group.setDomainId(idAsString(gr.domainId));
      group.setSuperGroupId(idAsString(gr.superGroupId));
      group.setName(gr.name);
      group.setDescription(gr.description);
      group.setRule(gr.rule);
    }
    return group;
  }
  /** Convert Group to GroupRow */
  private GroupRow group2GroupRow(Group group) {
    GroupRow gr = new GroupRow();
    gr.id = idAsInt(group.getId());
    gr.specificId = group.getSpecificId();
    gr.domainId = idAsInt(group.getDomainId());
    gr.superGroupId = idAsInt(group.getSuperGroupId());
    gr.name = group.getName();
    gr.description = group.getDescription();
    gr.rule = group.getRule();

    return gr;
  }
  /**
   * return group with given id (contains list of user ids for this group)
   *
   * @param groupId
   * @return Group
   */
  @Override
  public Group getGroup(String groupId) throws Exception {
    Group group = null;

    try {
      // Set the OrganizationSchema (if not already done)
      getOrganizationSchema();
      // Get the user information
      GroupRow gr = getOrganization().group.getGroup(idAsInt(groupId));
      if (gr == null) {
        throw new AdminException(
            "DomainDriverManager.getGroup",
            SilverpeasException.ERROR,
            "admin.EX_ERR_GROUP_NOT_FOUND",
            "group Id: '" + groupId + "'");
      }
      // Get a DomainDriver instance
      DomainDriver domainDriver = this.getDomainDriver(gr.domainId);
      // Get Group detail from specific domain
      group = domainDriver.getGroup(gr.specificId);

      // Fill silverpeas info of group details
      group.setId(groupId);
      group.setSpecificId(gr.specificId);
      group.setDomainId(idAsString(gr.domainId));
    } catch (AdminException e) {
      throw new AdminException(
          "DomainDriverManager.getGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_GET_GROUP",
          "group Id: '" + groupId + "'",
          e);
    } finally {
      releaseOrganizationSchema();
    }
    return group;
  }
 /**
  * @param ddManager
  * @param modelGroup
  * @param isAnd
  * @return
  * @throws AdminException
  */
 public Group[] searchGroups(DomainDriverManager ddManager, Group modelGroup, boolean isAnd)
     throws AdminException {
   try {
     // Get organization
     ddManager.getOrganizationSchema();
     GroupRow model = group2GroupRow(modelGroup);
     // The Ids could be equal to -1 !!!! Put it to -2 if null
     if (!StringUtil.isDefined((modelGroup.getId()))) {
       model.id = -2;
     }
     if (!StringUtil.isDefined(modelGroup.getDomainId())) {
       model.domainId = -2;
     }
     if (!StringUtil.isDefined(modelGroup.getSuperGroupId())) {
       model.superGroupId = -2;
     }
     // Get groups
     GroupRow[] grs = ddManager.getOrganization().group.searchGroups(model, isAnd);
     // Convert GroupRow objects in Group Object
     Group[] groups = new Group[grs.length];
     for (int nI = 0; nI < grs.length; nI++) {
       groups[nI] = groupRow2Group(grs[nI]);
       // Get the selected users for this group
       setDirectUsersOfGroup(ddManager, groups[nI]);
     }
     return groups;
   } catch (Exception e) {
     throw new AdminException(
         "GroupManager.searchGroups",
         SilverpeasException.ERROR,
         "admin.EX_ERR_GET_GROUPS_OF_DOMAIN",
         e);
   } finally {
     ddManager.releaseOrganizationSchema();
   }
 }
  /** Inserts in the database a new Group row. */
  public int createGroup(Connection c, Group group) throws AdminException {
    PreparedStatement statement = null;
    int nextId = 0;
    String theQuery =
        "insert into "
            + drvSettings.getGroupTableName()
            + "("
            + getColumns()
            + ") values (?,?,?,?)";

    try {
      SilverTrace.debug("admin", "SQLGroupTable.createGroup", "root.MSG_QUERY", theQuery);
      statement = c.prepareStatement(theQuery);
      nextId =
          DBUtil.getNextId(
              drvSettings.getGroupTableName(), drvSettings.getGroupSpecificIdColumnName());
      statement.setInt(1, nextId);
      String gid = group.getSuperGroupId();
      if ((gid == null) || (gid.length() <= 0) || (gid.equals("-1")))
        statement.setNull(2, Types.INTEGER);
      else statement.setInt(2, Integer.parseInt(gid));
      statement.setString(3, drvSettings.trunc(group.getName(), 100));
      statement.setString(4, drvSettings.trunc(group.getDescription(), 400));
      statement.executeUpdate();
    } catch (Exception e) {
      throw new AdminException(
          "SQLGroupTable.createGroup",
          SilverpeasException.ERROR,
          "root.EX_SQL_QUERY_FAILED",
          "Query = " + theQuery,
          e);
    } finally {
      DBUtil.close(statement);
    }
    return nextId;
  }
  /** Fetch the current group row from a resultSet. */
  protected Group fetchGroup(ResultSet rs) throws SQLException {
    Group g = new Group();

    g.setSpecificId(Integer.toString(rs.getInt(1)));
    g.setSuperGroupId(Integer.toString(rs.getInt(2)));
    if (rs.wasNull()) g.setSuperGroupId(null);
    g.setName(rs.getString(3));
    g.setDescription(rs.getString(4));
    return g;
  }
 @Override
 public int compareTo(Group o) {
   return (getName().toLowerCase()).compareTo(o.getName().toLowerCase());
 }
  /**
   * Add the given group in Silverpeas
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String addGroup(DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas)
      throws AdminException {
    if (group == null || !StringUtil.isDefined(group.getName())) {
      if (group != null) {
        SynchroReport.error(
            "GroupManager.addGroup()",
            "Problème lors de l'ajout du groupe "
                + group.getSpecificId()
                + " dans la base, ce groupe n'a pas de nom",
            null);
      }
      return "";
    }

    try {
      ddManager.getOrganizationSchema();
      // Create group in specific domain (if onlyInSilverpeas is not true)
      // if domainId=-1 then group is a silverpeas organization
      if (!onlyInSilverpeas) {
        String specificId;
        if (group.getDomainId() != null) {
          specificId = ddManager.createGroup(group);
          group.setSpecificId(specificId);
        }
      }
      // Create the group node in Silverpeas
      GroupRow gr = group2GroupRow(group);
      if (gr.superGroupId != -1) {
        SynchroReport.info(
            "GroupManager.addGroup()",
            "Ajout du groupe "
                + group.getName()
                + " (père="
                + getGroup(ddManager, group.getSuperGroupId()).getSpecificId()
                + ") dans la table ST_Group",
            null);
      } else { // pas de père
        SynchroReport.info(
            "GroupManager.addGroup()",
            "Ajout du groupe " + group.getName() + " (groupe racine) dans la table ST_Group...",
            null);
      }
      ddManager.getOrganization().group.createGroup(gr);
      String sGroupId = idAsString(gr.id);

      // index group information
      ddManager.indexGroup(gr);

      // Create the links group_user in Silverpeas
      SynchroReport.info(
          "GroupManager.addGroup()",
          "Inclusion des utilisateurs directement associés au groupe "
              + group.getName()
              + " (table ST_Group_User_Rel)",
          null);
      String[] asUserIds = group.getUserIds();
      int nUserAdded = 0;
      for (String asUserId : asUserIds) {
        if (StringUtil.isDefined(asUserId)) {
          ddManager.getOrganization().group.addUserInGroup(idAsInt(asUserId), idAsInt(sGroupId));
          nUserAdded++;
        }
      }
      SynchroReport.info(
          "GroupManager.addGroup()",
          nUserAdded + " utilisateurs ajoutés au groupe " + group.getName() + " dans la base",
          null);
      return sGroupId;
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.addGroup()",
          "problème lors de l'ajout du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.addGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_ADD_GROUP",
          "group name: '" + group.getName() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }
  /**
   * Update the given group
   *
   * @param ddManager
   * @param group
   * @param onlyInSilverpeas
   * @return
   * @throws AdminException
   */
  public String updateGroup(DomainDriverManager ddManager, Group group, boolean onlyInSilverpeas)
      throws AdminException {
    ArrayList<String> alRemUsers = new ArrayList<String>();
    ArrayList<String> alAddUsers = new ArrayList<String>();

    if (group == null
        || !StringUtil.isDefined(group.getName())
        || !StringUtil.isDefined(group.getId())) {
      if (group != null) {
        SynchroReport.error(
            "GroupManager.updateGroup()",
            "Problème lors de maj du groupe "
                + group.getSpecificId()
                + " dans la base, ce groupe n'a pas de nom",
            null);
      }
      return "";
    }
    try {
      ddManager.getOrganizationSchema();
      if (group.getDomainId() != null && !onlyInSilverpeas) {
        ddManager.updateGroup(group);
      }
      // Get the group id
      String sGroupId = group.getId();
      String strInfoSycnhro;
      if (group.getSuperGroupId() != null) {
        strInfoSycnhro =
            "Maj du groupe "
                + group.getName()
                + " (père="
                + getGroup(ddManager, group.getSuperGroupId()).getSpecificId()
                + ") dans la base (table ST_Group)...";
      } else {
        strInfoSycnhro =
            "Maj du groupe "
                + group.getName()
                + " (groupe racine) dans la base (table ST_Group)...";
      }
      SynchroReport.info("GroupManager.updateGroup()", strInfoSycnhro, null);
      // Update the group node
      GroupRow gr = group2GroupRow(group);
      ddManager.getOrganization().group.updateGroup(gr);

      // index group information
      ddManager.indexGroup(gr);

      // Update the users if necessary
      SynchroReport.info(
          "GroupManager.updateGroup()",
          "Maj éventuelle des relations du groupe "
              + group.getName()
              + " avec les utilisateurs qui y sont directement inclus (tables ST_Group_User_Rel)",
          null);
      String[] asOldUsersId =
          ddManager.getOrganization().user.getDirectUserIdsOfGroup(idAsInt(sGroupId));

      // Compute the remove users list
      String[] asNewUsersId = group.getUserIds();
      for (String anAsOldUsersId : asOldUsersId) {
        boolean bFound = false;
        for (String anAsNewUsersId : asNewUsersId) {
          if (anAsOldUsersId.equals(anAsNewUsersId)) {
            bFound = true;
          }
        }

        if (!bFound) {
          alRemUsers.add(anAsOldUsersId);
        }
      }

      // Compute the add users list
      for (String anAsNewUsersId : asNewUsersId) {
        boolean bFound = false;
        for (String anAsOldUsersId : asOldUsersId) {
          if (anAsNewUsersId.equals(anAsOldUsersId)) {
            bFound = true;
          }
        }

        if (!bFound) {
          alAddUsers.add(anAsNewUsersId);
        }
      }
      // Remove the users that are not in this group anymore
      for (String alRemUser : alRemUsers) {
        ddManager
            .getOrganization()
            .group
            .removeUserFromGroup(idAsInt(alRemUser), idAsInt(sGroupId));
      }

      // Add the new users of the group
      for (String alAddUser : alAddUsers) {
        ddManager.getOrganization().group.addUserInGroup(idAsInt(alAddUser), idAsInt(sGroupId));
      }

      SynchroReport.info(
          "GroupManager.updateGroup()",
          "Groupe : "
              + group.getName()
              + ", ajout de "
              + alAddUsers.size()
              + " nouveaux utilisateurs, suppression de "
              + alRemUsers.size()
              + " utilisateurs",
          null);
      return sGroupId;
    } catch (Exception e) {
      SynchroReport.error(
          "GroupManager.updateGroup()",
          "problème lors de la maj du groupe " + group.getName() + " - " + e.getMessage(),
          null);
      throw new AdminException(
          "GroupManager.updateGroup",
          SilverpeasException.ERROR,
          "admin.EX_ERR_UPDATE_GROUP",
          "group Id: '" + group.getId() + "'",
          e);
    } finally {
      ddManager.releaseOrganizationSchema();
    }
  }