You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.9 KiB
207 lines
5.9 KiB
package de.superx.bin.fm; |
|
|
|
import java.io.IOException; |
|
import java.io.StringWriter; |
|
import java.sql.ResultSet; |
|
import java.sql.ResultSetMetaData; |
|
import java.sql.SQLException; |
|
import java.util.ArrayList; |
|
import java.util.List; |
|
import java.util.Map; |
|
|
|
import javax.sql.DataSource; |
|
|
|
import org.apache.log4j.Logger; |
|
import org.springframework.dao.DataAccessException; |
|
import org.springframework.jdbc.core.JdbcTemplate; |
|
import org.springframework.jdbc.core.ResultSetExtractor; |
|
import org.springframework.jdbc.support.rowset.SqlRowSet; |
|
|
|
import de.superx.common.TemplateProcessor.SqlVarType; |
|
import de.superx.servlet.SuperXManager; |
|
import freemarker.core.Environment; |
|
import freemarker.template.ObjectWrapper; |
|
import freemarker.template.Template; |
|
import freemarker.template.TemplateDirectiveBody; |
|
import freemarker.template.TemplateDirectiveModel; |
|
import freemarker.template.TemplateException; |
|
import freemarker.template.TemplateModel; |
|
import freemarker.template.TemplateModelException; |
|
|
|
public class SqlVarsDirective implements TemplateDirectiveModel { |
|
|
|
/** |
|
* sqlvar "datatypes" |
|
* |
|
* @author nnguyen, j.hientzsch :) |
|
* |
|
*/ |
|
|
|
private static Logger logger = Logger.getLogger(SqlVarsDirective.class); |
|
|
|
private static final String PARAM_VAR_NAME = "name"; |
|
private static final String PARAM_VAR_TYPE = "type"; |
|
|
|
private static final boolean PARSE_FTL = true; |
|
private static final String FTL_ENCODING = "UTF-8"; |
|
|
|
@Override |
|
public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopvars, |
|
TemplateDirectiveBody body) throws TemplateException, IOException { |
|
|
|
// default inclusion of templates up for debate |
|
includeTemplates(env); |
|
|
|
SqlVarType varType = params.get(PARAM_VAR_TYPE) != null |
|
? SqlVarType.valueOf(params.get(PARAM_VAR_TYPE).toString().trim().toLowerCase()) |
|
: SqlVarType.none; |
|
|
|
if (!params.containsKey(PARAM_VAR_NAME)) { |
|
throw new TemplateModelException("No variable name is set for sqlvar"); |
|
} |
|
|
|
String varName = params.get(PARAM_VAR_NAME).toString(); |
|
String query = ""; |
|
|
|
ObjectWrapper objWrapper = env.getConfiguration().getObjectWrapper(); |
|
|
|
if (body != null) { |
|
StringWriter bodyContent = new StringWriter(); |
|
body.render(bodyContent); |
|
query = bodyContent.toString(); |
|
} else { |
|
logger.warn("Sqlvar " + varName + " has no nested content and therefore no effect and can be removed!"); |
|
} |
|
|
|
JdbcTemplate jt = new JdbcTemplate(); |
|
DataSource dataSource = SuperXManager.getBean("dataSource", DataSource.class); |
|
jt.setDataSource(dataSource); |
|
|
|
Object result = null; |
|
switch (varType) { |
|
|
|
case none: |
|
case list: { |
|
ArrayList<Object> list = buildList(jt, query); |
|
result = list.size() == 1 ? list.get(0) : list; |
|
|
|
result = result == null ? "" : result; |
|
} |
|
break; |
|
|
|
case hash: |
|
case hashlist: { |
|
FMListe list = new FMListe(); |
|
list = buildHashList(jt, query); |
|
result = list.size() == 1 ? list.get(0) : list; |
|
} |
|
break; |
|
|
|
case hashsequence: { |
|
FMListe list = new FMListe(); |
|
list = buildHashList(jt, query); |
|
result = list; |
|
} |
|
break; |
|
|
|
case sicht: |
|
throw new SqlVarsDirectiveException( |
|
"SqlVar type sicht is not supported as a freemarker directive instead use in block parsed by de.superx.common.TemplateProcessor"); |
|
case sichtsequence: |
|
throw new SqlVarsDirectiveException( |
|
"SqlVar type sichtsequence is not supported as a freemarker directive instead use in block parsed by de.superx.common.TemplateProcessor"); |
|
|
|
case string: |
|
result = query; |
|
break; |
|
|
|
default: |
|
throw new SqlVarsDirectiveException("Unknown SqlVar type " + varType.toString()); |
|
} |
|
|
|
env.setVariable(varName, objWrapper.wrap(result)); |
|
|
|
} |
|
|
|
/** |
|
* Executes query and and places result as SqlVarType.list into out |
|
* |
|
* @param jt |
|
* @param query |
|
* @param out |
|
*/ |
|
private static ArrayList<Object> buildList(JdbcTemplate jt, String query) { |
|
|
|
ArrayList<Object> out = new ArrayList<>(); |
|
|
|
SqlRowSet queryResult = jt.queryForRowSet(query); |
|
if (queryResult.first()) { |
|
do { |
|
out.add(queryResult.getObject(1)); |
|
} while (queryResult.next()); |
|
}else { |
|
out.add(""); //In case the query does not return a result, freemarker needs an empty string for further conditionals |
|
} |
|
return out; |
|
} |
|
|
|
/** |
|
* Executes SQL query and puts result into out as SqlVarType.hashlist |
|
* |
|
* @param jt |
|
* @param query |
|
* @param objWrapper |
|
* @param out |
|
*/ |
|
private static FMListe buildHashList(JdbcTemplate jt, String query) { |
|
|
|
FMListe out = new FMListe(); |
|
|
|
jt.query(query, new ResultSetExtractor<Void>() { |
|
@Override |
|
public Void extractData(ResultSet rs) throws SQLException, DataAccessException { |
|
|
|
ResultSetMetaData metaData = rs.getMetaData(); |
|
int columnCount = metaData.getColumnCount(); |
|
List<String> columnNames = new ArrayList<>(columnCount); |
|
for (int i = 1; i <= columnCount; i++) { |
|
columnNames.add(metaData.getColumnLabel(i)); |
|
} |
|
|
|
while (rs.next()) { |
|
SxHash row = new SxHash(); |
|
for (String columnName : columnNames) { |
|
row.put(columnName, rs.getString(columnName) == null ? "" : rs.getString(columnName)); |
|
} |
|
out.add(row); |
|
} |
|
|
|
return null; |
|
} |
|
}); |
|
|
|
return out; |
|
} |
|
|
|
private static void includeTemplates(Environment env) { |
|
Template inclTemplate1 = null, inclTemplate2 = null; |
|
try { |
|
inclTemplate1 = env.getTemplateForInclusion("SuperX_general", FTL_ENCODING, PARSE_FTL); |
|
inclTemplate2 = env.getTemplateForInclusion("SQL_lingua_franca", FTL_ENCODING, PARSE_FTL); |
|
} catch (IOException e) { |
|
logger.error( |
|
"Freemarker template inclusion failed for templates SuperX_general and/or SQL_lingua_franca!\n", e); |
|
} |
|
|
|
if (inclTemplate1 != null && inclTemplate2 != null) { |
|
try { |
|
env.include(inclTemplate1); |
|
env.include(inclTemplate2); |
|
} catch (TemplateException e) { |
|
logger.warn("Template inclusion failed in SqlVarsDirective:\n" + e.getStackTrace()); |
|
} catch (IOException e) { |
|
logger.warn("Template inclusion failed in SqlVarsDirective:\n" + e.getStackTrace()); |
|
} |
|
} |
|
} |
|
}
|
|
|