com.flexive.core.storage.GenericDBStorage.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.core.storage.GenericDBStorage.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.core.storage;

import com.flexive.core.Database;
import com.flexive.core.DatabaseConst;
import com.flexive.core.storage.genericSQL.GenericLockStorage;
import com.flexive.shared.FxFormatUtils;
import com.flexive.shared.FxSharedUtils;
import com.flexive.shared.exceptions.FxApplicationException;
import com.flexive.shared.impex.FxDivisionExportInfo;
import com.flexive.shared.structure.TypeStorageMode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import static com.flexive.core.DatabaseConst.TBL_STRUCT_SELECTLIST_ITEM;

/**
 * Database vendor specific storage, common implementations for all storages
 *
 * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 */
public abstract class GenericDBStorage implements DBStorage {

    private static final Log LOG = LogFactory.getLog(GenericDBStorage.class);

    final static String TRUE = "TRUE";
    final static String FALSE = "FALSE";

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBooleanExpression(boolean flag) {
        return flag ? TRUE : FALSE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBooleanTrueExpression() {
        return TRUE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getBooleanFalseExpression() {
        return FALSE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LockStorage getLockStorage() {
        return GenericLockStorage.getInstance();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String escapeReservedWords(String query) {
        return query; //nothing to escape
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isDirectSearchSupported() {
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String concat(String... text) {
        if (text.length == 0)
            return "";
        if (text.length == 1)
            return text[0];
        StringBuilder sb = new StringBuilder(500);
        for (int i = 0; i < text.length; i++) {
            if (i > 0 && i < text.length)
                sb.append("||");
            sb.append(text[i]);
        }
        return sb.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String concat_ws(String delimiter, String... text) {
        if (text.length == 0)
            return "";
        if (text.length == 1)
            return text[0];
        StringBuilder sb = new StringBuilder(500);
        for (int i = 0; i < text.length; i++) {
            if (i > 0 && i < text.length)
                sb.append("||'").append(delimiter).append("'||");
            sb.append(text[i]);
        }
        return sb.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getFromDual() {
        return "";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getLimitOffsetVar(String var, boolean hasWhereClause, long limit, long offset) {
        return getLimitOffset(hasWhereClause, limit, offset);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getLastContentChangeStatement(boolean live) {
        String contentFilter = live ? " WHERE ISLIVE_VER=TRUE " : "";
        return "SELECT MAX(modified_at) FROM\n" + "(SELECT\n" + "(SELECT MAX(modified_at) FROM "
                + DatabaseConst.TBL_CONTENT + contentFilter + ") AS modified_at\n"
                + (live ? "\nUNION\n(SELECT MAX(modified_at) FROM " + DatabaseConst.TBL_TREE + "_LIVE)\n" : "")
                + "\nUNION\n(SELECT MAX(modified_at) FROM " + DatabaseConst.TBL_TREE + ")\n" + ") changes";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setBigString(PreparedStatement ps, int pos, String data) throws SQLException {
        //default implementation using PreparedStatement#setString
        ps.setString(pos, data);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String formatDateCondition(java.util.Date date) {
        return "'" + FxFormatUtils.getDateTimeFormat().format(date) + "'";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String escapeFlatStorageColumn(String column) {
        return column;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getSelectListItemReferenceFixStatement() {
        return "UPDATE " + TBL_STRUCT_SELECTLIST_ITEM + " SET PARENTID=? WHERE PARENTID IN (SELECT p.ID FROM "
                + TBL_STRUCT_SELECTLIST_ITEM + " p WHERE p.LISTID=?)";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void exportDivision(Connection con, OutputStream out) throws FxApplicationException {
        ZipOutputStream zip = new ZipOutputStream(out);
        GenericDivisionExporter exporter = GenericDivisionExporter.getInstance();
        StringBuilder sb = new StringBuilder(10000);
        try {
            try {
                exporter.exportLanguages(con, zip, sb);
                exporter.exportMandators(con, zip, sb);
                exporter.exportSecurity(con, zip, sb);
                exporter.exportWorkflows(con, zip, sb);
                exporter.exportConfigurations(con, zip, sb);
                exporter.exportStructures(con, zip, sb);
                exporter.exportFlatStorageMeta(con, zip, sb);
                exporter.exportTree(con, zip, sb);
                exporter.exportBriefcases(con, zip, sb);
                exporter.exportScripts(con, zip, sb);
                exporter.exportHistory(con, zip, sb);
                exporter.exportResources(con, zip, sb);
                exporter.exportHierarchicalStorage(con, zip, sb);
                exporter.exportFlatStorages(con, zip, sb);
                exporter.exportSequencers(con, zip, sb);
                exporter.exportBuildInfos(con, zip, sb);
                exporter.exportBinaries(con, zip, sb);
            } finally {
                zip.finish();
            }
        } catch (Exception e) {
            throw new FxApplicationException(e, "ex.export.error", e.getMessage());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void importDivision(Connection _con, ZipFile zip) throws Exception {
        long startTime = System.currentTimeMillis();
        GenericDivisionImporter importer = getDivisionImporter();
        FxDivisionExportInfo exportInfo = importer.getDivisionExportInfo(zip);
        if (FxSharedUtils.getDBVersion() != exportInfo.getSchemaVersion()) {
            LOG.warn("DB Version mismatch! Current:" + FxSharedUtils.getDBVersion() + ", exported schema:"
                    + exportInfo.getSchemaVersion());
        }
        boolean isNonTX = importer.importRequiresNonTXConnection();
        Connection con = isNonTX ? Database.getNonTXDataSource().getConnection() : _con;

        boolean autoCommit = false;
        if (isNonTX) {
            autoCommit = con.getAutoCommit();
            con.setAutoCommit(false);
            con.commit(); //ensure a "clean" connection
        }
        Exception inner = null;
        try {
            importer.wipeDivisionData(con);
            if (isNonTX)
                con.commit();
            Statement stmt = con.createStatement();
            if (isNonTX)
                con.commit();
            try {
                importer.importLanguages(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importMandators(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importSecurity(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importWorkflows(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importConfigurations(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importBinaries(con, zip);
                if (isNonTX)
                    con.commit();
                stmt.execute(getReferentialIntegrityChecksStatement(false));
                importer.importStructures(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importHierarchicalContents(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importScripts(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importTree(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importHistory(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importResources(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importBriefcases(con, zip);
                if (isNonTX)
                    con.commit();
                importer.importFlatStorages(con, zip, exportInfo);
                if (isNonTX)
                    con.commit();
                importer.importSequencers(con, zip);
                if (isNonTX)
                    con.commit();
            } catch (Exception e) {
                if (isNonTX)
                    con.rollback();
                inner = e;
                throw e;
            } finally {
                if (isNonTX)
                    con.commit();
                stmt.execute(getReferentialIntegrityChecksStatement(true));
            }
            if (isNonTX)
                con.commit();
            //rebuild fulltext index
            FulltextIndexer ft = StorageManager.getStorageImpl().getContentStorage(TypeStorageMode.Hierarchical)
                    .getFulltextIndexer(null, con);
            ft.rebuildIndex();
            if (isNonTX)
                con.commit();
        } catch (Exception e) {
            if (isNonTX)
                con.rollback();
            if (inner != null) {
                LOG.error(e);
                throw inner;
            }
            throw e;
        } finally {
            if (isNonTX) {
                con.commit();
                con.setAutoCommit(autoCommit);
                Database.closeObjects(GenericDBStorage.class, con, null);
            }
            LOG.info(" Importing took " + FxFormatUtils.formatTimeSpan((System.currentTimeMillis() - startTime)));
        }
    }

    /**
     * Get the DivisionImporter in use
     *
     * @return DivisionImporter
     */
    protected GenericDivisionImporter getDivisionImporter() {
        return GenericDivisionImporter.getInstance();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public FxDivisionExportInfo getDivisionExportInfo(ZipFile zip) throws FxApplicationException {
        return getDivisionImporter().getDivisionExportInfo(zip);
    }
}