/****************************************************************************** * Product: Posterita Ajax UI * * Copyright (C) 2007 Posterita Ltd. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. 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., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * or via info@posterita.org or http://www.posterita.org/ * *****************************************************************************/ package org.adempiere.webui.apps; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import javax.servlet.ServletRequest; import org.adempiere.webui.component.Window; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; import org.compiere.acct.Doc; import org.compiere.model.GridWindowVO; import org.compiere.model.Lookup; import org.compiere.model.MAcctSchema; import org.compiere.model.MQuery; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.CacheMgt; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Ini; import org.compiere.util.Language; import org.zkoss.web.servlet.Servlets; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Execution; import org.zkoss.zk.ui.Executions; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; /** * ZK Application Environment and utilities * * @author Jorg Janke * @version $Id: AEnv.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $ * * Colin Rooney (croo) & kstan_79 RFE#1670185 */ public final class AEnv { public static final String LOCALE = "#Locale"; /** * Show in the center of the screen. * (pack, set location and set visibility) * @param window Window to position */ public static void showCenterScreen(Window window) { SessionManager.getAppDesktop().showWindow(window, "center"); } // showCenterScreen /** * Position window in center of the screen * @param window Window to position */ public static void positionCenterScreen(Window window) { showCenterScreen(window); } // positionCenterScreen /** * Show in the center of the screen. * (pack, set location and set visibility) * @param window Window to position * @param position */ public static void showScreen(Window window, String position) { SessionManager.getAppDesktop().showWindow(window, position); } // showScreen /** * Position in center of the parent window. * (pack, set location and set visibility) * @param parent Parent Window * @param window Window to position */ public static void showCenterWindow(Window parent, Window window) { parent.appendChild(window); showScreen(window, "parent,center"); } // showCenterWindow /** * Get Mnemonic character from text. * @param text text with '&' * @return Mnemonic or 0 */ public static char getMnemonic (String text) { int pos = text.indexOf('&'); if (pos != -1) // We have a nemonic return text.charAt(pos+1); return 0; } // getMnemonic /************************************************************************* * Zoom * @param AD_Table_ID * @param Record_ID */ public static void zoom (int AD_Table_ID, int Record_ID) { String TableName = null; int AD_Window_ID = 0; int PO_Window_ID = 0; String sql = "SELECT TableName, AD_Window_ID, PO_Window_ID FROM AD_Table WHERE AD_Table_ID=?"; try { PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, AD_Table_ID); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { TableName = rs.getString(1); AD_Window_ID = rs.getInt(2); PO_Window_ID = rs.getInt(3); } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } // Nothing to Zoom to if (TableName == null || AD_Window_ID == 0) return; // PO Zoom ? boolean isSOTrx = true; if (PO_Window_ID != 0) { String whereClause = TableName + "_ID=" + Record_ID; isSOTrx = DB.isSOTrx(TableName, whereClause); if (!isSOTrx) AD_Window_ID = PO_Window_ID; } log.config(TableName + " - Record_ID=" + Record_ID + " (IsSOTrx=" + isSOTrx + ")"); zoom(AD_Window_ID, MQuery.getEqualQuery(TableName + "_ID", Record_ID)); } // zoom /** * Exit System * @param status System exit status (usually 0 for no error) */ public static void exit (int status) { Env.exitEnv(status); } // exit public static void logout() { Env.logout(); } /** * Start Workflow Process Window * @param AD_Table_ID optional table * @param Record_ID optional record */ public static void startWorkflowProcess (int AD_Table_ID, int Record_ID) { if (s_workflow_Window_ID <= 0) { int AD_Window_ID = DB.getSQLValue(null, "SELECT AD_Window_ID FROM AD_Window WHERE Name = 'Workflow Process'"); s_workflow_Window_ID = AD_Window_ID; } if (s_workflow_Window_ID <= 0) return; MQuery query = new MQuery(); query.addRestriction("AD_Table_ID", MQuery.EQUAL, AD_Table_ID); query.addRestriction("Record_ID", MQuery.EQUAL, Record_ID); AEnv.zoom(s_workflow_Window_ID, query); } // startWorkflowProcess /*************************************************************************/ /** Workflow Window */ private static int s_workflow_Window_ID = 0; /** Logger */ private static CLogger log = CLogger.getCLogger(AEnv.class); /** Window Cache */ private static Map<String, CCache<Integer,GridWindowVO>> windowCache = new HashMap<String, CCache<Integer,GridWindowVO>>(); /** * Get Window Model * * @param WindowNo Window No * @param AD_Window_ID window * @param AD_Menu_ID menu * @return Model Window Value Obkect */ public static GridWindowVO getMWindowVO (int WindowNo, int AD_Window_ID, int AD_Menu_ID) { log.config("Window=" + WindowNo + ", AD_Window_ID=" + AD_Window_ID); GridWindowVO mWindowVO = null; String locale = Env.getLanguage(Env.getCtx()).getLocale().toString(); if (AD_Window_ID != 0 && Ini.isCacheWindow()) // try cache { synchronized (windowCache) { CCache<Integer,GridWindowVO> cache = windowCache.get(locale); if (cache != null) { mWindowVO = cache.get(AD_Window_ID); if (mWindowVO != null) { mWindowVO = mWindowVO.clone(WindowNo); log.info("Cached=" + mWindowVO); } } } } // Create Window Model on Client if (mWindowVO == null) { log.config("create local"); mWindowVO = GridWindowVO.create (Env.getCtx(), WindowNo, AD_Window_ID, AD_Menu_ID); if (mWindowVO != null) { synchronized (windowCache) { CCache<Integer,GridWindowVO> cache = windowCache.get(locale); if (cache == null) { cache = new CCache<Integer, GridWindowVO>("AD_Window", 10); windowCache.put(locale, cache); } cache.put(AD_Window_ID, mWindowVO); } } } // from Client if (mWindowVO == null) return null; // Check (remote) context if (!mWindowVO.ctx.equals(Env.getCtx())) { // Remote Context is called by value, not reference // Add Window properties to context Enumeration<Object> keyEnum = mWindowVO.ctx.keys(); while (keyEnum.hasMoreElements()) { String key = (String)keyEnum.nextElement(); if (key.startsWith(WindowNo+"|")) { String value = mWindowVO.ctx.getProperty (key); Env.setContext(Env.getCtx(), key, value); } } // Sync Context mWindowVO.setCtx(Env.getCtx()); } return mWindowVO; } // getWindow /** * Post Immediate * @param WindowNo window * @param AD_Table_ID Table ID of Document * @param AD_Client_ID Client ID of Document * @param Record_ID Record ID of this document * @param force force posting * @return null if success, otherwise error */ public static String postImmediate (int WindowNo, int AD_Client_ID, int AD_Table_ID, int Record_ID, boolean force) { log.info("Window=" + WindowNo + ", AD_Table_ID=" + AD_Table_ID + "/" + Record_ID + ", Force=" + force); String error = null; MAcctSchema[] ass = MAcctSchema.getClientAcctSchema(Env.getCtx(), AD_Client_ID); error = Doc.postImmediate(ass, AD_Table_ID, Record_ID, force, null); return error; } // postImmediate /** * Cache Reset * @param tableName table name * @param Record_ID record id */ public static void cacheReset (String tableName, int Record_ID) { log.config("TableName=" + tableName + ", Record_ID=" + Record_ID); CacheMgt.get().reset(tableName, Record_ID); } // cacheReset /** * Validate permissions to access Info queries on the view menu * @author kstan_79 * @return true if access is allowed */ public static boolean canAccessInfo(String infoWindowName) { boolean result=false; int roleid= Env.getAD_Role_ID(Env.getCtx()); String sqlRolePermission="Select COUNT(AD_ROLE_ID) AS ROWCOUNT FROM AD_ROLE WHERE AD_ROLE_ID=" + roleid + " AND ALLOW_INFO_" + infoWindowName + "='Y'"; log.config(sqlRolePermission); PreparedStatement prolestmt = null; ResultSet rs = null; try { prolestmt = DB.prepareStatement (sqlRolePermission, null); rs = prolestmt.executeQuery (); rs.next(); if (rs.getInt("ROWCOUNT")>0) { result=true; } else { return false; } } catch (Exception e) { log.log(Level.SEVERE, "(1)", e); } finally { DB.close(rs, prolestmt); } return result; } // canAccessInfo public static void actionRefresh(Lookup lookup, Object value, boolean mandatory) { if (lookup == null) return; lookup.refresh(); if (lookup.isValidated()) lookup.fillComboBox(mandatory, false, false, false); else lookup.fillComboBox(mandatory, true, false, false); } /** * * @param lookup * @param value */ public static void actionZoom(Lookup lookup, Object value) { if (lookup == null) return; // MQuery zoomQuery = lookup.getZoomQuery(); // If not already exist or exact value if (zoomQuery == null || value != null) { zoomQuery = new MQuery(); // ColumnName might be changed in MTab.validateQuery String column = lookup.getColumnName(); //strip off table name, fully qualify name doesn't work when zoom into detail tab if (column.indexOf(".") > 0) { int p = column.indexOf("."); String tableName = column.substring(0, p); column = column.substring(column.indexOf(".")+1); zoomQuery.setZoomTableName(tableName); zoomQuery.setZoomColumnName(column); } else { zoomQuery.setZoomColumnName(column); //remove _ID to get table name zoomQuery.setZoomTableName(column.substring(0, column.length() - 3)); } zoomQuery.setZoomValue(value); zoomQuery.addRestriction(column, MQuery.EQUAL, value); zoomQuery.setRecordCount(1); // guess } int windowId = lookup.getZoom(zoomQuery); zoom(windowId, zoomQuery); } /** * Zoom to a window with the provided window id and filters according to the * query * @param AD_Window_ID Window on which to zoom * @param query Filter to be applied on the records. */ public static void zoom(int AD_Window_ID, MQuery query) { SessionManager.getAppDesktop().showZoomWindow(AD_Window_ID, query); } public static void showWindow(Window win) { SessionManager.getAppDesktop().showWindow(win); } /** * Zoom * @param query query */ public static void zoom (MQuery query) { if (query == null || query.getTableName() == null || query.getTableName().length() == 0) return; String TableName = query.getTableName(); int AD_Window_ID = 0; int PO_Window_ID = 0; String sql = "SELECT AD_Window_ID, PO_Window_ID FROM AD_Table WHERE TableName=?"; try { PreparedStatement pstmt = DB.prepareStatement(sql, null); pstmt.setString(1, TableName); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { AD_Window_ID = rs.getInt(1); PO_Window_ID = rs.getInt(2); } rs.close(); pstmt.close(); } catch (SQLException e) { log.log(Level.SEVERE, sql, e); } // Nothing to Zoom to if (AD_Window_ID == 0) return; // PO Zoom ? boolean isSOTrx = true; if (PO_Window_ID != 0) { isSOTrx = DB.isSOTrx(TableName, query.getWhereClause(false)); if (!isSOTrx) AD_Window_ID = PO_Window_ID; } log.config(query + " (IsSOTrx=" + isSOTrx + ")"); zoom(AD_Window_ID, query); } /** * Get ImageIcon. * * @param fileNameInImageDir full file name in imgaes folder (e.g. Bean16.png) * @return image */ public static URI getImage(String fileNameInImageDir) { URI uri = null; try { uri = new URI("/images/" + fileNameInImageDir); } catch (URISyntaxException exception) { log.log(Level.SEVERE, "Not found: " + fileNameInImageDir); return null; } return uri; } // getImageIcon /** * * @return boolean */ public static boolean isFirefox2() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); if (n instanceof ServletRequest) { String userAgent = Servlets.getUserAgent((ServletRequest) n); return userAgent.indexOf("Firefox/2") >= 0; } else { return false; } } /** * @return boolean */ public static boolean isBrowserSupported() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); boolean supported = false; if (n instanceof ServletRequest) { String userAgent = Servlets.getUserAgent((ServletRequest) n); if (userAgent.indexOf("Firefox") >= 0) { supported = true; } else if (userAgent.indexOf("AppleWebKit") >= 0) { if (userAgent.indexOf("Chrome") >= 0 || userAgent.indexOf("Safari") >= 0) { supported = true; } } } return supported; } /** * @return true if user agent is internet explorer */ public static boolean isInternetExplorer() { Execution execution = Executions.getCurrent(); if (execution == null) return false; Object n = execution.getNativeRequest(); if (n instanceof ServletRequest) { String userAgent = Servlets.getUserAgent((ServletRequest) n); if (userAgent.indexOf("MSIE ") >= 0) { return true; } } return false; } /** * * @param parent * @param child * @return boolean */ public static boolean contains(Component parent, Component child) { if (child == parent) return true; Component c = child.getParent(); while (c != null) { if (c == parent) return true; c = c.getParent(); } return false; } /** * * @param pdfList * @param outFile * @throws IOException * @throws DocumentException * @throws FileNotFoundException */ public static void mergePdf(List<File> pdfList, File outFile) throws IOException, DocumentException, FileNotFoundException { Document document = null; PdfWriter copy = null; for (File f : pdfList) { PdfReader reader = new PdfReader(f.getAbsolutePath()); if (document == null) { document = new Document(reader.getPageSizeWithRotation(1)); copy = PdfWriter.getInstance(document, new FileOutputStream(outFile)); document.open(); } int pages = reader.getNumberOfPages(); PdfContentByte cb = copy.getDirectContent(); for (int i = 1; i <= pages; i++) { document.newPage(); PdfImportedPage page = copy.getImportedPage(reader, i); cb.addTemplate(page, 0, 0); } } document.close(); } /** * Get window title * @param ctx context * @param WindowNo window * @return Header String */ public static String getWindowHeader(Properties ctx, int WindowNo) { StringBuffer sb = new StringBuffer(); if (WindowNo > 0){ sb.append(Env.getContext(ctx, WindowNo, "WindowName", false)).append(" "); final String documentNo = Env.getContext(ctx, WindowNo, "DocumentNo", false); final String value = Env.getContext(ctx, WindowNo, "Value", false); final String name = Env.getContext(ctx, WindowNo, "Name", false); if(!"".equals(documentNo)) { sb.append(documentNo).append(" "); } if(!"".equals(value)) { sb.append(value).append(" "); } if(!"".equals(name)) { sb.append(name).append(" "); } } return sb.toString(); } // getHeader /** * @param ctx * @return Language */ public static Language getLanguage(Properties ctx) { Locale locale = getLocale(ctx); Language language = Env.getLanguage(ctx); if (!language.getLocale().equals(locale)) { Language tmp = Language.getLanguage(locale.toString()); String adLanguage = language.getAD_Language(); language = new Language(tmp.getName(), adLanguage, tmp.getLocale(), tmp.isDecimalPoint(), tmp.getDateFormat().toPattern(), tmp.getMediaSize()); } return language; } /** * @param ctx * @return Locale */ public static Locale getLocale(Properties ctx) { String value = Env.getContext(ctx, AEnv.LOCALE); Locale locale = null; if (value != null && value.length() > 0) { String[] components = value.split("\\_"); String language = components.length > 0 ? components[0] : ""; String country = components.length > 1 ? components[1] : ""; locale = new Locale(language, country); } else { locale = Env.getLanguage(ctx).getLocale(); } return locale; } /** * Get title for dialog window * @param ctx * @param windowNo * @return dialog header */ public static String getDialogHeader(Properties ctx, int windowNo) { StringBuffer sb = new StringBuffer(); if (windowNo > 0){ sb.append(Env.getContext(ctx, windowNo, "WindowName", false)).append(" "); final String documentNo = Env.getContext(ctx, windowNo, "DocumentNo", false); final String value = Env.getContext(ctx, windowNo, "Value", false); final String name = Env.getContext(ctx, windowNo, "Name", false); if(!"".equals(documentNo)) { sb.append(documentNo).append(" "); } if(!"".equals(value)) { sb.append(value).append(" "); } if(!"".equals(name)) { sb.append(name).append(" "); } } String header = sb.toString().trim(); if (header.length() == 0) header = ThemeManager.getBrowserTitle(); return header; } } // AEnv