no.abmu.finances.service.hibernate3.FinanceSchemaImportServiceH3Impl.java Source code

Java tutorial

Introduction

Here is the source code for no.abmu.finances.service.hibernate3.FinanceSchemaImportServiceH3Impl.java

Source

/*$Id: FinanceSchemaImportServiceH2Impl.java 12083 2008-12-07 00:49:40Z jens $*/
/*
 ****************************************************************************
 *                                                                          *
 *                   (c) Copyright 2008 ABM-utvikling                       *
 *                                                                          *
 *                                                                          *
 * 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 2 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. http://www.gnu.org/licenses/gpl.html    *
 *                                                                          *
 ****************************************************************************
 */

package no.abmu.finances.service.hibernate3;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import no.abmu.finances.domain.Account;
import no.abmu.finances.domain.AccountOrgUnitMapping;
import no.abmu.finances.domain.MainReportSchema;
import no.abmu.finances.domain.Post;
import no.abmu.finances.domain.PostPeriod;
import no.abmu.finances.domain.PostType;
import no.abmu.finances.domain.ReportSchema;
import no.abmu.finances.finders.hibernate3.AccountFinderSpecification;
import no.abmu.finances.finders.hibernate3.PostFinderSpecification;
import no.abmu.finances.finders.hibernate3.PostPeriodFinderSpecification;
import no.abmu.finances.finders.hibernate3.PostTypeFinderSpecification;
import no.abmu.finances.finders.hibernate3.ReportSchemaFinderSpecification;
import no.abmu.finances.service.AbstractFinanceSchemaImportService;
import no.abmu.finances.utils.FinanceImporterHelper;
import no.abmu.finances.utils.FinanceSchemaExcelParser;
import no.abmu.organisationregister.domain.OrganisationUnit;
import no.abmu.organisationregister.finders.hibernate3.OrgUnitCriteriaFinderSpecification;
import no.abmu.util.test.Assert;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

/**
 * <code>FinanceSchemaImportServiceH3Impl</code> extends 
 * AbstractFinanceSchemaImportService.
 * 
 * @author Jens Vindvad, Jens.Vindvad@abm-utvikling.no
 * @author $Author: jens $
 * @version $Rev: 12083 $
 * $Date: 2008-12-07 01:49:40 +0100 (Sun, 07 Dec 2008) $
 * copyright ABM-Utvikling
 *
 */
public class FinanceSchemaImportServiceH3Impl extends AbstractFinanceSchemaImportService {

    private static final Log logger = (Log) LogFactory.getLog(FinanceSchemaImportServiceH3Impl.class);

    private boolean doRollback = true;

    private SessionFactory sessionFactory;

    private SimpleDateFormat yearMonthDayFormatter = new SimpleDateFormat("yyyyMMdd");

    private Map<PostPeriodKey, PostPeriod> postPeriodMap = new HashMap<PostPeriodKey, PostPeriod>();
    private Map<String, PostType> postTypeMap = new HashMap<String, PostType>();
    private Map<String, Account> accountMap = new HashMap<String, Account>();
    private Map<SchemaKey, ReportSchema> reportSchemaMap = new HashMap<SchemaKey, ReportSchema>();

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public boolean importFromExcel(String fileName, String sheetName, boolean doRollback) {

        Assert.checkRequiredArgument("fileName", fileName);
        Assert.checkRequiredArgument("sheetName", sheetName);

        FinanceSchemaExcelParser excelParser = createFinanceSchemaExcelParser(fileName, sheetName);

        String errorMessage = excelParser.checkInputValues();
        if (errorMessage != null) {
            // Not all nessesary input values were present.
            logger.error(errorMessage);
            return false;
        }

        boolean wentOK = false;
        try {
            Session session = sessionFactory.openSession();
            wentOK = runInTransaction(session, excelParser, doRollback);
        } catch (HibernateException e) {
            logger.error("Feil gikk ikke");
            logger.error(e.toString());
        }

        if (wentOK) {
            logger.info("Import went OK");
        } else {
            logger.warn("There was some errors during import .... ");
        }
        return wentOK;
    }

    private boolean runInTransaction(Session session, FinanceSchemaExcelParser excelParser, boolean rollback) {

        doRollback = rollback;
        boolean runInTransactionWentOk = false;
        Transaction transaction = session.beginTransaction();
        try {
            runInTransactionWentOk = runInTransaction(session, excelParser);
            if (!runInTransactionWentOk) {
                logger.info("doing rollback");
                transaction.rollback();
            } else if (rollback || doRollback) {
                logger.info("doing rollback");
                transaction.rollback();
            }
        } catch (IllegalArgumentException e) {
            transaction.rollback();
            throw e;
        } catch (IllegalStateException e) {
            transaction.rollback();
            throw e;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            logger.error("doing rollback ", throwable);
            transaction.rollback();
        } finally {
            if (!transaction.wasRolledBack() && (!doRollback)) {
                transaction.commit();
            }
            session.close();
        }

        return runInTransactionWentOk;
    }

