com.aurel.track.dbase.UpgradeDatabase.java Source code

Java tutorial

Introduction

Here is the source code for com.aurel.track.dbase.UpgradeDatabase.java

Source

/**
 * Genji Scrum Tool and Issue Tracker
 * Copyright (C) 2015 Steinbeis GmbH & Co. KG Task Management Solutions
    
 * <a href="http://www.trackplus.com">Genji Scrum Tool</a>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/* $Id:$ */

package com.aurel.track.dbase;

import java.io.File;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.torque.Torque;
import org.apache.torque.TorqueException;
import org.apache.torque.util.Criteria;

import com.aurel.track.ApplicationStarter;
import com.aurel.track.StartServlet;
import com.aurel.track.accessControl.AccessBeans;
import com.aurel.track.admin.customize.category.filter.PredefinedQueryBL;
import com.aurel.track.admin.customize.category.report.ReportBL;
import com.aurel.track.admin.customize.lists.systemOption.PriorityBL;
import com.aurel.track.admin.customize.lists.systemOption.SeverityBL;
import com.aurel.track.admin.customize.localize.LocalizeBL;
import com.aurel.track.admin.customize.role.RoleBL;
import com.aurel.track.admin.project.ProjectBL;
import com.aurel.track.admin.server.logging.LoggingConfigBL;
import com.aurel.track.admin.server.siteConfig.SiteConfigBL;
import com.aurel.track.admin.user.userLevel.UserLevelBL;
import com.aurel.track.beans.TBaseLineBean;
import com.aurel.track.beans.TComputedValuesBean;
import com.aurel.track.beans.TCostBean;
import com.aurel.track.beans.TExportTemplateBean;
import com.aurel.track.beans.TLinkTypeBean;
import com.aurel.track.beans.TPriorityBean;
import com.aurel.track.beans.TProjectBean;
import com.aurel.track.beans.TRoleBean;
import com.aurel.track.beans.TSeverityBean;
import com.aurel.track.beans.TSiteBean;
import com.aurel.track.beans.TStateChangeBean;
import com.aurel.track.beans.TSystemStateBean;
import com.aurel.track.beans.TTrailBean;
import com.aurel.track.beans.TWorkItemBean;
import com.aurel.track.dao.BaseLineDAO;
import com.aurel.track.dao.DAOFactory;
import com.aurel.track.dao.LinkTypeDAO;
import com.aurel.track.dao.SiteDAO;
import com.aurel.track.dao.StateChangeDAO;
import com.aurel.track.dao.SystemStateDAO;
import com.aurel.track.dao.TrailDAO;
import com.aurel.track.dao.WorkItemDAO;
import com.aurel.track.item.ItemPersisterException;
import com.aurel.track.item.budgetCost.BudgetBL;
import com.aurel.track.item.budgetCost.ComputedValueBL;
import com.aurel.track.item.budgetCost.ExpenseBL;
import com.aurel.track.item.history.HistoryBean;
import com.aurel.track.item.history.HistoryBean.HISTORY_TYPE;
import com.aurel.track.linkType.CloseDependsOnLinkType;
import com.aurel.track.linkType.ILinkType.LINK_DIRECTION;
import com.aurel.track.linkType.MsProjectLinkType;
import com.aurel.track.persist.BaseTListTypePeer;
import com.aurel.track.persist.BaseTProject;
import com.aurel.track.persist.BaseTProjectTypePeer;
import com.aurel.track.persist.BaseTPstatePeer;
import com.aurel.track.persist.BaseTStatePeer;
import com.aurel.track.persist.BaseTWorkItemPeer;
import com.aurel.track.persist.TListType;
import com.aurel.track.persist.TPstate;
import com.aurel.track.persist.TSite;
import com.aurel.track.persist.TSitePeer;
import com.aurel.track.persist.TState;
import com.aurel.track.persist.TWorkItem;
import com.aurel.track.prop.ApplicationBean;
import com.aurel.track.resources.LocalizationKeyPrefixes;
import com.aurel.track.screen.dashboard.bl.design.DashboardScreenDesignBL;
import com.aurel.track.util.EqualUtils;
import com.aurel.track.util.PropertiesHelper;

/**
*
* This class manages database upgrades from previous versions
* to the actual version. This is because some operations can
* not be done with SQL scripts across many different platforms.
*
* @author Joerg Friedrich
* @version $Revision: 1795 $
*
*/
public class UpgradeDatabase {

    private static final Logger LOGGER = LogManager.getLogger(UpgradeDatabase.class);

    private static TrailDAO trailDAO = DAOFactory.getFactory().getTrailDAO();
    private static StateChangeDAO stateChangeDAO = DAOFactory.getFactory().getStateChangeDAO();
    private static BaseLineDAO baseLineDAO = DAOFactory.getFactory().getBaseLineDAO();
    private static WorkItemDAO workItemDAO = DAOFactory.getFactory().getWorkItemDAO();
    private static SiteDAO siteDAO = DAOFactory.getFactory().getSiteDAO();
    private static LinkTypeDAO linkTypeDAO = DAOFactory.getFactory().getLinkTypeDAO();
    private static SystemStateDAO systemStateDAO = DAOFactory.getFactory().getSystemStateDAO();

    // The database version for this software version
    public static final int DBVERSION = 500;

    private static transient String theVersion = "";

    public UpgradeDatabase(String _theVersion, String _theBuild) throws ServletException {
        theVersion = _theVersion;
    }

