com.flexive.ejb.beans.UserGroupEngineBean.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.ejb.beans.UserGroupEngineBean.java

Source

/***************************************************************
 *  This file is part of the [fleXive](R) framework.
 *
 *  Copyright (c) 1999-2014
 *  UCS - unique computing solutions gmbh (http://www.ucs.at)
 *  All rights reserved
 *
 *  The [fleXive](R) project is free software; you can redistribute
 *  it and/or modify it under the terms of the GNU Lesser General Public
 *  License version 2.1 or higher as published by the Free Software Foundation.
 *
 *  The GNU Lesser General Public License can be found at
 *  http://www.gnu.org/licenses/lgpl.html.
 *  A copy is found in the textfile LGPL.txt and important notices to the
 *  license from the author are found in LICENSE.txt distributed with
 *  these libraries.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  For further information about UCS - unique computing solutions gmbh,
 *  please see the company website: http://www.ucs.at
 *
 *  For further information about [fleXive](R), please see the
 *  project website: http://www.flexive.org
 *
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package com.flexive.ejb.beans;

import com.flexive.core.Database;
import com.flexive.core.security.UserTicketStore;
import com.flexive.core.storage.StorageManager;
import com.flexive.core.structure.StructureLoader;
import com.flexive.shared.*;
import com.flexive.shared.content.FxPermissionUtils;
import com.flexive.shared.exceptions.*;
import com.flexive.shared.interfaces.SequencerEngineLocal;
import com.flexive.shared.interfaces.UserGroupEngine;
import com.flexive.shared.interfaces.UserGroupEngineLocal;
import com.flexive.shared.security.*;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.annotation.Resource;
import javax.ejb.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

import static com.flexive.core.DatabaseConst.*;
import static com.flexive.shared.FxSharedUtils.indexOfSelectableObject;

/**
 * User Group management beans.
 *
 * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 */