    private boolean runInTransaction(Session session, FinanceSchemaExcelParser excelParser) {
        Assert.checkRequiredArgument("session", session);
        Assert.checkRequiredArgument("excelParser", excelParser);

        boolean importWentOK = true;

        // First check that new schema do not exist, if exists stop import. 
        excelParser.load();
        String schemaName = excelParser.getSchemaName();
        String schemaVersion = excelParser.getSchemaVersion();

        Assert.assertNotNull("schemaName", schemaName);
        Assert.assertNotNull("schemaVersion", schemaVersion);

        Criteria criteria = (new ReportSchemaFinderSpecification(schemaName, schemaVersion))
                .createCriteria(session);
        List list = criteria.list();

        if (list.size() > 0) {
            String errorMessage = "Finance schema with name='" + schemaName + "' and version='" + schemaVersion
                    + "' allready exists.";
            logger.error(errorMessage);
            importWentOK = false;
            doRollback = true;
            return false;
        }

        MainReportSchema mainReportSchema = null;
        ReportSchema reportSchema = null;

        List<AccountOrgUnitMapping> mapping = new ArrayList<AccountOrgUnitMapping>();
        excelParser.load();

        for (; excelParser.hasNext(); excelParser.next()) {

            reportSchema = getReportSchema(excelParser, reportSchemaMap);
            //the main is always first
            if (mainReportSchema == null) {
                mainReportSchema = (MainReportSchema) reportSchema;
                logger.info("Importing schemaName='" + mainReportSchema.getName() + "' version='"
                        + mainReportSchema.getVersion() + "'");
            }

            Account account = getAccount(session, excelParser);
            logger.info("");
            logger.info("XXXXXXXXXXXXXXXX NEW ROW ROW Row='" + excelParser.getCurrentRowIdx() + "' POST_CODE='"
                    + excelParser.getPostCode() + "' POST_VALUE_TYPE='" + excelParser.getPostValueType()
                    + "' Account id='" + account.getId() + "' name='" + account.getName() + "' ");

            if (!reportSchema.getAccounts().contains(account)) {
                reportSchema.addAccount(account);
            }

            OrganisationUnit organisationUnit = getOrganisationUnit(session, excelParser);
            if (organisationUnit != null) {
                AccountOrgUnitMapping orgUnitMapping = new AccountOrgUnitMapping(organisationUnit, account);
                mapping.add(orgUnitMapping);
            }

            //
            // handle posts
            //
            Post post = getNewPost(session, excelParser);
            //Post post = getPost(baseExcelParser, session);

            account.addPost(post);

            Set<Post> posts = account.getPosts();
            for (Post tmpPost : posts) {
                logger.info("Account id='" + account.getId() + "' ==> " + tmpPost.toString());
            }

        }

        session.save(mainReportSchema);
        for (AccountOrgUnitMapping orgUnitMapping : mapping) {
            session.save(orgUnitMapping);
        }

        return importWentOK;
    }

    private Account getAccount(Session session, FinanceSchemaExcelParser excelParser) {
        String accountName = excelParser.getAccountName();
        Account retAccount = accountMap.get(accountName);

        if (retAccount == null) {
            Criteria criteria = (new AccountFinderSpecification(accountName)).createCriteria(session);
            List list = criteria.list();
            if (list.size() > 0) {
                retAccount = (Account) list.get(0);
            }
        }

        if (null == retAccount) {
            retAccount = new Account();
            retAccount.setName(accountName);
            retAccount.setDescription(excelParser.getAccountDescription());
            accountMap.put(accountName, retAccount);
        }
        return retAccount;
    }

    private OrganisationUnit getOrganisationUnit(Session session, FinanceSchemaExcelParser excelParser) {
        String orgUnitId = excelParser.getAcountOrgUnitReference();
        if (orgUnitId == null) {
            return null;
        }
        OrgUnitCriteriaFinderSpecification finderSpecification = new OrgUnitCriteriaFinderSpecification(orgUnitId);
        List list = finderSpecification.createCriteria(session).list();
        if (list.size() == 0) {
            logger.warn("warn, the column " + FinanceImporterHelper.ACCOUNT_URG_UNIT_REFERENCE + " and row "
                    + excelParser.getCurrentRowIdx() + " had value \"" + orgUnitId
                    + "\". There is no org unit with this id in the " + "database");
            return null;
        }
        return (OrganisationUnit) list.get(0);
    }

