net.xy.jcms.controller.configurations.parser.TranslationDBConnector.java Source code

Java tutorial

Introduction

Here is the source code for net.xy.jcms.controller.configurations.parser.TranslationDBConnector.java

Source

/**
 * This file is part of XY.JCms, Copyright 2010 (C) Xyan Kruse, Xyan@gmx.net, Xyan.kilu.de
 * 
 * XY.JCms 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.
 * 
 * XY.JCms 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 XY.JCms. If not, see <http://www.gnu.org/licenses/>.
 */
package net.xy.jcms.controller.configurations.parser;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import net.xy.jcms.controller.configurations.ITranslationConfigurationAdapter;
import net.xy.jcms.controller.configurations.pool.ConverterPool;
import net.xy.jcms.controller.translation.RuleParameter;
import net.xy.jcms.controller.translation.TranslationRule;
import net.xy.jcms.shared.IDataAccessContext;

/**
 * implements an connector for retrieving the translation configuration from db.
 * The whole rule list shares an classloader for its type converters.
 * Note: this db connector don't supports special translation builtin parameter
 * mapping
 * 
 * @author Xyan
 * 
 */
public class TranslationDBConnector implements ITranslationConfigurationAdapter {
    /**
     * logger
     */
    static final Logger LOG = Logger.getLogger(TranslationDBConnector.class);

    /**
     * holds an singleton connection to the db
     */
    private final Connection connection;

    /**
     * classloader parent for the translation typeconverter classloaders
     */
    private final ClassLoader parentLoader;

    /**
     * cache for storing loading results
     */
    private TranslationRule[] cache;

    /**
     * constructor needs db connection to retrieve translation rules
     * 
     * @param connection
     *            will be set to readonly
     * @param parentLoader
     * @throws SQLException
     */
    public TranslationDBConnector(final Connection connection, final ClassLoader parentLoader) throws SQLException {
        this.connection = connection;
        this.parentLoader = parentLoader;
        connection.setReadOnly(true);
    }

    @Override
    public TranslationRule[] getRuleList(final IDataAccessContext dac) {
        if (dac.getProperty("flushConfig") == null && cache != null) {
            return cache;
        }
        try {
            final ClassLoader loader = new DBClassLoader(connection, parentLoader);
            cache = loadTranslations(dac, connection, loader);
            return cache;
        } catch (final SQLException e) {
            LOG.fatal("Could load translations from DB.", e);
        } catch (final ClassNotFoundException e) {
            LOG.fatal("An mendatory Translation type convertercouldn't be loaded.", e);
        }
        return null;
    }

    /**
     * loads/parses an single translation rule
     * 
     * @param dac
     * @param connection
     * @param parentLoader
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private static TranslationRule[] loadTranslations(final IDataAccessContext dac, final Connection connection,
            final ClassLoader loader) throws SQLException, ClassNotFoundException {
        final Statement query = connection.createStatement();
        if (!query.execute("SELECT * FROM Translations WHERE Enabled = true;")) {
            throw new IllegalArgumentException("Retrieving translations from DB returned no results.");
        }
        final ResultSet result = query.getResultSet();
        final List<TranslationRule> cases = new LinkedList<TranslationRule>();
        while (result.next()) {
            cases.add(loadRule(dac, result, connection, loader));
        }
        return cases.toArray(new TranslationRule[cases.size()]);
    }

    /**
     * gets an rule out from the query resultset
     * 
     * @param dac
     * @param result
     * @param connection
     * @param parentLoader
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private static TranslationRule loadRule(final IDataAccessContext dac, final ResultSet result,
            final Connection connection, final ClassLoader loader) throws SQLException, ClassNotFoundException {
        final String reactOn = result.getString("reactOn");
        final String buildOff = result.getString("buildOff");
        final String usecase = result.getString("usecase");
        final List<RuleParameter> params = parseParameters(result.getString("parameters"), connection, loader);
        return new TranslationRule(reactOn, buildOff, usecase, params);
    }

    /**
     * parses the parameters
     * 
     * @param paramStr
     * @param connection
     * @param loader
     * @return
     * @throws ClassNotFoundException
     */
    private static List<RuleParameter> parseParameters(final String paramStr, final Connection connection,
            final ClassLoader loader) throws ClassNotFoundException {
        if (StringUtils.isBlank(paramStr)) {
            return null;
        }
        final List<RuleParameter> params = new ArrayList<RuleParameter>();
        final String[] lines = paramStr.split("\n");
        for (final String line : lines) {
            final String[] parsLine = line.split(",");
            final String paramName = parsLine[0];
            final int paramGroup = Integer.valueOf(parsLine[1]);
            final String paramConverter = parsLine[2];
            params.add(new RuleParameter(paramName, paramGroup, ConverterPool.get(paramConverter, loader)));
        }
        return params;
    }

}