@Stateless(name = "UserGroupEngine", mappedName = "UserGroupEngine")
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserGroupEngineBean implements UserGroupEngine, UserGroupEngineLocal {
    private static final Log LOG = LogFactory.getLog(UserGroupEngineBean.class);
    @Resource
    javax.ejb.SessionContext ctx;
    @EJB
    SequencerEngineLocal seq;

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public UserGroup load(long groupId) throws FxApplicationException {
        Connection con = null;
        Statement stmt = null;
        String sql = "SELECT MANDATOR,NAME,COLOR,AUTOMANDATOR,ISSYSTEM FROM " + TBL_USERGROUPS + " WHERE ID="
                + groupId;
        try {

            // Obtain a database connection
            con = Database.getDbConnection();

            // Create the new workflow instance
            stmt = con.createStatement();

            // Build statement
            ResultSet rs = stmt.executeQuery(sql);

            // Does the group exist at all?
            if (rs == null || !rs.next()) {
                FxNotFoundException nfe = new FxNotFoundException("ex.account.group.notFound.id", groupId);
                if (LOG.isInfoEnabled())
                    LOG.info(nfe);
                throw nfe;
            }
            long autoMandator = rs.getLong(4);
            if (rs.wasNull())
                autoMandator = -1;
            return new UserGroup(groupId, rs.getLong(1), autoMandator, rs.getBoolean(5), rs.getString(2),
                    rs.getString(3));

        } catch (SQLException exc) {
            FxLoadException de = new FxLoadException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
            LOG.error(de);
            throw de;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public UserGroup loadMandatorGroup(long mandatorId) throws FxApplicationException {
        Connection con = null;
        Statement stmt = null;
        String sql = "SELECT ID,MANDATOR,NAME,COLOR,AUTOMANDATOR,ISSYSTEM FROM " + TBL_USERGROUPS
                + " WHERE AUTOMANDATOR=" + mandatorId;

        try {

            // Obtain a database connection
            con = Database.getDbConnection();

            // Create the new workflow instance
            stmt = con.createStatement();

            // Build statement
            ResultSet rs = stmt.executeQuery(sql);

            // Does the group exist at all?
            if (rs == null || !rs.next())
                throw new FxNotFoundException("ex.account.group.notFound.id", mandatorId);
            long autoMandator = rs.getLong(5);
            if (rs.wasNull())
                autoMandator = -1;
            return new UserGroup(rs.getLong(1), rs.getLong(2), autoMandator, rs.getBoolean(6), rs.getString(3),
                    rs.getString(4));
        } catch (SQLException exc) {
            FxLoadException de = new FxLoadException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
            LOG.error(de);
            throw de;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public List<UserGroup> loadAll(long mandatorId) throws FxApplicationException {
        Connection con = null;
        Statement stmt = null;
        String sql = null;
        try {

            // Obtain a database connection
            con = Database.getDbConnection();

            // Create the new workflow instance
            stmt = con.createStatement();

            //            1  2        3    4     5            6
            sql = "SELECT ID,MANDATOR,NAME,COLOR,AUTOMANDATOR,ISSYSTEM FROM " + TBL_USERGROUPS +
            // Never display the dummy NULL group
                    " WHERE ID!=" + UserGroup.GROUP_NULL;
            if (mandatorId != -1)
                sql += " AND (MANDATOR=" + mandatorId + " or ID in (" + UserGroup.GROUP_EVERYONE + ","
                        + UserGroup.GROUP_OWNER + "))";
            sql += " ORDER BY MANDATOR,NAME";

            ResultSet rs = stmt.executeQuery(sql);

            // Process resultset
            final List<UserGroup> result = new ArrayList<UserGroup>();
            while (rs != null && rs.next()) {
                long autoMandator = rs.getLong(5);
                if (rs.wasNull())
                    autoMandator = -1;
                result.add(new UserGroup(rs.getLong(1), rs.getLong(2), autoMandator, rs.getBoolean(6),
                        rs.getString(3), rs.getString(4)));
            }

            // Sanity check
            if (indexOfSelectableObject(result, UserGroup.GROUP_EVERYONE) == -1
                    || indexOfSelectableObject(result, UserGroup.GROUP_OWNER) == -1) {
                FxLoadException le = new FxLoadException("ex.usergroup.oneOfSystemGroupsIsMissing");
                LOG.fatal(le);
                throw le;
            }

            return result;
        } catch (SQLException exc) {
            FxLoadException de = new FxLoadException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
            LOG.error(de);
            throw de;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public long create(String name, String color, long mandatorId) throws FxApplicationException {
        final UserTicket ticket = FxContext.getUserTicket();
        // Permission checks
        try {
            if (!ticket.isGlobalSupervisor()) {
                if (ticket.getMandatorId() != mandatorId) {
                    throw new FxNoAccessException("ex.usergroup.create.foreignMandator");
                }
                if (!ticket.isInRole(Role.MandatorSupervisor))
                    FxPermissionUtils.checkRole(ticket, Role.AccountManagement);
            }
        } catch (FxNoAccessException nae) {
            if (LOG.isInfoEnabled())
                LOG.info(nae);
            throw nae;
        }

        Connection con = null;
        Statement stmt = null;
        PreparedStatement ps = null;
        String sql = null;
        try {

            // Sanity checks
            color = FxFormatUtils.processColorString("color", color);
            checkName(name);

            // Obtain a database connection
            con = Database.getDbConnection();

            // Obtain a new id
            long groupId = seq.getId(FxSystemSequencer.GROUP);

            // Create the new group
            sql = "INSERT INTO " + TBL_USERGROUPS + " "
                    + "(ID,MANDATOR,AUTOMANDATOR,ISSYSTEM,NAME,COLOR,CREATED_BY,CREATED_AT,MODIFIED_BY,MODIFIED_AT) VALUES ("
                    + "?,?,?,?,?,?,?,?,?,?)";
            final long NOW = System.currentTimeMillis();
            ps = con.prepareStatement(sql);
            ps.setLong(1, groupId);
            ps.setLong(2, mandatorId);
            ps.setNull(3, java.sql.Types.NUMERIC);
            ps.setBoolean(4, false);
            ps.setString(5, name);
            ps.setString(6, color);
            ps.setLong(7, ticket.getUserId());
            ps.setLong(8, NOW);
            ps.setLong(9, ticket.getUserId());
            ps.setLong(10, NOW);
            ps.executeUpdate();

            StructureLoader.updateUserGroups(FxContext.get().getDivisionId(), loadAll(-1));

            // Return the new id
            return groupId;
        } catch (SQLException exc) {
            final boolean uniqueConstraintViolation = StorageManager.isUniqueConstraintViolation(exc);
            EJBUtils.rollback(ctx);
            if (uniqueConstraintViolation) {
                FxEntryExistsException eee = new FxEntryExistsException("ex.usergroup.create.groupExists", name);
                if (LOG.isInfoEnabled())
                    LOG.info(eee);
                throw eee;
            } else {
                FxCreateException ce = new FxCreateException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
                LOG.error(ce);
                throw ce;
            }
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, null, ps);
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void update(long groupId, String name, String color) throws FxApplicationException {

        final UserTicket ticket = FxContext.getUserTicket();

        // Load the group
        UserGroup aGroup = CacheAdmin.getEnvironment().getUserGroup(groupId);

        // Permission checks
        checkPermission(aGroup, "ex.usergroup.noUpdatePerms");

        Connection con = null;
        Statement stmt = null;
        PreparedStatement pstmt;
        String sCurSql = null;
        try {

            // Sanity checks
            if (color != null && color.length() > 0 && color.charAt(0) != '#') {
                color = "#" + color;
            }
            checkName(name);

            // Fill in new values
            if (StringUtils.isNotBlank(name))
                aGroup.setName(name);
            if (StringUtils.isNotBlank(color))
                aGroup.setColor(color);

            // Obtain a database connection
            con = Database.getDbConnection();

            // Create the new group
            sCurSql = "UPDATE " + TBL_USERGROUPS + " SET " + "NAME=?, COLOR=?, MODIFIED_BY=?, MODIFIED_AT=? "
                    + "WHERE ID=" + groupId;
            final long NOW = System.currentTimeMillis();
            pstmt = con.prepareStatement(sCurSql);
            pstmt.setString(1, aGroup.getName());
            pstmt.setString(2, aGroup.getColor());
            pstmt.setLong(3, ticket.getUserId());
            pstmt.setLong(4, NOW);
            pstmt.executeUpdate();
            pstmt.close();

            StructureLoader.updateUserGroups(FxContext.get().getDivisionId(), loadAll(-1));
        } catch (SQLException exc) {
            final boolean uniqueConstraintViolation = StorageManager.isUniqueConstraintViolation(exc);
            EJBUtils.rollback(ctx);
            if (uniqueConstraintViolation) {
                FxEntryExistsException eee = new FxEntryExistsException("ex.usergroup.groupExists", name);
                if (LOG.isInfoEnabled())
                    LOG.info(eee);
                throw eee;
            } else {
                FxCreateException ce = new FxCreateException(exc, "ex.usergroup.sqlError", exc.getMessage(),
                        sCurSql);
                LOG.error(ce);
                throw ce;
            }
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void remove(long groupId) throws FxApplicationException {

        // Check special groups
        if (groupId == UserGroup.GROUP_UNDEFINED)
            return;

        // Load the group
        final UserGroup theGroup = CacheAdmin.getEnvironment().getUserGroup(groupId);

        if (theGroup == null) {
            throw new FxNotFoundException("ex.usergroup.groupNotFound.id", groupId);
        }

        // Check special groups
        if (theGroup.isSystem() && !FxContext.get().getRunAsSystem()) {
            FxNoAccessException nae = new FxNoAccessException("ex.usergroup.mayNotDeleteSystemGroups",
                    theGroup.getName());
            LOG.error(nae);
            throw nae;
        }

        // Caller may delete the group?
        checkPermission(theGroup, "ex.usergroup.noDeletePerms");

        Connection con = null;
        Statement stmt = null;
        String sCurSql;
        try {

            // Obtain a database connection
            con = Database.getDbConnection();

            // First of delete all user assignments to this group ..
            stmt = con.createStatement();
            sCurSql = "DELETE FROM " + TBL_ASSIGN_GROUPS + " WHERE USERGROUP=" + groupId;
            stmt.executeUpdate(sCurSql);
            stmt.close();

            // ... delete all roles assigned to this group
            stmt = con.createStatement();
            sCurSql = "DELETE FROM " + TBL_ROLE_MAPPING + " WHERE USERGROUP=" + groupId;
            stmt.executeUpdate(sCurSql);
            stmt.close();

            // ... then delete all ACL assignments to this group ..
            stmt = con.createStatement();
            sCurSql = "DELETE FROM " + TBL_ACLS_ASSIGNMENT + " WHERE USERGROUP=" + groupId;
            stmt.executeUpdate(sCurSql);
            stmt.close();

            // ... and finally delete the group itself;
            stmt = con.createStatement();
            sCurSql = "DELETE FROM " + TBL_USERGROUPS + " WHERE ID=" + groupId;
            stmt.executeUpdate(sCurSql);

            // Update all active user tickets that are affected
            UserTicketStore.flagDirtyHavingGroupId(groupId);

            StructureLoader.updateUserGroups(FxContext.get().getDivisionId(), loadAll(-1));

            // Log
            if (LOG.isDebugEnabled())
                LOG.debug("Group [" + theGroup + "] was successfully deleted.");
        } catch (SQLException exc) {
            EJBUtils.rollback(ctx);
            FxRemoveException ce = new FxRemoveException(exc, "ex.usergroup.deleteSqlException",
                    theGroup.getName());
            LOG.error(ce);
            throw ce;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }

    }

    /**
     * Checks if the group name is valid.
     * Throws a FxInvalidParameterException if the name is invalid.
     *
     * @param sName the name to check
     * @throws FxInvalidParameterException if the name is not valid
     */
    private void checkName(final String sName) throws FxInvalidParameterException {
        if (sName == null || sName.length() == 0) {
            throw new FxInvalidParameterException("NAME", "ex.usergroup.nameEmpty");
        }
        if (sName.indexOf("'") > -1 || sName.indexOf("\"") > -1) {
            throw new FxInvalidParameterException("NAME", "ex.usergroup.nameContainsInvalidChars");
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setRoles(long groupId, List<Role> roles) throws FxApplicationException {
        long tmp[] = new long[roles == null ? 0 : roles.size()];
        if (roles != null) {
            int pos = 0;
            for (Role role : roles) {
                tmp[pos++] = role.getId();
            }
        }
        setRoles(groupId, tmp);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void setRoles(long groupId, long[] roles) throws FxApplicationException {

        final UserTicket ticket = FxContext.getUserTicket();

        UserGroup aGroup = CacheAdmin.getEnvironment().getUserGroup(groupId);

        // Permission check
        if (!ticket.isGlobalSupervisor())
            try {
                if (aGroup.getMandatorId() != ticket.getMandatorId()) {
                    // foreign mandator
                    throw new FxNoAccessException("ex.usergroup.noPermSetRoles", aGroup.getName());
                }
                if (!(ticket.isInRole(Role.AccountManagement) || ticket.isInRole(Role.MandatorSupervisor))) {
                    throw new FxNoAccessException("ex.usergroup.noPermSetRoles", aGroup.getName());
                }
            } catch (FxNoAccessException nae) {
                if (LOG.isInfoEnabled())
                    LOG.info(nae);
                throw nae;
            }

        // Bye bye duplicates
        roles = FxArrayUtils.removeDuplicates(roles);
        //only allow to assign roles which the calling user is a member of (unless it is a global supervisor)
        if (!ticket.isGlobalSupervisor()) {
            List<Role> orgRoles = getRoles(groupId);
            List<Long> orgRoleIds = FxSharedUtils.getSelectableObjectIdList(orgRoles);
            //check removed roles
            for (long check : orgRoleIds) {
                if (!ArrayUtils.contains(roles, check)) {
                    if (!ticket.isInRole(Role.getById(check))) {
                        EJBUtils.rollback(ctx);
                        throw new FxNoAccessException("ex.account.roles.assign.noMember.remove",
                                Role.getById(check).getName());
                    }
                }
            }
            //check added roles
            for (long check : roles) {
                if (!orgRoleIds.contains(check)) {
                    if (!ticket.isInRole(Role.getById(check))) {
                        EJBUtils.rollback(ctx);
                        throw new FxNoAccessException("ex.account.roles.assign.noMember.add",
                                Role.getById(check).getName());
                    }
                }
            }
        }

        // Write roles to database
        Connection con = null;
        Statement stmt = null;
        String sCurSql;

        try {
            // Obtain a database connection
            con = Database.getDbConnection();

            // Delete the old assignments of the user
            sCurSql = "DELETE FROM " + TBL_ROLE_MAPPING + " WHERE USERGROUP=" + groupId;
            stmt = con.createStatement();
            stmt.executeUpdate(sCurSql);
            stmt.close();

            // Store the new assignments of the user
            for (long role : roles) {

                if (Role.isUndefined(role))
                    continue;

                stmt = con.createStatement();
                sCurSql = "INSERT INTO " + TBL_ROLE_MAPPING + " (ACCOUNT,USERGROUP,ROLE) VALUES ("
                        + Account.NULL_ACCOUNT + "," + groupId + "," + role + ")";
                stmt.executeUpdate(sCurSql);
                stmt.close();
            }

            // Update all active user tickets that are affected
            UserTicketStore.flagDirtyHavingGroupId(groupId);

        } catch (SQLException exc) {
            EJBUtils.rollback(ctx);
            FxUpdateException dbe = new FxUpdateException(exc, "ex.usergroup.updateRolesSqlException",
                    aGroup.getName());
            LOG.error(dbe);
            throw dbe;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }

    }

    /**
     * Returns true if the caller may see the group and its roles and assignments.
     *
     * @param grp the group
     * @return true if the caller may see the group its roles and assignments
     */
    public boolean mayAccessGroup(UserGroup grp) {
        final UserTicket ticket = FxContext.getUserTicket();
        return ticket.isGlobalSupervisor() || grp.getId() == UserGroup.GROUP_EVERYONE
                || grp.getId() == UserGroup.GROUP_OWNER || grp.getMandatorId() == ticket.getMandatorId();
    }

    /**
     * Checks if the caller may update/edit/delete a given group.
     *
     * @param group the group to check for
     * @param mode  mode displayed in the error message, eg 'update', 'delete', ..
     * @throws FxNoAccessException if the caller lacks the permissions
     */
    private void checkPermission(UserGroup group, String mode) throws FxNoAccessException {
        final UserTicket ticket = FxContext.getUserTicket();
        // Permission checks
        try {
            if (!ticket.isGlobalSupervisor()) {
                if (ticket.getMandatorId() != group.getMandatorId()) {
                    throw new FxNoAccessException(mode);
                }
                if (!ticket.isInRole(Role.MandatorSupervisor))
                    FxPermissionUtils.checkRole(ticket, Role.AccountManagement);
            }
        } catch (FxNoAccessException nae) {
            if (LOG.isInfoEnabled())
                LOG.info(nae);
            throw nae;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public List<Role> getRoles(long groupId) throws FxApplicationException {
        Connection con = null;
        Statement stmt = null;
        final String sql = "SELECT DISTINCT ROLE FROM " + TBL_ROLE_MAPPING + " WHERE USERGROUP=" + groupId;

        final UserGroup aGroup = CacheAdmin.getEnvironment().getUserGroup(groupId);

        // Permission check
        if (!mayAccessGroup(aGroup)) {
            FxNoAccessException nae = new FxNoAccessException("ex.usergroup.noPermissionsToReadRoles",
                    aGroup.getName());
            if (LOG.isInfoEnabled())
                LOG.info(nae);
            throw nae;
        }

        try {
            // Obtain a database connection
            con = Database.getDbConnection();
            // Load the roles
            stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            List<Role> result = new ArrayList<Role>();
            while (rs != null && rs.next()) {
                result.add(Role.getById(rs.getByte(1)));
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Roles for group [" + groupId + "]: " + result);
            }
            return result;
        } catch (SQLException exc) {
            FxLoadException le = new FxLoadException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
            LOG.error(le);
            throw le;
        } finally {
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void rebuildMandatorGroups() throws FxApplicationException {
        Connection con = null;
        PreparedStatement ps = null;
        Statement stmt = null;
        String sql = "";
        try {
            con = Database.getDbConnection();
            stmt = con.createStatement();
            List<Mandator> missing = new ArrayList<Mandator>(5);
            for (Mandator m : CacheAdmin.getEnvironment().getMandators(true, true)) {
                try {
                    UserGroup g = loadMandatorGroup(m.getId());
                    sql = "DELETE FROM " + TBL_ASSIGN_GROUPS + " WHERE USERGROUP=" + g.getId();
                    stmt.executeUpdate(sql);
                    sql = "INSERT INTO " + TBL_ASSIGN_GROUPS + " (ACCOUNT,USERGROUP) (SELECT a.id, " + g.getId()
                            + " FROM " + TBL_ACCOUNTS + " a WHERE a.MANDATOR=" + m.getId() + " AND a.ID!="
                            + Account.NULL_ACCOUNT + ")";
                    stmt.executeUpdate(sql);
                } catch (FxNotFoundException e) {
                    missing.add(m);
                }
            }
            final long NOW = System.currentTimeMillis();
            for (Mandator m : missing) {
                sql = "INSERT INTO " + TBL_USERGROUPS + " "
                        + "(ID,MANDATOR,AUTOMANDATOR,ISSYSTEM,NAME,COLOR,CREATED_BY,CREATED_AT,MODIFIED_BY,MODIFIED_AT) VALUES ("
                        + "?,?,?,?,?,?,?,?,?,?)";
                if (ps == null)
                    ps = con.prepareStatement(sql);
                long gid = seq.getId(FxSystemSequencer.GROUP);
                ps.setLong(1, gid);
                ps.setLong(2, m.getId());
                ps.setLong(3, m.getId());
                ps.setBoolean(4, true); //ISSYSTEM
                ps.setString(5, "Everyone (" + m.getName() + ")");
                ps.setString(6, "#00AA00");
                ps.setLong(7, 0);
                ps.setLong(8, NOW);
                ps.setLong(9, 0);
                ps.setLong(10, NOW);
                ps.executeUpdate();
                sql = "INSERT INTO " + TBL_ASSIGN_GROUPS + " (ACCOUNT,USERGROUP) (SELECT a.ID, " + gid + " FROM "
                        + TBL_ACCOUNTS + " a WHERE a.MANDATOR=" + m.getId() + " AND a.ID!=" + Account.NULL_ACCOUNT
                        + ")";
                stmt.executeUpdate(sql);
            }

            StructureLoader.updateUserGroups(FxContext.get().getDivisionId(), loadAll(-1));
        } catch (SQLException exc) {
            FxLoadException le = new FxLoadException(exc, "ex.usergroup.sqlError", exc.getMessage(), sql);
            LOG.error(le);
            throw le;
        } finally {
            if (ps != null)
                try {
                    ps.close();
                } catch (SQLException e) {
                    //ignore
                }
            Database.closeObjects(UserGroupEngineBean.class, con, stmt);
        }
    }

}