/********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * * Copyright (C) Contributors * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * * MA 02110-1301, USA. * * * * Contributors: * * - Igor Pojzl, Cloudempiere * * - Peter Takacs, Cloudempiere * **********************************************************************/ package org.compiere.print; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.Map.Entry; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; import org.compiere.model.MColumn; import org.compiere.model.MProcess; import org.compiere.model.MProcessDrillRule; import org.compiere.model.MProcessDrillRulePara; import org.compiere.model.MProcessPara; import org.compiere.model.MQuery; import org.compiere.model.MReportView; import org.compiere.model.MRole; import org.compiere.model.MTable; import org.compiere.model.PrintInfo; import org.compiere.model.Query; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoParameter; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; import org.compiere.util.Util; /** * Drill Report Controller * @author Igor Pojzl, Cloudempiere * */ public class DrillReportCtl { /** Logger */ private static final CLogger log = CLogger.getCLogger(DrillReportCtl.class); private int m_WindowNo = 0; private String m_TableName; private String m_ColumnName; private Object m_Value; private MQuery m_Query; private Integer m_AD_Table_ID; private String m_DisplayValue; /** Process ID of the source Report */ private int m_AD_Process_ID; /** Drill Tables Map */ private KeyNamePair[] drillTables; /** Drill Process Map */ private KeyNamePair[] drillProcessList; /** Drill Process Rule Map */ private HashMap drillProcesRules; /** Drill Process Rule PrintFormats */ private HashMap drillProcessRulesPrintFormatMap = new HashMap<>(); /** * * @param TableName * @param query * @param ColumnName * @param Value * @param displayValue * @param WindowNo * @param processID */ public DrillReportCtl(String TableName, MQuery query, String ColumnName, Object Value, String displayValue, int WindowNo, int processID) { this.m_TableName = TableName; this.m_ColumnName = ColumnName; this.m_Value = Value; this.m_WindowNo = WindowNo; this.m_DisplayValue = displayValue; this.m_AD_Process_ID = processID; m_Query = query; this.initProcessDrillRuleMaps(); } /** * Get Drill Table KeyNamePairs */ public KeyNamePair[] getDrillTables() { return this.drillTables; } /** * Return Array of Drill Process Rules * @return */ public HashMap getDrillProcesRules() { return drillProcesRules; } /** * * @param AD_Process_DrillRule_ID * @return */ public KeyNamePair[] getDrillProcessRulesPrintFormatMap(int AD_Process_DrillRule_ID) { return drillProcessRulesPrintFormatMap.get(AD_Process_DrillRule_ID); } /** * Get Display Value * @return */ public String getDisplayValue() { return m_DisplayValue; } /** * Get Value * @return */ public Object getValue() { return m_Value; } /** * Init Process Drill Rule Maps for Window */ private void initProcessDrillRuleMaps() { // Init Table Name this.m_AD_Table_ID = MTable.getTable_ID(m_TableName); // Init Drill Process Rule Maps initProcessDrillRuleMap(); // Init Drill Process Rule Print Formats initDrillProcessRulePrintFormatMap(); } /** * Initialize Drill Process Rules Map */ private void initProcessDrillRuleMap() { HashMap drillProcessMap = new HashMap<>(); HashMap> drillProcessRuleMap = new HashMap<>(); if(!Util.isEmpty(m_ColumnName)) { MProcessDrillRule[] processDrillRules = MProcessDrillRule.getByColumnName(Env.getCtx(), m_ColumnName, null); for( MProcessDrillRule drillProcesRule: processDrillRules) { if (drillProcesRule.getAD_Process_ID() == 0 || drillProcesRule.getAD_Process_ID() == m_AD_Process_ID) continue; MProcess process = MProcess.get(drillProcesRule.getAD_Process_ID()); drillProcessMap.put(drillProcesRule.getAD_Process_ID(), process.get_Translation(MProcess.COLUMNNAME_Name)); ArrayList drillProcessRuleList = drillProcessRuleMap.get(drillProcesRule.getAD_Process_ID()); if(drillProcessRuleList == null) { drillProcessRuleList = new ArrayList<>(); drillProcessRuleMap.put(drillProcesRule.getAD_Process_ID(), drillProcessRuleList); } drillProcessRuleList.add(new KeyNamePair(drillProcesRule.getAD_Process_DrillRule_ID(), drillProcesRule.getName())); } } ArrayList drillProcessList = new ArrayList<>(); for(Entry drillProcessEntry :drillProcessMap.entrySet()) { drillProcessList.add(new KeyNamePair(drillProcessEntry.getKey(), drillProcessEntry.getValue())); } this.drillProcessList = drillProcessList.toArray(new KeyNamePair[drillProcessList.size()]); HashMap drillProcessRuleMapOut = new HashMap<>(); for(Entry> drillProcessRuleEntry :drillProcessRuleMap.entrySet()) { drillProcessRuleMapOut.put(drillProcessRuleEntry.getKey(), drillProcessRuleEntry.getValue().toArray(new KeyNamePair[drillProcessRuleEntry.getValue().size()])); } this.drillProcesRules = drillProcessRuleMapOut; } /** * Initialize Drill Table Map */ public void initDrillTableMap() { MRole defaultRole = MRole.getDefault(); StringBuilder rolesId = new StringBuilder(); rolesId.append(defaultRole.get_ID()); defaultRole.getIncludedRoles(true).forEach(role -> rolesId.append(",").append(role.get_ID())); ArrayList drillTableList = new ArrayList<>(); String sql = "SELECT DISTINCT t.AD_Table_ID, t.TableName, e.PrintName, NULLIF(e.PO_PrintName,e.PrintName) " + "FROM AD_Column c " + " INNER JOIN AD_Column used ON (c.ColumnName=used.ColumnName)" + " INNER JOIN AD_Table t ON (used.AD_Table_ID=t.AD_Table_ID AND t.IsView='N' AND t.AD_Table_ID <> c.AD_Table_ID AND t.IsShowInDrillOptions='Y')" + " INNER JOIN AD_Tab tab ON (t.AD_Table_ID = tab.AD_Table_ID AND tab.isActive = 'Y') " + " INNER JOIN AD_Window_Access w ON (tab.AD_Window_ID = w.AD_Window_ID AND w.isActive = 'Y') " + " INNER JOIN AD_Column cKey ON (t.AD_Table_ID=cKey.AD_Table_ID AND cKey.IsKey='Y')" + " INNER JOIN AD_Element e ON (cKey.ColumnName=e.ColumnName) " + "WHERE c.AD_Table_ID=? AND w.AD_Role_ID IN (" + rolesId.toString() + ") AND c.IsKey='Y' " + "ORDER BY 3 "; boolean trl = !Env.isBaseLanguage(Env.getCtx(), "AD_Element"); if (trl) sql = "SELECT DISTINCT t.AD_Table_ID, t.TableName, et.PrintName, NULLIF(et.PO_PrintName,et.PrintName) " + "FROM AD_Column c" + " INNER JOIN AD_Column used ON (c.ColumnName=used.ColumnName)" + " INNER JOIN AD_Table t ON (used.AD_Table_ID=t.AD_Table_ID AND t.IsView='N' AND t.AD_Table_ID <> c.AD_Table_ID AND t.IsShowInDrillOptions='Y')" + " INNER JOIN AD_Tab tab ON (t.AD_Table_ID = tab.AD_Table_ID AND tab.isActive = 'Y') " + " INNER JOIN AD_Window_Access w ON (tab.AD_Window_ID = w.AD_Window_ID AND w.isActive = 'Y') " + " INNER JOIN AD_Column cKey ON (t.AD_Table_ID=cKey.AD_Table_ID AND cKey.IsKey='Y')" + " INNER JOIN AD_Element e ON (cKey.ColumnName=e.ColumnName)" + " INNER JOIN AD_Element_Trl et ON (e.AD_Element_ID=et.AD_Element_ID) " + "WHERE c.AD_Table_ID=? AND w.AD_Role_ID IN (" + rolesId.toString() + ") AND c.IsKey='Y' " + " AND et.AD_Language=? " + "ORDER BY 3 "; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, m_AD_Table_ID); if (trl) pstmt.setString(2, Env.getAD_Language(Env.getCtx())); rs = pstmt.executeQuery(); while (rs.next()) { int ad_Table_ID = rs.getInt(1); String name = rs.getString(3); String poName = rs.getString(4); if (poName != null) name += "/" + poName; drillTableList.add(new KeyNamePair(ad_Table_ID, name)); } } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } this.drillTables = drillTableList.toArray(new KeyNamePair[drillTableList.size()]); } /** * Initialize Print Formats for Table Name */ private void initDrillProcessRulePrintFormatMap() { int AD_Window_ID = Env.getContextAsInt(Env.getCtx(), this.m_WindowNo, "_WinInfo_AD_Window_ID", true); if (AD_Window_ID == 0) AD_Window_ID = Env.getZoomWindowID(m_Query); for( KeyNamePair[] drilProcessRuleList : drillProcesRules.values() ) { for( KeyNamePair drillProcessRule : drilProcessRuleList ) { // MProcessDrillRule processDrillRule = MProcessDrillRule.get(Env.getCtx(), drillProcessRule.getKey()); KeyNamePair[] m_list = null; if(processDrillRule.getAD_PrintFormat_ID() > 0) { // Print Format MPrintFormat pf = MPrintFormat.get(processDrillRule.getAD_PrintFormat_ID()); if(pf != null) { m_list = new KeyNamePair[] { new KeyNamePair(pf.getAD_PrintFormat_ID(), drillProcessRule.getName())}; } } else if(processDrillRule.getAD_ReportView_ID() > 0) { // Report View MReportView reportView = MReportView.get(processDrillRule.getAD_ReportView_ID()); m_list = getPrintFormats(reportView.getAD_Table_ID(), reportView.getAD_ReportView_ID()); } else { MProcess process = MProcess.get(processDrillRule.getAD_Process_ID()); if(process == null || process.getAD_ReportView_ID() <= 0) continue; MReportView reportView = MReportView.get(process.getAD_ReportView_ID()); m_list = getPrintFormats(reportView.getAD_Table_ID(), reportView.getAD_ReportView_ID()); } this.drillProcessRulesPrintFormatMap.put(drillProcessRule.getKey(), m_list); } } } private KeyNamePair[] getPrintFormats(int table_ID, int reportView_ID) { ArrayList printFormatList = new ArrayList<>(); // fill Report Options String sql = MRole.getDefault().addAccessSQL( "SELECT * " + "FROM AD_PrintFormat " + "WHERE AD_Table_ID=? " + "AND IsActive='Y' " + (reportView_ID > 0 ? "AND AD_ReportView_ID=? " : "") + "ORDER BY AD_Client_ID, Name", "AD_PrintFormat", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); int idx = 1; pstmt.setInt(idx++, table_ID); if (reportView_ID > 0) pstmt.setInt(idx++, reportView_ID); rs = pstmt.executeQuery(); while (rs.next()) { MPrintFormat printFormat = new MPrintFormat (Env.getCtx(), rs, null); KeyNamePair pp = new KeyNamePair(printFormat.get_ID(), printFormat.get_Translation(MPrintFormat.COLUMNNAME_Name, Env.getAD_Language(Env.getCtx()), true)); printFormatList.add(pp); } } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } return printFormatList.toArray(new KeyNamePair[printFormatList.size()]); } /** * Launch Report * @param ad_PrintFormat_ID print format * @param tableName */ public void launchTableDrillReport (int ad_PrintFormat_ID, String tableName) { MPrintFormat pf = null; if(ad_PrintFormat_ID == 0) { int AD_Table_ID = new Query(Env.getCtx(), MTable.Table_Name, " Name = ? ", null).setParameters(tableName).firstId(); pf = MPrintFormat.createFromTable(Env.getCtx(), AD_Table_ID > 0 ? AD_Table_ID : m_AD_Table_ID); } else pf = MPrintFormat.get(ad_PrintFormat_ID); int Record_ID = 0; if (m_Query.getRestrictionCount() == 1) { if (m_Query.getColumnName(0).equals(m_Query.getTableName()+"_ID")) { Object vrec = m_Query.getCode(0); if (vrec instanceof Integer) { Record_ID = ((Integer)vrec).intValue(); } else { try { if(vrec != null) Record_ID = Integer.parseInt(m_Query.getCode(0).toString()); } catch (NumberFormatException e) { log.info(e.getMessage()); } } } } PrintInfo info = new PrintInfo( pf.getName(), pf.getAD_Table_ID(), Record_ID); info.setDescription(m_Query.getInfo()); // It's a default report using the standard printing engine ReportEngine re = new ReportEngine (Env.getCtx(), pf, m_Query, info,null,m_WindowNo); ReportCtl.preview(re); } // launchReport /** * * @param AD_Process_DrillRule_ID * @param AD_PrintFormat_ID * @return * @throws Exception */ public ProcessInfo getDrillProcessProcessInfo (int AD_Process_DrillRule_ID, int AD_PrintFormat_ID) throws Exception { MProcessDrillRule drillRule = MProcessDrillRule.get(Env.getCtx(), AD_Process_DrillRule_ID); MProcess process = new MProcess(Env.getCtx(), drillRule.getAD_Process_ID(), null); return prepareProcessInfo(process, drillRule, AD_PrintFormat_ID); // It's a default report using the standard printing engine } // launchReport /** * Run Process or Report * @param process process * @return summary * @throws Exception */ protected ProcessInfo prepareProcessInfo(MProcess process,MProcessDrillRule processDrillRule, int ad_PrintFormat_ID) throws Exception { if (log.isLoggable(Level.INFO)) log.info(process.toString()); ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID()); pi.setAD_User_ID(Env.getAD_User_ID(Env.getCtx())); pi.setAD_Client_ID(processDrillRule.getAD_Client_ID()); pi.setAD_Process_UU(process.getAD_Process_UU()); pi.setIsBatch(true); pi.setPrintPreview(true); fillParameter(pi, processDrillRule); int AD_PrintFormat_ID = ad_PrintFormat_ID > 0 ? ad_PrintFormat_ID : processDrillRule.getAD_PrintFormat_ID(); if (AD_PrintFormat_ID > 0) { MPrintFormat format = new MPrintFormat(Env.getCtx(), AD_PrintFormat_ID, null); pi.setSerializableObject(format); } if (!Util.isEmpty(process.getJasperReport())) { pi.setExport(true); if ("HTML".equals(pi.getReportType())) pi.setExportFileExtension("html"); else if ("CSV".equals(pi.getReportType())) pi.setExportFileExtension("csv"); else if ("XLS".equals(pi.getReportType())) pi.setExportFileExtension("xls"); else if ("XLSX".equals(pi.getReportType())) pi.setExportFileExtension("xlsx"); else pi.setExportFileExtension("pdf"); } return pi; } // runProcess /** * Fill Parameter * @param pi process info * @param processDrillRule */ protected void fillParameter(ProcessInfo pi, MProcessDrillRule processDrillRule) { boolean isKeyParameterSet = false; MProcessDrillRulePara[] sParams = processDrillRule.getParameters (true); ArrayList iParams = new ArrayList(); MProcess process = (MProcess) processDrillRule.getAD_Process(); ArrayList processParasExclDrillRuleParas = new ArrayList(Arrays.asList(process.getParameters())); // Check for key parameter for(int i = 0; i < sParams.length; i++) { if(sParams[i].getAD_Process_Para().getColumnName().equals(m_ColumnName)) { isKeyParameterSet = true; } } if(!isKeyParameterSet) { MProcessDrillRulePara keyPara = new MProcessDrillRulePara(Env.getCtx(), 0, null); keyPara.setAD_Process_DrillRule_ID(processDrillRule.getAD_Process_DrillRule_ID()); keyPara.setAD_Process_Para_ID(processDrillRule.getAD_Process_Para_ID()); MProcessDrillRulePara[] sParamsTmp = Arrays.stream(sParams).toArray(MProcessDrillRulePara[]::new);; sParams = new MProcessDrillRulePara[sParamsTmp.length+1]; int idx = 0; for(idx = 0; idx < sParamsTmp.length; idx++) { sParams[idx] = sParamsTmp[idx]; } sParams[idx] = keyPara; isKeyParameterSet = true; } for (int p = 0; p < sParams.length; p++) { MProcessPara processPara = (MProcessPara) sParams[p].getAD_Process_Para(); ProcessInfoParameter iPara = new ProcessInfoParameter(processPara.getColumnName(), null, null, null, null); MProcessDrillRulePara sPara = sParams[p]; if(processPara.getColumnName().equals(m_ColumnName)) { if(m_Value == null) { if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " - empty"); continue; } iPara.setParameter(DisplayType.isID(sPara.getDisplayType()) ? new BigDecimal(String.valueOf(m_Value)) : String.valueOf(m_Value)); iPara.setInfo(!Util.isEmpty(m_DisplayValue) ? m_DisplayValue : String.valueOf(m_Value)); iParams.add(iPara); processParasExclDrillRuleParas.remove(processPara); continue; } String paraDesc = sPara.getDescription(); if (paraDesc != null && paraDesc.trim().length() > 0) iPara.setInfo(sPara.getDescription()); String variable = sPara.getParameterDefault(); String toVariable = sPara.getParameterToDefault(); if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " = " + variable); // Value - Constant/Variable Object value = parseVariable(sPara, variable); Object toValue = toVariable != null ? parseVariable(sPara, toVariable) : null; // No Value if (value == null && toValue == null) { if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " - empty"); continue; } // Convert to Type try { if (DisplayType.isNumeric(sPara.getDisplayType()) || DisplayType.isID(sPara.getDisplayType())) { DecimalFormat decimalFormat = DisplayType.getNumberFormat(sPara.getDisplayType()); BigDecimal bd = toBigDecimal(value); iPara.setParameter(bd); if (toValue != null) { bd = toBigDecimal(toValue); iPara.setParameter_To(bd); } if (Util.isEmpty(paraDesc)) { String info = decimalFormat.format(iPara.getParameterAsBigDecimal()); if (iPara.getParameter_ToAsBigDecimal() != null) info = info + " - " + decimalFormat.format(iPara.getParameter_ToAsBigDecimal()); iPara.setInfo(info); } if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " = " + variable + " (=" + bd + "=)"); } else if (DisplayType.isDate(sPara.getDisplayType())) { SimpleDateFormat dateFormat = DisplayType.getDateFormat(sPara.getDisplayType()); Timestamp ts = toTimestamp(value); iPara.setParameter(ts); if (toValue != null) { ts = toTimestamp(toValue); iPara.setParameter_To(ts); } if (Util.isEmpty(paraDesc)) { String info = dateFormat.format(iPara.getParameterAsTimestamp()); if (iPara.getParameter_ToAsTimestamp() != null) { info = info + " - " + dateFormat.format(iPara.getParameter_ToAsTimestamp()); } iPara.setInfo(info); } if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " = " + variable + " (=" + ts + "=)"); } else { iPara.setParameter(value.toString()); if (toValue != null) { iPara.setParameter_To(toValue.toString()); } if (Util.isEmpty(paraDesc)) { String info = iPara.getParameterAsString(); if (iPara.getParameter_ToAsString() != null) { info = info + " - " + iPara.getParameter_ToAsString(); } iPara.setInfo(info); } if (log.isLoggable(Level.FINE)) log.fine(sPara.getColumnName() + " = " + variable + " (=" + value + "=) " + value.getClass().getName()); } // Mandatory check if(processPara.isMandatory() && Util.isEmpty(sPara.getParameterDefault()) && !MProcessDrillRule.SHOWHELP_ShowHelp.equalsIgnoreCase(processDrillRule.getShowHelp())) { if((!processPara.isRange()) || (processPara.isRange() && Util.isEmpty(sPara.getParameterToDefault()))) throw new AdempiereException(Msg.parseTranslation(Env.getCtx(), "@FillMandatoryDrillRulePara@")); } processParasExclDrillRuleParas.remove(processPara); iParams.add(iPara); } catch (Exception e) { log.warning(sPara.getColumnName() + " = " + variable + " (" + value + ") " + value.getClass().getName() + " - " + e.getLocalizedMessage()); } } // Drill Rule Parameter loop // Mandatory check if(!MProcessDrillRule.SHOWHELP_ShowHelp.equalsIgnoreCase(processDrillRule.getShowHelp())) { for(MProcessPara unsetProcessPara : processParasExclDrillRuleParas) { if(unsetProcessPara.isMandatory()) { throw new AdempiereException(Msg.parseTranslation(Env.getCtx(), "@FillMandatoryDrillRulePara@")); } } } pi.setParameter(iParams.toArray(new ProcessInfoParameter[0])); if(!isKeyParameterSet) { throw new AdempiereException(Msg.parseTranslation(Env.getCtx(), "@NoDrillKeyParameterSet@")); } } // fillParameter private Timestamp toTimestamp(Object value) { Timestamp ts = null; if (value instanceof Timestamp) ts = (Timestamp)value; else ts = Timestamp.valueOf(value.toString()); return ts; } private BigDecimal toBigDecimal(Object value) { BigDecimal bd = null; if (value instanceof BigDecimal) bd = (BigDecimal)value; else if (value instanceof Integer) bd = new BigDecimal (((Integer)value).intValue()); else bd = new BigDecimal (value.toString()); return bd; } private Object parseVariable(MProcessDrillRulePara sPara, String variable) { Object value = variable; if (variable == null || (variable != null && variable.length() == 0)) value = null; else if (variable.startsWith(MColumn.VIRTUAL_UI_COLUMN_PREFIX)) { String defStr = ""; String sql = variable.substring(5); // w/o tag //hengsin, capture unparseable error to avoid subsequent sql exception sql = Env.parseContext(Env.getCtx(), 0, sql, false, false); // replace variables if (sql.equals("")) log.log(Level.WARNING, "(" + sPara.getColumnName() + ") - Default SQL variable parse failed: " + variable); else { PreparedStatement stmt = null; ResultSet rs = null; try { stmt = DB.prepareStatement(sql, null); rs = stmt.executeQuery(); if (rs.next()) defStr = rs.getString(1); else { if (log.isLoggable(Level.INFO)) log.log(Level.INFO, "(" + sPara.getColumnName() + ") - no Result: " + sql); } } catch (SQLException e) { log.log(Level.WARNING, "(" + sPara.getColumnName() + ") " + sql, e); } finally{ DB.close(rs, stmt); rs = null; stmt = null; } } if (!Util.isEmpty(defStr)) value = defStr; } // SQL Statement else if ( variable.indexOf('@') != -1 && variable.indexOf('@') != variable.lastIndexOf('@')) // we have a variable / BF [1926032] { // Strip int index = variable.indexOf('@'); String columnName = variable.substring(index+1); index = columnName.indexOf('@'); if (index == -1) { log.warning(sPara.getColumnName() + " - cannot evaluate=" + variable); return null; } String tail=index < (columnName.length()-1) ? columnName.substring(index+1) : null; columnName = columnName.substring(0, index); // try Env String env = Env.getContext(Env.getCtx(), columnName); if (env == null || env.length() == 0) env = Env.getContext(Env.getCtx(), columnName); if (env.length() == 0) { log.warning(sPara.getColumnName() + " - not in environment =" + columnName + "(" + variable + ")"); if(DisplayType.isDate(sPara.getDisplayType())) { return Env.getContext(Env.getCtx(), "#Date"); } return null; } else value = env; if (tail != null && columnName.equals("#Date")) { tail = tail.trim(); if (tail.startsWith("-") || tail.startsWith("+")) { boolean negate = tail.startsWith("-"); int type = Calendar.DATE; tail = tail.substring(1); if (tail.endsWith("d")) { tail = tail.substring(0, tail.length()-1); } else if (tail.endsWith("m")) { type = Calendar.MONTH; tail = tail.substring(0, tail.length()-1); } else if (tail.endsWith("y")) { type = Calendar.YEAR; tail = tail.substring(0, tail.length()-1); } int toApply = 0; try { toApply = Integer.parseInt(tail); } catch(Exception e){} if (toApply > 0) { if (negate) toApply = toApply * -1; Timestamp ts = toTimestamp(value); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(ts.getTime()); cal.add(type, toApply); value = new Timestamp(cal.getTimeInMillis()); } } } } // @variable@ return value; } /** * Get Table Name * @return */ public String getTableName() { return m_TableName; } /** * Get Drill Process List * @return */ public KeyNamePair[] getDrillProcessList() { return drillProcessList; } /** * Get Drill Process Rules Print Format Map * @return */ public HashMap getDrillProcessRulesPrintFormatMap() { return drillProcessRulesPrintFormatMap; } }