    /**
     * This method performs the actual upgrade by reading information
     * from the database and writing to it directly and via the Torque
     * persistence layer. You can really screw things up if you manually
     * mess with the database version in TSite.
     * @throws SQLException
     * @throws ItemPersisterException
     * @throws TorqueException
     */
    public void upgrade(ServletContext servletContext)
            throws TorqueException, SQLException, ItemPersisterException {
        LoggingConfigBL.setLevel(LOGGER, Level.INFO);
        upgrade220To300();
        upgrade300To310();
        upgrade310To320();
        upgrade320To330();
        upgrade330To340();
        upgrade340To350();
        upgrade350To370(servletContext);
        addNewReportTemplatesBy372();
        addNewReportTemplatesBy373();

        // For future releases, put additional upgrade functions
        // into method upgradeFrom370().
    }

    /**
     * From 370 on the new upgrade code will be called from this method instead of upgrade()
     * @param servletContext
     * @throws SQLException
     */
    public static void upgradeFrom370(ServletContext servletContext) throws TorqueException, SQLException {
        upgrade370To380();
        upgrade380To400();
        upgrade400To411();
        upgrade411To412();
        upgrade412To415();
        upgrade415To416();
        upgrade416To417();
        upgrade417To500();
        upgrade500To502();
        upgrade502To503();
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_READY_TEXT);
    }

    /*
     * Coming from very early version 2.2.x -------------------------------------
     */
    private void upgrade220To300() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 300)) {
            return;// upgrade should not be necessary
        }
        // Insert generic project type into all projects in TPROJECT
        // that do not have an entry there already.
        try {
            List<TProjectBean> list = ProjectBL.loadAll();
            TProjectBean projectBean = ProjectBL.loadByPrimaryKey(Integer.valueOf(0));
            if (projectBean != null) {
                list.add(projectBean);
            }
            TProjectBean prj = null;
            Iterator<TProjectBean> i = list.iterator();
            while (i.hasNext()) {
                prj = i.next();
                if ((prj != null) && (prj.getProjectType() == null)) {
                    prj.setProjectType(new Integer(0));
                    ProjectBL.saveSimple(prj);// prj.save();
                    LOGGER.info("Adding project type to project " + prj.getLabel());
                }
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }

        // Insert entries into TPSTATE if there aren't any yet
        // This adds an entry for each list type and each state
        // and for any project (project oid == 0). Thus we will
        // have the same behaviour as before, but we can modify
        // it by manually pruning the table
        // Default states , stateflags and sort order are:
        // 1,'opened',0,
        // 2,'analyzed',0,2
        // 3,'assigned',0,3
        // 4,'suspended',1,9
        // 5,'processing',0,4
        // 6,'implemented',0,5
        // 7,'integrated',2,6
        // 8,'closed',1,8
        // 9,'assessing',0,7
        //
        // Default list types are:
        // 1,'ProblemReport',1
        // 2,'RequirementChange',2
        // 3,'ImplementationError',3
        // 4,'WorkPackage',4
        // 5,'ActionItem',5
        // 6,'Milestone',6
        // 7,'Risk',7
        // 8,'Requirements',8
        // 9,'ReleaseNotes',9

        try {
            List<TPstate> list = BaseTPstatePeer.doSelect(new Criteria());
            Iterator<TPstate> i = list.iterator();
            TPstate pstate = null;
            if (!i.hasNext()) { // not a single entry here
                LOGGER.info("Adding entries to TPSTATE");
                List<TListType> listTypeList = BaseTListTypePeer.doSelect(new Criteria());
                Iterator<TListType> il = listTypeList.iterator();
                TState state = null;
                TListType listType = null;
                while (il.hasNext()) {
                    listType = (TListType) il.next();
                    List<TState> stateList = BaseTStatePeer.doSelect(new Criteria());
                    Iterator<TState> is = stateList.iterator();
                    while (is.hasNext()) {
                        state = (TState) is.next();
                        pstate = new TPstate();
                        pstate.setTState(state);
                        pstate.setTListType(listType);
                        pstate.setProjectType(new Integer(0));
                        if ((listType.getObjectID().intValue() <= 4) || (listType.getObjectID().intValue() >= 8)) {
                            pstate.save();
                        }
                        if ((listType.getObjectID().intValue() == 5)
                                && (state.getObjectID().intValue() == 5 || state.getObjectID().intValue() == 6)) {
                            pstate.save();
                        }
                        if (((listType.getObjectID().intValue() == 5) || (listType.getObjectID().intValue() == 6)
                                || (listType.getObjectID().intValue() == 7))
                                && (state.getObjectID().intValue() == 1 || state.getObjectID().intValue() == 8)) {
                            pstate.save();
                        }
                        System.out.print(".");
                    }
                }
                LOGGER.info("done");
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            LOGGER.error("Problem adding entries to TPSTATE");
        }

        // Last but not least update the TWORKITEM tables and check for
        // null values in CLASSKEY (just to make sure, should not be any)
        // and RELNOTICEDKEY. A RELNOTICEDKEY of null would cause
        // problems when we extending our report queries to this field.
        // This operation can take some time on a big database...
        try {
            System.err.print("Upgrading TWORKITEM table...");
            List<TWorkItem> list = BaseTWorkItemPeer.doSelect(new Criteria());
            Iterator<TWorkItem> i = list.iterator();
            TWorkItem wi = null;
            Integer reln = null;
            Integer classn = null;
            Integer inull = new Integer(0);
            int count = 0;
            while (i.hasNext()) {
                wi = (TWorkItem) i.next();
                reln = wi.getReleaseNoticedID();
                classn = wi.getClassID();
                if (reln == null) {
                    wi.setReleaseNoticedID(inull);
                }
                if (classn == null) {
                    wi.setClassID(inull);
                }
                wi.save();
                if ((count % 10) == 0) {
                    System.err.print("."); // give some sign that we are alive
                }
                ++count;
            }
            LOGGER.info("done");
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            LOGGER.error("Problem checking TWORKITEM");
        }

        // Finally mark this upgrade off so we don't run into it again
        // with this database
        LOGGER.info("Database upgrade from 220 to 300 completed.");

        siteBean.setDbVersion("300");
        siteDAO.save(siteBean);

    }

    /*
     * Upgrade from 30x to 31x ----------------------------
     */
    private void upgrade300To310() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 310)) {
            return; // upgrade should not be necessary
        }
        siteBean.setDbVersion("310");
        if (siteBean.getSmtpPort() == null || siteBean.getSmtpPort().intValue() == 0) {
            siteBean.setSmtpPort(new Integer(25));
        }
        if (siteBean.getMailReceivingPort() == null || siteBean.getMailReceivingPort().intValue() == 0) {
            siteBean.setMailReceivingPort(new Integer(110));
        }
        try {
            siteDAO.save(siteBean);
        } catch (Exception e) {
            LOGGER.error("Problem saving TSITE");
            LOGGER.error(e.getMessage());
            LOGGER.error("Continuing nonetheless");
        }
        try {
            List<TProjectBean> list = ProjectBL.loadAll();
            TProjectBean projectBean = ProjectBL.loadByPrimaryKey(Integer.valueOf(0));
            if (projectBean != null) {
                list.add(projectBean);
            }
            if (list != null) {
                Iterator<TProjectBean> it = list.iterator();
                TProjectBean project = null;
                while (it.hasNext()) {
                    project = it.next();
                    project.setDeleted("N");
                    if (project.getProjectType() == null) {
                        project.setProjectType(new Integer(0));
                    }
                    ProjectBL.saveSimple(project);//project.save();

                }
            }
        } catch (Exception e) {
            LOGGER.error("Error when trying to update TPROJECT");
            LOGGER.error(e.getMessage());
        }

        LOGGER.info("Database upgrade from 300 to 310 completed.");
    }

    private void upgrade310To320() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 320)) {
            return; // upgrade should not be necessary
        }

        LOGGER.info("Database upgrade from 310 to 320 completed.");

        siteBean.setDbVersion("320");
        siteDAO.save(siteBean);
    }

    private void upgrade320To330() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 330)) {
            return; // upgrade should not be necessary
        }

        //get all roles to migrate
        String extendedAccessKey;
        List<TRoleBean> roles = RoleBL.loadAll();
        Iterator<TRoleBean> itrRoles = roles.iterator();
        while (itrRoles.hasNext()) {
            TRoleBean roleBean = (TRoleBean) itrRoles.next();
            Integer accessKey = roleBean.getAccesskey();
            extendedAccessKey = roleBean.getExtendedaccesskey();
            if (accessKey != null && accessKey.intValue() != 0
                    && (extendedAccessKey == null || extendedAccessKey.length() == 0)) {
                extendedAccessKey = migrateRoleAccessKey(accessKey.intValue());
                roleBean.setExtendedaccesskey(extendedAccessKey);
                RoleBL.save(roleBean);
            }
        }
        LOGGER.info("Database upgrade from 320 to 330 completed.");
        siteBean.setDbVersion("330");
        siteDAO.save(siteBean);
    }

    private void upgrade330To340() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 340)) {
            return; // upgrade should not be necessary
        }

        //force the warning levels for priority
        List<TPriorityBean> priorityList = PriorityBL.loadAll();
        if (priorityList != null && !priorityList.isEmpty()) {
            for (TPriorityBean priorityBean : priorityList) {
                if (priorityBean.getWlevel() == null) {
                    priorityBean.setWlevel(new Integer(priorityBean.getObjectID().intValue() - 1));
                    PriorityBL.saveSimple(priorityBean);
                }
            }
        }

        //force the warning levels for severity
        List<TSeverityBean> severityList = SeverityBL.loadAll();
        if (severityList != null && !severityList.isEmpty()) {
            for (TSeverityBean severityBean : severityList) {
                if (severityBean.getWlevel() == null) {
                    severityBean.setWlevel(new Integer(severityBean.getObjectID().intValue() - 1));
                    SeverityBL.saveSimple(severityBean);
                }
            }
        }

        //copy the content of lastEdit to the effortDate for the costs
        List<TCostBean> costList = ExpenseBL.loadAll();
        if (costList != null && !costList.isEmpty()) {
            Iterator<TCostBean> iterator = costList.iterator();
            while (iterator.hasNext()) {
                TCostBean costBean = (TCostBean) iterator.next();
                if (costBean.getEffortdate() == null) {
                    costBean.setEffortdate(costBean.getLastEdit());
                    ExpenseBL.saveCostBean(costBean);
                }
            }
        }

        LOGGER.info("Database upgrade from 330 to 340 completed.");

        siteBean.setDbVersion("340");
        siteDAO.save(siteBean);
    }

    private void upgrade340To350() throws SQLException, ItemPersisterException, TorqueException {

        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 350)) {
            return; // upgrade should not be necessary
        }

        LOGGER.info("Performing upgrade step 340 to 350.");

        MigrateTagReplacer tagReplacer = new MigrateTagReplacer(Locale.ENGLISH);
        tagReplacer.setContextPath("");
        //replace the trail descriptions
        List<TTrailBean> trails = trailDAO.loadAll();
        if (trails != null) {
            Iterator<TTrailBean> iterator = trails.iterator();
            while (iterator.hasNext()) {
                TTrailBean trailBean = (TTrailBean) iterator.next();
                if (replaceDescriptionForHistoryBean(trailBean, tagReplacer)) {
                    trailDAO.save(trailBean);
                }
            }
        }
        //replace the state change descriptions
        List<TStateChangeBean> stateChanges = stateChangeDAO.loadAll();
        if (stateChanges != null) {
            Iterator<TStateChangeBean> iterator = stateChanges.iterator();
            while (iterator.hasNext()) {
                TStateChangeBean stateChangeBean = (TStateChangeBean) iterator.next();
                if (replaceDescriptionForHistoryBean(stateChangeBean, tagReplacer)) {
                    stateChangeDAO.save(stateChangeBean);
                }
            }
        }
        //replace the base line change descriptions
        List<TBaseLineBean> baseLineChanges = baseLineDAO.loadAll();
        if (baseLineChanges != null) {
            Iterator<TBaseLineBean> iterator = baseLineChanges.iterator();
            while (iterator.hasNext()) {
                TBaseLineBean baseLineBean = (TBaseLineBean) iterator.next();
                if (replaceDescriptionForHistoryBean(baseLineBean, tagReplacer)) {
                    baseLineDAO.save(baseLineBean);
                }
            }
        }

        List<TWorkItemBean> allItems = workItemDAO.loadAll();
        if (allItems != null) {
            Iterator<TWorkItemBean> iterator = allItems.iterator();
            while (iterator.hasNext()) {
                TWorkItemBean workItemBean = (TWorkItemBean) iterator.next();
                if (replaceDescriptionForItemBean(workItemBean, tagReplacer)) {
                    workItemDAO.save(workItemBean);
                }
            }
        }
        //set version control viewer  for projects. Append project in baseURL
        List<TProjectBean> projects = ProjectBL.loadAll();
        for (int i = 0; i < projects.size(); i++) {
            TProjectBean prj = projects.get(i);
            boolean useVC = (PropertiesHelper.getProperty(prj.getMoreProps(),
                    TProjectBean.MOREPPROPS.USE_VERSION_CONTROL_PROPERTY) + "").equalsIgnoreCase("true");
            if (useVC) {
                String viewVCBaseUrl = prj.getVersionSystemField0();
                String viewVCProject = prj.getVersionSystemField1();
                if (viewVCBaseUrl != null && viewVCProject != null && viewVCProject.length() > 0) {
                    if (!viewVCBaseUrl.endsWith("/") && !viewVCProject.startsWith("/")) {
                        viewVCBaseUrl = viewVCBaseUrl + "/";
                    }
                    viewVCBaseUrl = viewVCBaseUrl + viewVCProject;
                    prj.setVersionSystemField0(viewVCBaseUrl);
                    ProjectBL.saveSimple(prj);
                }
            }
        }

        //populates the computed values table for the existing time and cost values
        ComputedValueBL.deleteAll();
        saveComputedValuesBeanList(ExpenseBL.loadExpenseGroupedByWorkItem());
        saveComputedValuesBeanList(ExpenseBL.loadExpenseGroupedByWorkItemAndPerson());
        ComputedValueBL.computePlannedValuesToLastFromHistory(BudgetBL.loadLastPlanForWorkItems());

        // Make sure that the next ID from the ID_TABLE for the TEXPORTTEMPLATE
        // table begins with at least 101 for the new templates added by the customers.
        // That to reserve the numbers till 100 for temlates supplied with the Genji application.
        // If a customer has added some templates by version 3.4
        // (where this problem was not taken into account)
        // they should save/download their custom templates before installing the new version
        // and after installing the new version upload the templates again
        // (this time the IDs will be above 100)
        Connection con = Torque.getConnection(BaseTProjectTypePeer.DATABASE_NAME);
        try {
            int maxid = 0;
            String sqlStmt = "SELECT MAX(OBJECTID) FROM TEXPORTTEMPLATE";

            ResultSet rs = executeSelect(sqlStmt, con);
            if (rs != null) {
                maxid = rs.getInt(1) + 1;
            }
            if (maxid < 101) {
                maxid = 101;
                sqlStmt = "UPDATE ID_TABLE SET NEXT_ID = " + String.valueOf(maxid)
                        + " WHERE TABLE_NAME = 'TEXPORTTEMPLATE'";
                insertData(sqlStmt);
            }
            if (!isNewInstall(siteBean)) {
                //move the existing custom (non system) templates to values over 101
                //by 3.4 there were only 5 "system" reports
                List<TExportTemplateBean> exportTemplateBeans = ReportBL.loadFromTo(new Integer(5),
                        new Integer(100));
                if (exportTemplateBeans != null && !exportTemplateBeans.isEmpty()) {
                    Iterator<TExportTemplateBean> iterator = exportTemplateBeans.iterator();
                    while (iterator.hasNext()) {
                        //ideal would be to change the objectID, but torque does not change the objectID
                        TExportTemplateBean oldExportTemplateBean = iterator.next();
                        TExportTemplateBean newExportTemplateBean = new TExportTemplateBean();
                        newExportTemplateBean.setName(oldExportTemplateBean.getName());
                        newExportTemplateBean.setReportType(oldExportTemplateBean.getReportType());
                        newExportTemplateBean.setExportFormat(oldExportTemplateBean.getExportFormat());
                        newExportTemplateBean.setRepositoryType(oldExportTemplateBean.getRepositoryType());
                        newExportTemplateBean.setDescription(oldExportTemplateBean.getDescription());
                        newExportTemplateBean.setProject(oldExportTemplateBean.getProject());
                        newExportTemplateBean.setPerson(oldExportTemplateBean.getPerson());
                        newExportTemplateBean.setUuid(oldExportTemplateBean.getUuid());
                        Integer oldObjectID = oldExportTemplateBean.getObjectID();
                        ReportBL.delete(oldObjectID);
                        Integer newObjectID = ReportBL.saveReport(newExportTemplateBean);
                        File oldUnzippedDirectory = ReportBL.getDirTemplate(oldObjectID);
                        File newUnzippedDirectory = ReportBL.getDirTemplate(newObjectID);
                        oldUnzippedDirectory.renameTo(newUnzippedDirectory);
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("Updating the ID_TABLE for TEXPORTTEMPLATE ID failed with " + e.getMessage());
        } finally {
            Torque.closeConnection(con);
        }

        //deletes the old system templates from in the disk in order
        //to trigger extracting the new templates from the zips found in the classpath
        deleteOldReportTemplates();

        LOGGER.info("Database upgrade from 340 to 350 completed.");

        siteBean.setDbVersion("350");
        siteDAO.save(siteBean);

    }

    private void upgrade350To370(ServletContext servletContext) throws SQLException, TorqueException {

        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 370)) {
            upgradeFrom370(servletContext);
            return; // upgrade should not be necessary
        }
        LOGGER.info("Performing upgrade step 350 to 370.");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "3.7");
        new MigrateTo37(servletContext).start();
    }

    public static void upgrade370To380() throws SQLException, TorqueException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 380)) {
            return; // upgrade should not be necessary
        }
        LOGGER.info("Performing upgrade step 370 to 380.");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "3.8");
        addNewReportTemplatesBy380();
        Connection con = Torque.getConnection(BaseTProjectTypePeer.DATABASE_NAME);
        int maxid = 0;
        String sqlStmt = "SELECT MAX(OBJECTID) FROM TLINKTYPE";
        ResultSet rs = executeSelect(sqlStmt, con);
        if (rs != null) {
            maxid = rs.getInt(1) + 1;
        }
        if (maxid < 101) {
            maxid = 101;
            sqlStmt = "UPDATE ID_TABLE SET NEXT_ID = " + String.valueOf(maxid) + " WHERE TABLE_NAME = 'TLINKTYPE'";
            insertData(sqlStmt);
        }
        Integer linkTypeID = addLinkType("close depends on", "conditioning the close", LINK_DIRECTION.RIGHT_TO_LEFT,
                CloseDependsOnLinkType.class.getName());
        LocalizeBL.saveLocalizedResource("linkType.name.1.", linkTypeID, "close depends on", Locale.ENGLISH);
        LocalizeBL.saveLocalizedResource("linkType.filterSuperset.1.", linkTypeID, "conditioning the close",
                Locale.ENGLISH);
        LocalizeBL.saveLocalizedResource("linkType.name.1.", linkTypeID, "Schlieen hngt ab von", Locale.GERMAN);
        LocalizeBL.saveLocalizedResource("linkType.filterSuperset.1.", linkTypeID, "zuerst geschlossen sein mssen",
                Locale.GERMAN);

        addUnscheduledReleaseState();
        siteBean.setDbVersion("380");
        siteDAO.save(siteBean);
        Torque.closeConnection(con);
    }

    static Integer addLinkType(String name, String leftToRight, Integer direction, String linkTypePlugin) {
        TLinkTypeBean linkTypeBean = new TLinkTypeBean();
        linkTypeBean.setName(name);
        linkTypeBean.setLeftToRightFirst(leftToRight);
        linkTypeBean.setLinkDirection(direction);
        linkTypeBean.setLinkTypePlugin(linkTypePlugin);
        return linkTypeDAO.save(linkTypeBean);
    }

    private static void addUnscheduledReleaseState() {
        TSystemStateBean systemStateBean = new TSystemStateBean();
        systemStateBean.setLabel("unscheduled");
        systemStateBean.setStateflag(TSystemStateBean.STATEFLAGS.NOT_PLANNED);
        systemStateBean.setEntityflag(TSystemStateBean.ENTITYFLAGS.RELEASESTATE);
        systemStateBean.setSortorder(Integer.valueOf(10));
        Integer systemStateID = systemStateDAO.save(systemStateBean);
        String fieldName = LocalizationKeyPrefixes.SYSTEM_STATUS_KEY_PREFIX
                + TSystemStateBean.ENTITYFLAGS.RELEASESTATE;
        LocalizeBL.saveLocalizedResource(fieldName, systemStateID, "unscheduled", Locale.ENGLISH);
        LocalizeBL.saveLocalizedResource(fieldName, systemStateID, "nicht geplannt", Locale.GERMAN);
    }

    /**
     * Adds the new report templates into the database
     * and
     */
    private void addNewReportTemplatesBy372() {
        try {
            TSite site = TSitePeer.load();
            String version = site.getTrackVersion();
            if (version == null || version.compareTo("3.7.2") <= 0) {
                List<TExportTemplateBean> newReportTemplates = ReportBL.loadFromTo(7, 11);
                if (newReportTemplates == null || newReportTemplates.isEmpty()) {
                    String sqlStmt;
                    Integer templateID;
                    TExportTemplateBean exportTemplateBean;
                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(8),*/
                            "Detailed expense with person, project, account",
                            "Detailed expense report with project, date, person");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(8) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(9),*/
                            "Grouped expense by person, project, account",
                            "Expense report grouped by person, project, account");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(9) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(10),*/
                            "Grouped expense by project, costcenter, account, person",
                            "Expense report grouped by project, costcenter, account, person");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(10) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(11),*/
                            "Detailed expense with subproject and item",
                            "Detailed expense report including subproject and item");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(11) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    LOGGER.info("Added new report templates in databse for 3.7.2");
                }
            }
        } catch (Exception e) {
            LOGGER.error("Adding new templates in database for 3.7.2 failed with " + e.getMessage());
        }

    }

    /**
     * Adds the new report templates into the database
     * and
     */
    private void addNewReportTemplatesBy373() {
        try {
            TSite site = TSitePeer.load();
            String theVersion = site.getTrackVersion();
            if (theVersion == null || theVersion.compareTo("3.7.3") < 0) {
                List<TExportTemplateBean> newReportTemplates = ReportBL.loadFromTo(11, 14);
                if (newReportTemplates == null || newReportTemplates.isEmpty()) {
                    String sqlStmt;
                    Integer templateID;
                    TExportTemplateBean exportTemplateBean;
                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(12),*/
                            "Filtered history", "Detailed report with filtered history");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(12) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(13),*/
                            "Earned value chart", "Chart with planned, actual and earned values");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(13) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    exportTemplateBean = prepareExportTemplateBean(/*new Integer(14),*/
                            "Opened vs. closed chart", "Chart with number of issues opened vs. closed");
                    templateID = ReportBL.saveReport(exportTemplateBean);
                    sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(14) + " WHERE OBJECTID = "
                            + templateID;
                    insertData(sqlStmt);

                    LOGGER.info("Added new report templates in database for 3.7.3");
                }
            }
        } catch (Exception e) {
            LOGGER.error("Adding new templates in database for 3.7.3 failed with " + e.getMessage());
        }

    }

    /**
     * Adds the new report templates into the database
     * and
     */
    private static void addNewReportTemplatesBy380() {
        try {
            TExportTemplateBean exportTemplateBean = ReportBL.loadByPrimaryKey(15);
            if (exportTemplateBean == null) {
                String sqlStmt;
                Integer templateID;
                exportTemplateBean = prepareExportTemplateBean("Status over time", "Status ove time table");
                templateID = ReportBL.saveReport(exportTemplateBean);
                sqlStmt = "UPDATE TEXPORTTEMPLATE SET OBJECTID = " + String.valueOf(15) + " WHERE OBJECTID = "
                        + templateID;
                insertData(sqlStmt);
                LOGGER.info("Added new report templates in database for 3.8.0");
            }
        } catch (Exception e) {
            LOGGER.error("Adding new templates in database for 3.8.0 failed with " + e.getMessage());
        }

    }

    private static TExportTemplateBean prepareExportTemplateBean(String name, String description) {
        TExportTemplateBean exportTemplateBean;
        exportTemplateBean = new TExportTemplateBean();
        exportTemplateBean.setName(name);
        exportTemplateBean.setExportFormat("pdf");
        exportTemplateBean.setRepositoryType(new Integer(2));
        exportTemplateBean.setDescription(description);
        exportTemplateBean.setPerson(new Integer(1));
        exportTemplateBean.setReportType("Jasper Report");
        return exportTemplateBean;
    }

    private static void upgrade380To400() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 400)) {
            return; // upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 380 to 400 started...");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.0");
        Migrate380To400.migrate380To400();
        LOGGER.info("Database upgrade from 380 to 400 completed.");
        siteBean.setDbVersion("400");
        siteDAO.save(siteBean);
    }

    private static void upgrade400To411() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 411)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 400 to 411 started...");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.1");
        PredefinedQueryBL.addHardcodedFilters();
        Migrate400To410.inverseLinkDirections(true);
        Migrate380To400.migrateFullTrigger();
        LOGGER.info("Database upgrade from 400 to 411 completed.");
        siteBean.setDbVersion("411");
        siteDAO.save(siteBean);
    }

    private static void upgrade411To412() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 412)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 411 to 412 started...");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.12");
        Migrate411To412.addTaskIsMilestone();
        if (!(ApplicationBean.getInstance().getAppType() == ApplicationBean.APPTYPE_DESK)
                && !ApplicationBean.getInstance().isGenji()) {
        }
        //forgot to add it for 400 To 410
        PredefinedQueryBL.addWatcherFilter();
        LOGGER.info("Database upgrade from 411 to 412 completed.");
        siteBean.setDbVersion("412");
        siteDAO.save(siteBean);
    }

    private static void upgrade412To415() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 415)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 412 to 415 started...");
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.12");
        LOGGER.info("Database upgrade from 412 to 415 completed.");
        siteBean.setDbVersion("415");
        siteDAO.save(siteBean);
    }

    private static void upgrade415To416() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 416)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 415 to 416 started...");
        if (!(ApplicationBean.getInstance().getAppType() == ApplicationBean.APPTYPE_DESK)
                && !ApplicationBean.getInstance().isGenji()) {
            Migrate415To416.addNewItemTypes();
        }
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.15");
        LOGGER.info("Database upgrade from 415 to 416 completed.");
        siteBean.setDbVersion("416");
        siteDAO.save(siteBean);
    }

    private static void upgrade416To417() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 417)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 416 to 417 started...");
        Migrate416To417.addDeletedBasket();
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "4.15");
        LOGGER.info("Database upgrade from 416 to 417 completed.");
        siteBean.setDbVersion("417");
        siteDAO.save(siteBean);
    }

    private static void upgrade417To500() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 500)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 416 to 500 started...");
        Migrate417To500.addWorkflowPerson();
        Migrate417To500.migrateWorkflows();
        Migrate417To500.setTypeFlagsForItemTypes();
        DashboardScreenDesignBL.getInstance().checkAndCreateClientDefaultCockpit();
        ApplicationStarter.getInstance().actualizePercentComplete(ApplicationStarter.DB_DATA_UPGRADE_STEP,
                ApplicationStarter.DATA_UPGRADE_TO_TEXT + "5.00");
        LOGGER.info("Database upgrade from 416 to 500 completed.");
        siteBean.setDbVersion("500");
        siteDAO.save(siteBean);
    }

    private static void upgrade500To502() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 502)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 500 to 501 started...");
        UserLevelBL.migrateFromProperyFileToDatabase(null);
        Migrate400To410.inverseLinkDirections(false);
        Migrate500To502.addInlineLinkedLinkType();
        LOGGER.info("Database upgrade from 500 to 501 completed.");
        siteBean.setDbVersion("502");
        siteDAO.save(siteBean);
    }

    private static void upgrade502To503() throws SQLException {
        TSiteBean siteBean = siteDAO.load1();
        if (!isNewDbVersion(siteBean, 503)) {
            return;// upgrade should not be necessary
        }
        LOGGER.info("Database upgrade from 502 to 503   started...");
        SiteConfigBL.setDefaultPrefixToWorkspaceIfNotExists();
        Migrate502To503.changeDateFieldNames();
        Migrate502To503.addDurations();
        LOGGER.info("Database upgrade from 502 to 503 completed.");
        siteBean.setDbVersion("503");
        siteDAO.save(siteBean);
    }

    /**
     * Populates the computed values table for the existing time and cost values
     * @param computedValuesBeanList
     */
    private void saveComputedValuesBeanList(List<TComputedValuesBean> computedValuesBeanList) {
        if (computedValuesBeanList != null && !computedValuesBeanList.isEmpty()) {
            Iterator<TComputedValuesBean> iterator = computedValuesBeanList.iterator();
            while (iterator.hasNext()) {
                TComputedValuesBean computedValuesBean = iterator.next();
                ComputedValueBL.save(computedValuesBean);
            }
        }
    }

    /**
     * Replaces the description with the HTML description
     * @param historyBean
     * @param tagReplacer
     * @throws SQLException
    * @throws TorqueException
     */
    private boolean replaceDescriptionForHistoryBean(HistoryBean historyBean, MigrateTagReplacer tagReplacer)
            throws SQLException, TorqueException {
        Integer workItemID = historyBean.getWorkItemID();
        TProjectBean projectBean = ProjectBL.loadByWorkItemKey(workItemID);
        String originalDescription = historyBean.getDescription();
        if (originalDescription != null && originalDescription.length() > 0) {
            String replacedDescription = tagReplacer.processSquareBracketsTags(
                    tagReplacer.replace(originalDescription, BaseTProject.createTProject(projectBean)));
            if (EqualUtils.notEqual(originalDescription, replacedDescription)) {
                if (replacedDescription != null
                        && replacedDescription.length() > ApplicationBean.getInstance().getCommentMaxLength()) {
                    LOGGER.warn("History description too long (" + replacedDescription.length() + ") for item:"
                            + workItemID + " type:" + getHistoryType(historyBean.getType()) + " historyID:"
                            + historyBean.getObjectID());
                    LOGGER.warn(
                            "\n******************************Original description******************************\n");
                    LOGGER.warn(originalDescription);
                    LOGGER.warn(
                            "\n******************************Replaced description******************************\n");
                    replacedDescription = replacedDescription.substring(0,
                            ApplicationBean.getInstance().getCommentMaxLength() - 1);
                    LOGGER.warn(replacedDescription);
                }
                historyBean.setDescription(replacedDescription);
                return true;
            }
        }
        return false;
    }

    private String getHistoryType(int type) {
        switch (type) {
        case HISTORY_TYPE.COMMON_HISTORYVALUES:
            return "HISTORYVALUES";
        case HISTORY_TYPE.TRAIL:
            return "TRAIL";
        case HISTORY_TYPE.BASELINE_CHANGE:
            return "BASELINE_CHANGE";
        case HISTORY_TYPE.STATE_CHANGE:
            return "STATE_CHANGE";
        case HISTORY_TYPE.PLANNED_VALUE_CHANGE:
            return "PLANNED_VALUE_CHANGE";
        case HISTORY_TYPE.BUDGET_CHANGE:
            return "BUDGET_CHANGE";
        case HISTORY_TYPE.REMAINING_PLAN_CHANGE:
            return "ESTIMATED_BUDGET_CHANGE";
        case HISTORY_TYPE.COST:
            return "COST";
        }
        return "HISTORYVALUES";
    }

    /**
    * Replaces the description with the HTML description
    *
    * @param historyBean
    * @param tagReplacer
    * @throws SQLException
     * @throws TorqueException
    */
    private boolean replaceDescriptionForItemBean(TWorkItemBean workItemBean, MigrateTagReplacer tagReplacer)
            throws SQLException, TorqueException {
        Integer workItemID = workItemBean.getObjectID();
        TProjectBean projectBean = ProjectBL.loadByWorkItemKey(workItemID);
        String originalDescription = workItemBean.getDescription();
        if (originalDescription != null && originalDescription.length() > 0) {
            String replacedDescription = tagReplacer.processSquareBracketsTags(
                    tagReplacer.replace(originalDescription, BaseTProject.createTProject(projectBean)));
            if (!replacedDescription.startsWith("<p>")) {
                replacedDescription = "<p>" + replacedDescription + "</p>";
            }
            if (EqualUtils.notEqual(originalDescription, replacedDescription)) {
                if (replacedDescription != null
                        && replacedDescription.length() > ApplicationBean.getInstance().getCommentMaxLength()) {
                    LOGGER.warn("Item description too long for item:" + workItemID);
                    LOGGER.warn("\n*****************************************************************\n");
                    LOGGER.warn(originalDescription);
                    LOGGER.warn("\n*****************************************************************\n");
                    replacedDescription = replacedDescription.substring(0,
                            ApplicationBean.getInstance().getCommentMaxLength() - 1);
                }
                workItemBean.setDescription(replacedDescription);
                return true;
            }
        }
        return false;
    }

    /**
     * Deletes the old system templates from in the disk in order
     * to trigger extracting the new templates from the zips found in the classpath
     *
     */
    private void deleteOldReportTemplates() {
        List<TExportTemplateBean> templatesList = ReportBL.getAllTemplates();
        for (int i = 0; i < templatesList.size(); i++) {
            TExportTemplateBean templateBean = (TExportTemplateBean) templatesList.get(i);
            File f = ReportBL.getDirTemplate(templateBean.getObjectID());
            if (f.exists()) {
                NumberFormat nf = new DecimalFormat("00000");
                String dbId = nf.format(templateBean.getObjectID());
                String reportTemplateName = ReportBL.RESOURCE_PATH + "/" + ReportBL.EXPORT_TEMPLATE_PREFIX + dbId
                        + ".zip";
                InputStream is = StartServlet.class.getClassLoader().getResourceAsStream(reportTemplateName);
                //delete only those templates which has corresponding zip file in the classpath
                if (is == null) {
                    //zip not found in the classpath: nothing to expand and copy
                    continue;
                } else {
                    try {
                        //delete the system template to trigger the copy of the newer template version
                        if (f.isDirectory()) {
                            deleteDirectory(f);
                        } else {
                            f.delete();
                        }
                    } catch (Exception e) {
                        LOGGER.error("Deleting the old system template for template number "
                                + templateBean.getObjectID() + " failed with " + e.getMessage(), e);
                    }
                }
            }
        }

    }

    public static boolean deleteDirectory(File path) {
        if (path.exists()) {
            File[] files = path.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    deleteDirectory(files[i]);
                } else {
                    files[i].delete();
                }
            }
        }
        return path.delete();
    }

    private String migrateRoleAccessKey(int accessKey) {
        int thousand; // close
        int hundred; // read
        int ten; // modify
        int one; // create
        StringBuffer extendedAccessKey = new StringBuffer();
        //create the string buffer with no rights
        //-2 because at this time we have the last two permission flags not yet defined
        for (int i = 0; i < AccessBeans.NUMBER_OF_ACCESS_FLAGS; i++) {
            extendedAccessKey.append(AccessBeans.OFFVALUE);
        }
        thousand = accessKey / 1000;//close
        switch (thousand) {
        case 1:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CLOSETASKIFMANAGERORORIGINATOR,
                    AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CLOSETASKIFRESPONSIBLE, AccessBeans.ONVALUE);
            break;
        case 2:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CLOSETASKIFMANAGERORORIGINATOR,
                    AccessBeans.ONVALUE);
            break;
        default:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CLOSEANYTASK, AccessBeans.ONVALUE);
            break;
        }
        switch (accessKey % 1000) {
        case 999:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.PROJECTADMIN, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MANAGER, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.READANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MODIFYANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            break;
        case 777:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MANAGER, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.READANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MODIFYANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            break;
        case 770:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MANAGER, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            break;
        case 666:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.RESPONSIBLE, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.READANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MODIFYANYTASK, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            break;
        case 660:
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.RESPONSIBLE, AccessBeans.ONVALUE);
            extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            break;
        default:
            // pattern: read modify create
            hundred = (accessKey - thousand * 1000) / 100; // read
            ten = (accessKey - thousand * 1000 - hundred * 100) / 10; // modify
            one = accessKey - thousand * 1000 - hundred * 100 - ten * 10; // create
            if (hundred == 2) {
                extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.READANYTASK, AccessBeans.ONVALUE);
            }
            if (ten == 2) {
                extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.MODIFYANYTASK, AccessBeans.ONVALUE);
                //extendedAccessKey.setCharAt(AccessBeans.AccessFlagMigrationIndexes.ADDMODIFYDELETEDUEDATES, AccessBeans.ONVALUE);
            }
            if (one == 1) {
                extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CREATETASK, AccessBeans.ONVALUE);
            }
            break;
        }
        extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.CONSULTANT, AccessBeans.ONVALUE);
        extendedAccessKey.setCharAt(AccessBeans.AccessFlagIndexes.INFORMANT, AccessBeans.ONVALUE);
        return extendedAccessKey.toString();
    }

    private static void insertData(String sqlStmt) throws TorqueException, SQLException {
        Connection db = null;
        try {
            db = Torque.getConnection(BaseTProjectTypePeer.DATABASE_NAME);
            // it's the same name for all tables here, so we don't care
            Statement stmt = db.createStatement();
            stmt.executeUpdate(sqlStmt);
        } finally {
            Torque.closeConnection(db);
        }
    }

    private static ResultSet executeSelect(String sqlStmt, Connection db) {

        ResultSet rs = null;
        // Connection db = null;
        try {
            // it's the same name for all tables here, so we don't care
            Statement stmt = db.createStatement();
            rs = stmt.executeQuery(sqlStmt);
            if (rs.next() == false)
                rs = null;
        } catch (Exception e) {
            LOGGER.debug(ExceptionUtils.getStackTrace(e));
        }
        return rs;
    }

    private static boolean isNewDbVersion(TSiteBean siteBean, int theDbVersion) throws SQLException {
        if (siteBean == null) {
            throw new SQLException("Could not load site object");
        }
        Integer dbVersion = new Integer(0);
        if (siteBean.getDbVersion() != null || !"".equals(siteBean.getDbVersion())) {
            try {
                dbVersion = new Integer(siteBean.getDbVersion());
            } catch (Exception e) {
                dbVersion = new Integer(0);
            }
        }
        if (dbVersion.intValue() >= theDbVersion) {
            return false; // upgrade should not be necessary
        }
        return true;
    }

    private boolean isNewInstall(TSiteBean siteBean) {
        //it means actually new Genji installation or upgrade on a 3.7.2 after the first start
        //(due to a bug which resulted in overwriting the trackVersion field of the siteBean
        //in the UpdateDatabase code to null after a new 3.7.2 install)
        return siteBean.getTrackVersion() == null;
    }

    public static boolean isNewVersion() {
        TSite site = TSitePeer.load();
        if (site == null) {
            return true;
        }

        String tversion = site.getTrackVersion(); // e.g. 3.7.3

        return (tversion != null && !"".equals(tversion.trim()) && tversion.trim().equals(theVersion.trim()));
    }

}