/****************************************************************************** * 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.panel; import java.util.logging.Level; import org.adempiere.webui.component.Window; import org.adempiere.webui.exception.ApplicationException; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.ADClassNameMap; import org.compiere.model.MForm; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; /** * Adempiere Web UI custom form. * The form is abstract, so specific types of custom form must be implemented * * @author Andrew Kimball */ public abstract class ADForm extends Window implements EventListener { /** * */ private static final long serialVersionUID = -5183711788893823434L; /** The class' logging enabler */ protected static final CLogger logger; static { logger = CLogger.getCLogger(ADForm.class); } /** The unique identifier of the form type */ private int m_adFormId; /** The identifying number of the window in which the form is housed */ protected int m_WindowNo; private String m_name; private ProcessInfo m_pi; private IFormController m_customForm; /** * Constructor * * @param ctx the context into which the form is being placed * @param adFormId the Adempiere form identifier */ protected ADForm() { m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); this.setWidth("100%"); this.setHeight("95%"); this.setStyle("position:absolute"); this.setContentSclass("adform-content"); } public int getWindowNo() { return m_WindowNo; } protected int getAdFormId() { return m_adFormId; } /** * Initialise the form * * @param adFormId the Adempiere form identifier * @param name the name of the Adempiere form */ protected void init(int adFormId, String name) { if(adFormId <= 0) { throw new IllegalArgumentException("Form Id is invalid"); } m_adFormId = adFormId; //window title setTitle(name); m_name = name; initForm(); } abstract protected void initForm(); /** * @return form name */ public String getFormName() { return m_name; } /** * Convert the rich client class name for a form to its web UI equivalent * * @param originalName The full class path to convert * @return the converted class name */ private static String translateFormClassName(String originalName) { String zkName = null; /* * replacement string to translate class paths to the form * "org.adempiere.webui.apps.form.<classname>" */ final String zkPackage = "org.adempiere.webui."; /* * replacement string to translate custom form class name from * "V<name>" to "W<name>" */ final String zkPrefix = "W"; final String swingPrefix = "V"; String tail = null; //first, try replace package if (originalName.startsWith("org.compiere.")) { tail = originalName.substring("org.compiere.".length()); } else if(originalName.startsWith("org.adempiere.")) { tail = originalName.substring("org.adempiere.".length()); } if (tail != null) { zkName = zkPackage + tail; try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } //try replace package and add W prefix to class name if (zkName == null) { String packageName = zkPackage; int lastdot = tail.lastIndexOf("."); String className = null; if (lastdot >= 0) { if (lastdot > 0) packageName = packageName + tail.substring(0, lastdot+1); className = tail.substring(lastdot+1); } else { className = tail; } //try convert V* to W* if (className.startsWith(swingPrefix)) { zkName = packageName + zkPrefix + className.substring(1); try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } } //try append W prefix to original class name if (zkName == null) { zkName = packageName + zkPrefix + className; try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } } } } /* * not found, try changing only the class name */ if (zkName == null) { int lastdot = originalName.lastIndexOf("."); String packageName = originalName.substring(0, lastdot); String className = originalName.substring(lastdot+1); //try convert V* to W* if (className.startsWith(swingPrefix)) { String zkClassName = zkPrefix + className.substring(1); zkName = packageName + "." + zkClassName; try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } } //try just append W to the original class name if (zkName == null) { String zkClassName = zkPrefix + className; zkName = packageName + "." + zkClassName; try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } } if (zkName == null) { //finally try whether same name is used for zk zkName = originalName; try { Class<?> clazz = ADForm.class.getClassLoader().loadClass(zkName); if (!isZkFormClass(clazz)) { zkName = null; } } catch (ClassNotFoundException e) { zkName = null; } } } return zkName; } private static boolean isZkFormClass(Class<?> clazz) { return IFormController.class.isAssignableFrom(clazz) || Component.class.isAssignableFrom(clazz); } /** * Create a new form corresponding to the specified identifier * * @param adFormID The unique identifier for the form type * @return The created form */ public static ADForm openForm (int adFormID) { Object obj; ADForm form; String webClassName = ""; MForm mform = new MForm(Env.getCtx(), adFormID, null); String richClassName = mform.getClassname(); String name = mform.get_Translation(MForm.COLUMNNAME_Name); if (mform.get_ID() == 0 || richClassName == null) { throw new ApplicationException("There is no form associated with the specified selection"); } else { logger.info("AD_Form_ID=" + adFormID + " - Class=" + richClassName); //static lookup webClassName = ADClassNameMap.get(richClassName); //fallback to dynamic translation if (webClassName == null || webClassName.trim().length() == 0) { webClassName = translateFormClassName(richClassName); } if (webClassName == null) { throw new ApplicationException("Web UI form not implemented for the swing form " + richClassName); } try { // Create instance w/o parameters obj = ADForm.class.getClassLoader().loadClass(webClassName).newInstance(); } catch (Exception e) { throw new ApplicationException("The selected web user interface custom form '" + webClassName + "' is not accessible.", e); } try { if (obj instanceof ADForm) { form = (ADForm)obj; form.init(adFormID, name); return form; } else if (obj instanceof IFormController) { IFormController customForm = (IFormController)obj; Object o = customForm.getForm(); if(o instanceof ADForm) { form = (ADForm)o; form.setICustomForm(customForm); form.init(adFormID, name); return form; } else throw new ApplicationException("The web user interface custom form '" + webClassName + "' cannot be displayed in the web user interface."); } else { throw new ApplicationException("The web user interface custom form '" + webClassName + "' cannot be displayed in the web user interface."); } } catch (Exception ex) { logger.log(Level.SEVERE, "Class=" + webClassName + ", AD_Form_ID=" + adFormID, ex); throw new ApplicationException("The web user interface custom form '" + webClassName + "' failed to initialise:" + ex); } } } // openForm /** * */ public void onEvent(Event arg0) throws Exception { } /** * @param pi */ public void setProcessInfo(ProcessInfo pi) { m_pi = pi; } /** * @return ProcessInfo */ public ProcessInfo getProcessInfo() { return m_pi; } public void setICustomForm(IFormController customForm) { m_customForm = customForm; } public IFormController getICustomForm() { return m_customForm; } }