    private Post getNewPost(Session session, FinanceSchemaExcelParser excelParser) {

        String code = excelParser.getPostCode();
        PostType postType = getPostType(session, excelParser);
        PostPeriod period = getPeriod(session, excelParser);

        PostFinderSpecification finderSpecification = new PostFinderSpecification(code);
        Criteria criteria = finderSpecification.createCriteria(session);

        List<Post> list = criteria.list();

        Post retPost = null;
        if (list.size() == 0) {
            retPost = createNewPost(excelParser);
            retPost.setPostType(postType);
            retPost.setPeriod(period);
            session.save(retPost);
            logger.info("NEW POST: " + retPost);
            validatorLogging(retPost);
        } else if (list.size() == 1) {
            retPost = list.get(0);
            String postValueType = excelParser.getPostValueType();
            if (!postValueType.equals(retPost.getClass().getName())) {
                logger.error("");
                logger.error(
                        "      XXXXXXXXXXXXXXXXXX OLD NOT SAME AS DEFINITION IN NEW SCHEMA  XXXXXXXXXXXXXXXXXXXX");
                logger.error("");
            }
            Set validators = retPost.getValidators();
            logger.info("Number of validators befor clearing existing validators: '" + validators.size() + "'");
            validators.clear();
            addNewValidators(excelParser, retPost);
            retPost.setPeriod(period);
            session.save(retPost);
            logger.info("OLD POST: " + retPost);
            validatorLogging(retPost);
        } else {
            retPost = list.get(0);
            logger.warn("");
            logger.warn(" ZZZZZZZ More than on post number of posts: " + list.size() + "'");
            logger.warn("");
            for (Post tmpPost : list) {
                logger.info("OLD POSTS: " + tmpPost.toString());
                validatorLogging(tmpPost);
            }
        }

        return retPost;
    }

    private PostType getPostType(Session session, FinanceSchemaExcelParser excelParser) {
        String postTypeName = excelParser.getPostTypeName();
        String postTypeDesc = excelParser.getPostTypeDescription();
        PostType postType = postTypeMap.get(postTypeName);

        if (null == postType) {
            Criteria criteria = (new PostTypeFinderSpecification(postTypeName)).createCriteria(session);
            List list = criteria.list();
            if (list.size() == 0) {
                postType = new PostType(postTypeName);
                postType.setDescription(postTypeDesc);
                session.save(postType);
            } else {
                postType = (PostType) list.get(0);
            }
        }
        return postType;
    }

    private PostPeriod getPeriod(Session session, FinanceSchemaExcelParser excelParser) {
        String valueFrom = excelParser.getPostPeriodFrom();
        String valueTo = excelParser.getPostPeriodTo();
        Date valueFromDate = null;
        Date valueToDate = null;
        try {
            valueFromDate = yearMonthDayFormatter.parse(valueFrom);
            if (valueTo != null) {
                valueToDate = yearMonthDayFormatter.parse(valueTo);
            }
        } catch (ParseException e) {
            throw new IllegalArgumentException("Could not parse the value " + valueFrom + " or " + valueTo
                    + ". The date has to have the format yyyyMMdd.");
        }

        PostPeriodKey key = new PostPeriodKey(valueFrom, valueTo);
        PostPeriod postPeriod = (PostPeriod) postPeriodMap.get(key);

        if (null == postPeriod) {
            Criteria criteria = (new PostPeriodFinderSpecification(valueFromDate, valueToDate))
                    .createCriteria(session);
            List list = criteria.list();
            if (list.size() == 0) {
                postPeriod = new PostPeriod(valueFromDate, valueToDate);
                session.save(postPeriod);
            } else {
                postPeriod = (PostPeriod) list.get(0);
            }
            postPeriodMap.put(key, postPeriod);
        }
        return postPeriod;
    }

    /**
     * dd. 
     * 
     *
     */
    class PostPeriodKey {
        private String from;
        private String to;

        public PostPeriodKey(String from, String to) {
            this.from = from;
            this.to = to;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            final PostPeriodKey that = (PostPeriodKey) o;

            if (!from.equals(that.from)) {
                return false;
            }
            if (to != null ? !to.equals(that.to) : that.to != null) {
                return false;
            }

            return true;
        }

        public int hashCode() {
            int result;
            result = from.hashCode();
            result = 29 * result + (to != null ? to.hashCode() : 0);
            return result;
        }
    }

}