/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 ro.nextreports.designer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Date; import java.util.Set; import java.sql.Connection; import ro.nextreports.engine.queryexec.QueryParameter; import ro.nextreports.engine.util.QueryUtil; import ro.nextreports.engine.util.NameType; import ro.nextreports.engine.util.ReportUtil; import ro.nextreports.engine.Report; import ro.nextreports.engine.ReportGroup; import ro.nextreports.engine.ReportLayout; import ro.nextreports.engine.exporter.util.variable.Variable; import ro.nextreports.engine.exporter.util.variable.VariableFactory; import ro.nextreports.engine.exporter.ResultExporter; import org.apache.commons.jexl2.JexlEngine; import org.apache.commons.jexl2.Expression; import org.apache.commons.jexl2.JexlContext; import org.apache.commons.jexl2.MapContext; import org.apache.commons.jexl2.JexlException; import ro.nextreports.designer.datasource.DataSource; import ro.nextreports.designer.datasource.DefaultDataSourceManager; import ro.nextreports.designer.querybuilder.ParameterManager; import ro.nextreports.designer.querybuilder.QueryBuilderPanel; import ro.nextreports.designer.util.I18NSupport; import ro.nextreports.designer.util.Show; /** * Created by IntelliJ IDEA. * User: mihai.panaitescu * Date: Sep 18, 2008 * Time: 2:42:33 PM */ public class ReportLayoutUtil { public static List<NameType> getAllColumnsForReport(Report report) throws Exception { return getAllColumnsForReport(report, DefaultDataSourceManager.getInstance().getConnectedDataSource()); } public static List<NameType> getAllColumnsForReport(Report report, DataSource ds) throws Exception { String sql; if (report == null) { QueryBuilderPanel builderPanel = Globals.getMainFrame().getQueryBuilderPanel(); builderPanel.refreshSql(); sql = builderPanel.getUserSql(); } else { if (report.getSql() != null) { sql = report.getSql(); } else { sql = report.getQuery().toString(); } } return getAllColumnsForSql(report, sql, ds); } public static List<String> getAllColumnNamesForReport(Report report) throws Exception { return getAllColumnNamesForReport(report, DefaultDataSourceManager.getInstance().getConnectedDataSource()); } public static List<String> getAllColumnNamesForReport(Report report, DataSource ds) throws Exception { String sql; if (report == null) { QueryBuilderPanel builderPanel = Globals.getMainFrame().getQueryBuilderPanel(); builderPanel.refreshSql(); sql = builderPanel.getUserSql(); } else { if (report.getSql() != null) { sql = report.getSql(); } else { sql = report.getQuery().toString(); } } return getAllColumnNamesForSql(report, sql, ds); } public static Set<String> getAllColumnNamesUsedByGroupes(ReportLayout layout) { Set<String> columnNames = new HashSet<String>(); List<ReportGroup> groups = layout.getGroups(); if ((groups != null) && (groups.size() > 0)) { for (ReportGroup group : groups) { Integer index = Integer.parseInt(group.getName()); columnNames.add(group.getColumn()); } } return columnNames; } public static List<String> getAllColumnNamesForSql(Report report, String sql) throws Exception { return getAllColumnNamesForSql(report, sql, DefaultDataSourceManager.getInstance().getConnectedDataSource()); } public static List<String> getAllColumnNamesForSql(Report report, String sql, DataSource dataSource) throws Exception { List<NameType> columns = getAllColumnsForSql(report, sql, dataSource); List<String> columnNames = new ArrayList<String>(); for (NameType nt : columns) { columnNames.add(nt.getName()); } return columnNames; } public static List<NameType> getAllColumnsForSql(Report report, String sql, DataSource dataSource) throws Exception { List<NameType> columns = new ArrayList<NameType>(); String md5Key = Cache.getColumnsKey(sql); List<NameType> result = Cache.getColumns(md5Key); if (result != null) { return result; } Connection con = null; try { con = Globals.createTempConnection(dataSource); QueryUtil qu = new QueryUtil(con, Globals.getDialect()); // get parameters definition from system Map<String, QueryParameter> params = new HashMap<String, QueryParameter>(); if (report == null) { ParameterManager paramManager = ParameterManager.getInstance(); List<String> paramNames = paramManager.getParameterNames(); for (String paramName : paramNames) { QueryParameter param = paramManager.getParameter(paramName); if (param == null) { throw new Exception(I18NSupport.getString("parameter.undefined", paramName)); } params.put(paramName, param); } } else { for (QueryParameter param : report.getParameters()) { params.put(param.getName(), param); } } columns = qu.getColumns(sql, params); Cache.setColumns(md5Key, columns); } finally { if (con != null) { con.close(); } } return columns; } public static List<String> getAllColumnTypesForReport(String sql) throws Exception { List<String> columnTypes = new ArrayList<String>(); Connection con = null; String md5Key = Cache.getColumnsKey(sql); List<NameType> result = Cache.getColumns(md5Key); if (result != null) { return ReportUtil.getColumnTypes(result); } try { con = Globals.createTempConnection( DefaultDataSourceManager.getInstance().getConnectedDataSource()); QueryUtil qu = new QueryUtil(con, Globals.getDialect()); // get parameters definition from system Map<String, QueryParameter> params = new HashMap<String, QueryParameter>(); ParameterManager paramManager = ParameterManager.getInstance(); List<String> paramNames = paramManager.getParameterNames(); for (String paramName : paramNames) { QueryParameter param = paramManager.getParameter(paramName); if (param == null) { throw new Exception(I18NSupport.getString("parameter.undefined", paramName)); } params.put(paramName, param); } List <NameType> columns = qu.getColumns(sql, params); columnTypes = ReportUtil.getColumnTypes(columns); Cache.setColumns(md5Key, columns); } finally { if (con != null) { con.close(); } } return columnTypes; } public static List<NameType> getAllColumnsForReport(String sql) throws Exception { List<NameType> columnTypes = new ArrayList<NameType>(); String md5Key = Cache.getColumnsKey(sql); List<NameType> result = Cache.getColumns(md5Key); if (result != null) { return result; } Connection con = null; try { con = Globals.createTempConnection( DefaultDataSourceManager.getInstance().getConnectedDataSource()); QueryUtil qu = new QueryUtil(con, Globals.getDialect()); // get parameters definition from system Map<String, QueryParameter> params = new HashMap<String, QueryParameter>(); ParameterManager paramManager = ParameterManager.getInstance(); List<String> paramNames = paramManager.getParameterNames(); for (String paramName : paramNames) { QueryParameter param = paramManager.getParameter(paramName); if (param == null) { throw new Exception(I18NSupport.getString("parameter.undefined", paramName)); } params.put(paramName, param); } columnTypes = qu.getColumns(sql, params); Cache.setColumns(md5Key, columnTypes); } finally { if (con != null) { con.close(); } } return columnTypes; } public static List<String> getColumnNames(List<NameType> columns) { List<String> names = new ArrayList<String>(); if (columns != null) { for (NameType nt : columns) { names.add(nt.getName()); } } return names; } public static String getColumnTypeForReportColumn(String sql, String column) throws Exception { Connection con = null; String md5Key = Cache.getColumnsKey(sql); List<NameType> result = Cache.getColumns(md5Key); if (result != null) { return getColumnTypeByName(column, result); } try { con = Globals.createTempConnection( DefaultDataSourceManager.getInstance().getConnectedDataSource()); QueryUtil qu = new QueryUtil(con, Globals.getDialect()); // get parameters definition from system Map<String, QueryParameter> params = new HashMap<String, QueryParameter>(); ParameterManager paramManager = ParameterManager.getInstance(); List<String> paramNames = paramManager.getParameterNames(); for (String paramName : paramNames) { QueryParameter param = paramManager.getParameter(paramName); if (param == null) { throw new Exception(I18NSupport.getString("parameter.undefined", paramName)); } params.put(paramName, param); } List<NameType> columns = qu.getColumns(sql, params); Cache.setColumns(md5Key, columns); return getColumnTypeByName(column, columns); } finally { if (con != null) { con.close(); } } } private static String getColumnTypeByName(String columnName, List<NameType> list) { for (NameType nt : list) { if (nt.getName().equalsIgnoreCase(columnName)) { return nt.getType(); } } return null; } public static void setCurrentGroupIndex(ReportLayout layout) { List<ReportGroup> groups = layout.getGroups(); if ((groups == null) || (groups.size() == 0)) { GroupIndexGenerator.resetCurrentIndex(); } else { int lastIndex = 0; for (ReportGroup group : groups) { Integer index = Integer.parseInt(group.getName()); if (index > lastIndex) { lastIndex = index; } } GroupIndexGenerator.setCurrentIndex(lastIndex); } } public static void resizeColumn(ReportGrid grid, int column, int size) { grid.setColumnWidth(column, size); int total = 0; List<Integer> columnsWidth = new ArrayList<Integer>(); for (int i = 0, n = grid.getColumnCount(); i < n; i++) { total += grid.getColumnWidth(i); columnsWidth.add(grid.getColumnWidth(i)); } LayoutHelper.getReportLayout().setColumnsWidth(columnsWidth); } public static void updateColumnWidth(ReportGrid grid) { List<Integer> columnsWidth = new ArrayList<Integer>(); for (int i = 0, n = Globals.getReportGrid().getColumnCount(); i < n; i++) { columnsWidth.add(Globals.getReportGrid().getColumnWidth(i)); } LayoutHelper.getReportLayout().setColumnsWidth(columnsWidth); } public static String getColumnType(String column) { String type = "java.lang.Double"; String sql = Globals.getMainFrame().getQueryBuilderPanel().getUserSql(); if (column != null) { try { type = getColumnTypeForReportColumn(sql, column); } catch (Exception e) { e.printStackTrace(); } } return type; } public static String getExpressionType(String expression) { Object value = null; try { value = testExpression(expression); } catch (JexlException ex) { ex.printStackTrace(); Show.error(ex); } String type = "java.lang.Double"; if ((value instanceof String) || (value instanceof Boolean) || (value instanceof Date) ) { type = value.getClass().getCanonicalName(); } return type; } public static boolean isValidExpression(String expression) { Object value = null; try { value = testExpression(expression); } catch (JexlException ex) { ex.printStackTrace(); return false; } return true; } public static boolean isValidBooleanExpression(String expression) { Object value = null; try { value = testExpression(expression); if ( !(value instanceof Boolean) ) { return false; } } catch (JexlException ex) { ex.printStackTrace(); return false; } return true; } private static Object testExpression(String expression) throws JexlException { Object value = null; JexlEngine jexl = new JexlEngine(); Expression e = jexl.createExpression(expression); // create context with all variables, parameters and columns // make sure to replace spaces in column names (as in designer expression evaluator) JexlContext checkContext = new MapContext(); // default values for variables for (Variable variable : VariableFactory.getVariables()) { Object obj = "test"; if (variable.getName().equals(Variable.DATE_VARIABLE)) { obj = new Date(); } else if ((variable.getName().equals(Variable.ROW_VARIABLE)) || (variable.getName().equals(Variable.GROUP_ROW_VARIABLE)) ) { obj = new Integer(1); } else if (variable.getName().equals(Variable.EMPTY_DATA_VARIABLE)) { obj = Boolean.FALSE; } checkContext.set("$V_" + variable.getName(), obj); } // default values for parameters for (QueryParameter parameter : ParameterManager.getInstance().getParameters()) { Object obj = new Integer(1); if ("java.lang.String".equals(parameter.getValueClassName())) { obj = "test"; } else if ("java.lang.Boolean".equals(parameter.getValueClassName())) { obj = Boolean.TRUE; } else if ("java.util.Date".equals(parameter.getValueClassName())) { obj = new Date(); } checkContext.set("$P_" + parameter.getName(), obj); } // default values for columns try { List<NameType> columns = getAllColumnsForReport(Globals.getMainFrame().getQueryBuilderPanel().getUserSql()); for (NameType nt : columns) { String columnName = nt.getName(); String col = columnName.replaceAll("\\s", ResultExporter.SPACE_REPLACEMENT); Object obj = new Integer(1); if ("java.lang.String".equals(nt.getType())) { obj = "test"; } else if ("java.util.Date".equals(nt.getType())) { obj = new Date(); } else if ("java.lang.Boolean".equals(nt.getType())) { obj = Boolean.TRUE; } checkContext.set("$C_" + col, obj); } } catch (Exception e1) { e1.printStackTrace(); } // default values for functions for (String function : LayoutHelper.getReportLayout().getFunctions()) { checkContext.set("$F_" + function, new Integer(1)); } value = e.evaluate(checkContext); return value; } }