/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.sql; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.api.datasource.DSRequest; import org.solmix.api.datasource.DataSource; import org.solmix.api.exception.SlxException; import org.solmix.api.jaxb.Eoperation; import org.solmix.api.jaxb.Tfield; import org.solmix.api.jaxb.ToperationBinding; import org.solmix.commons.util.DataUtils; /** * * @author solmix.f@gmail.com * @version 110035 2011-3-22 */ @SuppressWarnings("unchecked") public class SQLSelectClause { private static Logger log = LoggerFactory.getLogger(SQLSelectClause.class.getName()); private final List<SQLDataSource> dataSources; private Map remapTable; private Map<String, String> column2TableMap; /** * Qualify column to specific Table */ private boolean qualifyColumnNames; private List<String> customValueFields; public List<String> getCustomValueFields() { return customValueFields; } public void setCustomValueFields(List<String> customValueFields) { this.customValueFields = customValueFields; } public SQLSelectClause(SQLDataSource dataSource) { this(DataUtils.makeList(dataSource)); } public SQLSelectClause(List<SQLDataSource> dataSources) { column2TableMap = new HashMap<String, String>(); qualifyColumnNames = true; customValueFields = null; this.dataSources = dataSources; remapTable = SQLDataSource.getField2ColumnMap(dataSources); if (dataSources.size() > 1) column2TableMap = SQLDataSource.getColumn2TableMap(dataSources); } public SQLSelectClause(DSRequest request, SQLDataSource ds, boolean qualifyColumnNames) { this(request, DataUtils.makeList(ds), qualifyColumnNames); } public SQLSelectClause(DSRequest request, List<SQLDataSource> dataSources, boolean qualifyColumnNames) { this(dataSources); List<String> outputColumns = computeOutputColumns(request); if (outputColumns != null) remapTable = DataUtils.subsetMap(remapTable, outputColumns); this.qualifyColumnNames = qualifyColumnNames; } /** * @param request * @return */ protected List<String> computeOutputColumns(DSRequest request) { List<String> __return = null; if (request == null) return null; Eoperation __type = request.getContext().getOperationType(); String __id = request.getContext().getOperationId(); SQLDataSource ds = dataSources.get(0); ToperationBinding __bind = ds.getContext().getOperationBinding(__type, __id); if (__bind != null && __bind.getOutputs() != null) { String __out = __bind.getOutputs(); String __outArray[] = __out.split(","); __return = new ArrayList<String>(); for (String str : __outArray) { __return.add(str); } } // request's outputs List<String> __RO = request.getContext().getOutputs(); if (__RO != null) { if (__return != null) { if (__return.containsAll(__RO)) __return = __RO; } else if (ds.getContext().getFieldNames().containsAll(__RO)) __return = __RO; } return __return; } public String getSQLString() throws SlxException { return getSQLString((dataSources.get(0)).getDriver()); } public String getSQLString(SQLDriver driver) throws SlxException { if (remapTable == null || remapTable.size() == 0) { log.debug("SQLSelectClause is null or zero size, remap and conversions won't work!"); return "*"; } StringBuffer __result = new StringBuffer(); Iterator e = remapTable.keySet().iterator(); while (e.hasNext()) { boolean qualifyColumnNames = this.qualifyColumnNames; boolean _skipCusSQLCheck = false; String _rsName = (String) e.next(); String _columnName = (String) remapTable.get(_rsName); String _tableName = qualifyColumnNames ? (String) column2TableMap.get(_columnName) : null; if (_tableName == null && qualifyColumnNames) { DataSource firstDS = dataSources.get(0); if (firstDS instanceof SQLDataSource) _tableName = ((SQLDataSource) firstDS).getTable().getName(); } if (customValueFields != null) { for (String field : customValueFields) { if (field.equalsIgnoreCase(_rsName)) { _skipCusSQLCheck = true; break; } } } else { _skipCusSQLCheck = true; } Tfield __f = null; boolean _exclude = false; for (SQLDataSource ds : dataSources) { __f = ds.getContext().getField(_rsName); if (__f != null) { if (!_skipCusSQLCheck) _exclude = true; else if (__f.getTableName() != null) { _tableName = __f.getTableName(); qualifyColumnNames = true; } break; } }// END datasource. if (!_exclude) { if (__result.length() != 0) __result.append(", "); if (__f != null && __f.getType().value().equals("relatedCount")) __result.append(aggregationSubSelect(driver, _columnName, _rsName, _tableName, __f)); else if (__f != null && __f.getCustomSelectExpression() != null) { __result.append(customSQLExpression(driver, _columnName, _rsName, _tableName, __f, qualifyColumnNames)); } else __result.append(driver.sqlOutTransform(_columnName, _rsName, _tableName)); } } return __result.toString(); } /** * @param driver * @param columnName * @param rsName * @param tableName * @param f * @return */ private String aggregationSubSelect(SQLDriver driver, String columnName, String rsName, String tableName, Tfield f) { // TODO Auto-generated method stub // String relatedTable = field.getProperty("relatedTable"); // String relatedColumn = field.getProperty("relatedColumn"); // String localField = field.getProperty("localField"); // String subselect = " (SELECT "; // subselect = (new StringBuilder()).append(subselect).append("COUNT").toString(); // subselect = (new StringBuilder()).append(subselect).append("(").toString(); // subselect = (new StringBuilder()).append(subselect).append("*").toString(); // subselect = (new StringBuilder()).append(subselect).append(") FROM ").toString(); // subselect = (new StringBuilder()).append(subselect).append(field.getProperty("relatedTable")).toString(); // subselect = (new StringBuilder()).append(subselect).append(" WHERE ").toString(); // subselect = (new StringBuilder()).append(subselect).append(driver.sqlOutTransform(localField, localField, // tableName)).toString(); // subselect = (new StringBuilder()).append(subselect).append(" = ").toString(); // subselect = (new StringBuilder()).append(subselect).append(driver.sqlOutTransform(relatedColumn, // relatedColumn, // relatedTable)).toString(); // subselect = (new StringBuilder()).append(subselect).append(") AS ").toString(); // subselect = (new StringBuilder()).append(subselect).append(field.getName()).toString(); // return subselect; return null; } /** * @param driver * @param columnName * @param rsName * @param tableName * @param f * @return */ private String customSQLExpression(SQLDriver driver, String columnName, String rsName, String tableName, Tfield field, boolean qualifyColumnNames) { String custom = field.getCustomSelectExpression(); if (DataUtils.isNullOrEmpty(custom) && custom.substring(0, 1).equals("$")) { if (custom.substring(0, custom.indexOf(":")).equalsIgnoreCase("$value")) custom = custom.substring(custom.indexOf(":") + 1); } else { if (qualifyColumnNames) custom = tableName + "." + custom; } custom = custom + " AS " + field.getName(); return custom; } }