no.trank.openpipe.jdbc.SimpleJdbcDocumentProducer.java Source code

Java tutorial

Introduction

Here is the source code for no.trank.openpipe.jdbc.SimpleJdbcDocumentProducer.java

Source

/*
 * Copyright 2007  T-Rank AS
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package no.trank.openpipe.jdbc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import static no.trank.openpipe.api.document.DocumentOperation.*;

/**
 * A simple document producer for getting documents from a jdbc source.
 *
 * The producer can trigger add, modify and/or deletes. Each operation has a corresponding pre, post, fail and list
 * sqls. Ex: for add you have the setters: setAddPreSql(...), setAddSql(...), setAddPostSql(...) and
 * setAddFailSql(List<String> sql).
 *
 * For each operation type (add, modify, delete):<br/>
 * - The preSql is run<br/>
 * - Each document is produced by running the producer sql. There is no guarantee that all documents are fetched before
 * next step happens. But it is guaranteed that a after a post/failSql a new preSql is run before new documents are
 * fetched.<br/>
 * - If no errors happened the postSql is run.</br>
 * - If an error happened the failSql is run.</br>
 *
 * To use:
 *
 * 1. Set the JdbcTemplate (and its dataSource)</br>
 * 2. Set the sqls for producing documents.</br>
 *
 * @version $Revision$
 */
public class SimpleJdbcDocumentProducer extends JdbcDocumentProducer {
    private static final Logger log = LoggerFactory.getLogger(SimpleJdbcDocumentProducer.class);
    private final Map<String, SqlOperationPart> opPartsMap = new LinkedHashMap<String, SqlOperationPart>();

    @Override
    public void init() {
        super.setOperationParts(new ArrayList<OperationPart>(opPartsMap.values()));
        super.init();
    }

    private static <T> List<T> notNull(List<T> list) {
        return list == null ? Collections.<T>emptyList() : list;
    }

    private static void execute(JdbcTemplate jdbcTemplate, List<String> sqls) throws DataAccessException {
        for (String sql : sqls) {
            log.debug("Executing sql {}", sql);
            jdbcTemplate.execute(sql);
        }
    }

    private SqlOperationPart getPart(String operation) {
        SqlOperationPart part = opPartsMap.get(operation);
        if (part == null) {
            part = new SqlOperationPart(operation);
            opPartsMap.put(operation, part);
        }
        return part;
    }

    /**
     * Set a list of preSqls to run.
     *
     * @param operation the operation that this preSql is used for.
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setPreSql(String operation, List<String> sql) {
        getPart(operation).setPreSql(sql);
    }

    /**
     * Set a list of sqls to run to get the documents.
     *
     * @param operation the operation that this preSql is used for.
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setSql(String operation, List<String> sql) {
        getPart(operation).setSqls(sql);
    }

    /**
     * Set a list of sqls to run after documents have been fetched.
     *
     * @param operation the operation that this preSql is used for.
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setPostSql(String operation, List<String> sql) {
        getPart(operation).setPostSql(sql);
    }

    /**
     * Set a list of sqls to run if there was an error in the pipeline.
     *
     * @param operation the operation that this preSql is used for.
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    private void setFailSql(String operation, List<String> sql) {
        getPart(operation).setFailSql(sql);
    }

    /**
     * Set a list of preSqls to run before producing add Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setAddPreSql(List<String> sql) {
        setPreSql(ADD_VALUE, sql);
    }

    /**
     * Set a list of sqls to run for producing add Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setAddSql(List<String> sql) {
        setSql(ADD_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after add documents have been produced. (If no error happened)
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setAddPostSql(List<String> sql) {
        setPostSql(ADD_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after add documents have been produced and some error happened.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setAddFailSql(List<String> sql) {
        setFailSql(ADD_VALUE, sql);
    }

    /**
     * Set a list of preSqls to run before producing modify Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setModifyPreSql(List<String> sql) {
        setPreSql(MODIFY_VALUE, sql);
    }

    /**
     * Set a list of sqls to run for producing modify Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setModifySql(List<String> sql) {
        setSql(MODIFY_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after modify documents have been produced. (If no error happened)
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setModifyPostSql(List<String> sql) {
        setPostSql(MODIFY_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after modify documents have been produced and some error happened.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setModifyFailSql(List<String> sql) {
        setFailSql(MODIFY_VALUE, sql);
    }

    /**
     * Set a list of preSqls to run before producing delete Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setDeletePreSql(List<String> sql) {
        setPreSql(DELETE_VALUE, sql);
    }

    /**
     * Set a list of sqls to run for producing delete Documents.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setDeleteSql(List<String> sql) {
        setSql(DELETE_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after delete documents have been produced. (If no error happened)
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setDeletePostSql(List<String> sql) {
        setPostSql(DELETE_VALUE, sql);
    }

    /**
     * Set a list of sqls to run after delete documents have been produced and some error happened.
     *
     * @param sql a list of sql to run as preSql
     * @see no.trank.openpipe.api.document.DocumentOperation
     */
    public void setDeleteFailSql(List<String> sql) {
        setFailSql(DELETE_VALUE, sql);
    }

    private static class SqlOperationPart implements OperationPart {
        private final String operation;
        private List<String> preSql = Collections.emptyList();
        private List<String> sqls = Collections.emptyList();
        private List<String> postSql = Collections.emptyList();
        private List<String> failSql = Collections.emptyList();

        public SqlOperationPart(String operation) {
            this.operation = operation;
        }

        @Override
        public boolean isEmpty() {
            return preSql.isEmpty() && sqls.isEmpty() && postSql.isEmpty();
        }

        @Override
        public String getOperation() {
            return operation;
        }

        @Override
        public void doPreSql(JdbcTemplate jdbcTemplate) throws DataAccessException {
            execute(jdbcTemplate, preSql);
        }

        @Override
        public void doPostSql(JdbcTemplate jdbcTemplate) throws DataAccessException {
            execute(jdbcTemplate, postSql);
        }

        @Override
        public void doFailSql(JdbcTemplate jdbcTemplate) throws DataAccessException {
            execute(jdbcTemplate, failSql);
        }

        @Override
        public List<String> getSqls() {
            return sqls;
        }

        public void setSqls(List<String> sqls) {
            this.sqls = notNull(sqls);
        }

        public void setPreSql(List<String> preSql) {
            this.preSql = notNull(preSql);
        }

        public void setPostSql(List<String> postSql) {
            this.postSql = notNull(postSql);
        }

        public void setFailSql(List<String> failSql) {
            this.failSql = notNull(failSql);
        }
    }
}