org.milyn.routing.db.SQLExecutor Maven / Gradle / Ivy
The newest version!
/*
Milyn - Copyright (C) 2006 - 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (version 2.1) as published by the Free Software
Foundation.
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 Lesser General Public License for more details:
http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.routing.db;
import org.milyn.SmooksException;
import org.milyn.assertion.AssertArgument;
import org.milyn.delivery.Fragment;
import org.milyn.delivery.sax.SAXUtil;
import org.milyn.util.CollectionsUtil;
import org.milyn.cdr.SmooksConfigurationException;
import org.milyn.cdr.SmooksResourceConfigurationFactory;
import org.milyn.cdr.SmooksResourceConfiguration;
import org.milyn.cdr.annotation.AppContext;
import org.milyn.cdr.annotation.ConfigParam;
import org.milyn.container.ApplicationContext;
import org.milyn.container.ExecutionContext;
import org.milyn.db.AbstractDataSource;
import org.milyn.delivery.annotation.Initialize;
import org.milyn.delivery.annotation.VisitAfterIf;
import org.milyn.delivery.annotation.VisitBeforeIf;
import org.milyn.delivery.dom.DOMElementVisitor;
import org.milyn.delivery.sax.SAXElement;
import org.milyn.delivery.sax.SAXVisitAfter;
import org.milyn.delivery.sax.SAXVisitBefore;
import org.milyn.delivery.ordering.Producer;
import org.milyn.delivery.ordering.Consumer;
import org.milyn.delivery.VisitorAppender;
import org.milyn.delivery.VisitorConfigMap;
import org.milyn.event.report.annotation.VisitAfterReport;
import org.milyn.event.report.annotation.VisitBeforeReport;
import org.milyn.javabean.DataDecodeException;
import org.milyn.javabean.DataDecoder;
import org.milyn.javabean.context.BeanContext;
import org.milyn.javabean.repository.BeanId;
import org.milyn.javabean.repository.BeanIdRegister;
import org.milyn.javabean.repository.BeanRepository;
import org.milyn.javabean.repository.BeanRepositoryManager;
import org.w3c.dom.Element;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
/**
* SQLExecutor Visitor.
*
* Supports extraction and persistence to a Database.
*
* @author [email protected]
*/
@VisitBeforeIf( condition = "parameters.containsKey('executeBefore') && parameters.executeBefore.value == 'true'")
@VisitAfterIf( condition = "!parameters.containsKey('executeBefore') || parameters.executeBefore.value != 'true'")
@VisitBeforeReport(summary = "Execute statement '${resource.parameters.statement}' on Datasource '${resource.parameters.datasource}'.", detailTemplate = "reporting/SQLExecutor.html")
@VisitAfterReport(summary = "Execute statement '${resource.parameters.statement}' on Datasource '${resource.parameters.datasource}'.", detailTemplate = "reporting/SQLExecutor.html")
public class SQLExecutor implements SmooksResourceConfigurationFactory, SAXVisitBefore, SAXVisitAfter, DOMElementVisitor, Producer, Consumer {
@ConfigParam
private String datasource;
@ConfigParam
private String statement;
private StatementExec statementExec;
private String rsAppContextKey;
@ConfigParam(use = ConfigParam.Use.OPTIONAL)
private String resultSetName;
@ConfigParam(defaultVal = "EXECUTION", choice = {"EXECUTION", "APPLICATION"}, decoder = ResultSetScopeDecoder.class)
private ResultSetScope resultSetScope = ResultSetScope.EXECUTION;
@ConfigParam(defaultVal = "900000")
private long resultSetTTL = 900000L;
private boolean executeBefore = false;
@AppContext
private ApplicationContext appContext;
private BeanId resultSetBeanId;
public SQLExecutor setDatasource(AbstractDataSource datasource) {
AssertArgument.isNotNull(datasource, "datasource");
this.datasource = datasource.getName();
return this;
}
public SQLExecutor setStatement(String statement) {
AssertArgument.isNotNullAndNotEmpty(statement, "statement");
this.statement = statement;
return this;
}
public SQLExecutor setResultSetName(String resultSetName) {
AssertArgument.isNotNullAndNotEmpty(resultSetName, "resultSetName");
this.resultSetName = resultSetName;
return this;
}
public String getResultSetName() {
return resultSetName;
}
public SQLExecutor setResultSetScope(ResultSetScope resultSetScope) {
AssertArgument.isNotNull(resultSetScope, "resultSetScope");
this.resultSetScope = resultSetScope;
return this;
}
public SQLExecutor setResultSetTTL(long resultSetTTL) {
this.resultSetTTL = resultSetTTL;
return this;
}
public SQLExecutor setExecuteBefore(boolean executeBefore) {
this.executeBefore = executeBefore;
return this;
}
public SmooksResourceConfiguration createConfiguration() {
SmooksResourceConfiguration config = new SmooksResourceConfiguration();
config.setParameter("executeBefore", Boolean.toString(executeBefore));
return config;
}
@Initialize
public void intitialize() throws SmooksConfigurationException {
statementExec = new StatementExec(statement);
if(statementExec.getStatementType() == StatementType.QUERY && resultSetName == null) {
throw new SmooksConfigurationException("Sorry, query statements must be accompanied by a 'resultSetName' property, under whose value the query results are bound.");
}
if(resultSetName != null) {
resultSetBeanId = appContext.getBeanIdStore().register(resultSetName);
}
rsAppContextKey = datasource + ":" + statement;
}
public Set extends Object> getProducts() {
if(statementExec.getStatementType() == StatementType.QUERY) {
return CollectionsUtil.toSet(resultSetName);
}
return CollectionsUtil.toSet();
}
public boolean consumes(Object object) {
if(statement.indexOf(object.toString()) != -1) {
return true;
}
return false;
}
public void visitBefore(SAXElement saxElement, ExecutionContext executionContext) throws SmooksException, IOException {
executeSQL(executionContext, new Fragment(saxElement));
}
public void visitAfter(SAXElement saxElement, ExecutionContext executionContext) throws SmooksException, IOException {
executeSQL(executionContext, new Fragment(saxElement));
}
public void visitBefore(Element element, ExecutionContext executionContext) throws SmooksException {
executeSQL(executionContext, new Fragment(element));
}
public void visitAfter(Element element, ExecutionContext executionContext) throws SmooksException {
executeSQL(executionContext, new Fragment(element));
}
private void executeSQL(ExecutionContext executionContext, Fragment source) throws SmooksException {
Connection connection = AbstractDataSource.getConnection(datasource, executionContext);
BeanContext beanContext = executionContext.getBeanContext();
Map beanMap = beanContext.getBeanMap();
try {
if(!statementExec.isJoin()) {
if(statementExec.getStatementType() == StatementType.QUERY) {
if(resultSetScope == ResultSetScope.EXECUTION) {
beanContext.addBean(resultSetBeanId, statementExec.executeUnjoinedQuery(connection), source);
} else {
List