From 633c2e240f7fc347149c1f77ef1a4f167bd4e4d3 Mon Sep 17 00:00:00 2001 From: hengsin Date: Sat, 23 Oct 2021 21:11:49 +0800 Subject: [PATCH] IDEMPIERE-5012 org.idempiere.ui.zk.annotation.Form annotation (#944) --- org.adempiere.base/META-INF/MANIFEST.MF | 1 + org.adempiere.ui.zk/META-INF/MANIFEST.MF | 1 + .../OSGI-INF/defaultformfactory.xml | 1 + ...ui.factory.DefaultScanBasedFormFactory.xml | 8 + .../webui/apps/form/AddAuthorizationForm.java | 1 + .../apps/form/CompareCtxHelpSuggestion.java | 1 + .../apps/form/CompareFieldSuggestion.java | 1 + .../webui/apps/form/MFARegisterForm.java | 1 + .../webui/apps/form/WAllocation.java | 1 + .../webui/apps/form/WArchiveViewer.java | 2 +- .../webui/apps/form/WAttributeGrid.java | 1 + .../adempiere/webui/apps/form/WBOMDrop.java | 1 + .../adempiere/webui/apps/form/WCharge.java | 1 + .../webui/apps/form/WCreateFromForm.java | 1 + .../webui/apps/form/WFactReconcile.java | 1 + .../webui/apps/form/WFileImport.java | 1 + .../adempiere/webui/apps/form/WGenForm.java | 1 + .../adempiere/webui/apps/form/WInOutGen.java | 1 + .../webui/apps/form/WInvoiceGen.java | 1 + .../org/adempiere/webui/apps/form/WMatch.java | 1 + .../org/adempiere/webui/apps/form/WMerge.java | 1 + .../adempiere/webui/apps/form/WPayPrint.java | 1 + .../adempiere/webui/apps/form/WPaySelect.java | 1 + .../webui/apps/form/WPluginManager.java | 1 + .../webui/apps/form/WProcessParameter.java | 1 + .../webui/apps/form/WReportCustomization.java | 1 + .../webui/apps/form/WResetPassword.java | 1 + .../webui/apps/form/WSQLProcess.java | 1 + .../webui/apps/form/WSetupWizard.java | 1 + .../apps/form/WStatementCreateFromBatch.java | 1 + .../adempiere/webui/apps/form/WTabEditor.java | 1 + .../adempiere/webui/apps/form/WTreeBOM.java | 1 + .../webui/apps/form/WTreeMaintenance.java | 1 + .../webui/apps/form/WTrxMaterial.java | 1 + .../adempiere/webui/apps/graph/WViewPI.java | 1 + .../org/adempiere/webui/apps/wf/WFEditor.java | 1 + .../adempiere/webui/apps/wf/WWFActivity.java | 1 + .../factory/DefaultScanBasedFormFactory.java | 46 +++++ .../webui/factory/IMappedFormFactory.java | 8 + .../webui/factory/MappedFormFactory.java | 82 +++++++++ .../webui/factory/ScanBasedFormFactory.java | 162 ++++++++++++++++++ .../org/adempiere/webui/panel/CustomForm.java | 1 + .../webui/panel/WProcessParameterForm.java | 1 + .../adempiere/webui/panel/WTabEditorForm.java | 1 + .../org/idempiere/ui/zk/annotation/Form.java | 47 +++++ .../org/idempiere/test/model/FormTest.java | 76 ++++++++ 46 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 org.adempiere.ui.zk/OSGI-INF/org.adempiere.webui.factory.DefaultScanBasedFormFactory.xml create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultScanBasedFormFactory.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/ScanBasedFormFactory.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/annotation/Form.java create mode 100644 org.idempiere.test/src/org/idempiere/test/model/FormTest.java diff --git a/org.adempiere.base/META-INF/MANIFEST.MF b/org.adempiere.base/META-INF/MANIFEST.MF index ae26774fd0..e4491dee0b 100644 --- a/org.adempiere.base/META-INF/MANIFEST.MF +++ b/org.adempiere.base/META-INF/MANIFEST.MF @@ -19,6 +19,7 @@ Export-Package: bsh, bsh.servlet, bsh.util, com.akunagroup.uk.postcode, + io.github.classgraph, it.sauronsoftware.cron4j, org.adempiere.apps.graph, org.adempiere.base, diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 0af84aea1b..fc7eda5454 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -65,6 +65,7 @@ Import-Package: com.google.common.annotations;version="30.1.1", org.jfree.util, org.osgi.framework;version="1.7.0", org.osgi.framework.wiring;version="1.2.0", + org.osgi.service.component;version="1.4.0", org.osgi.service.component.annotations;version="1.3.0", org.osgi.service.event;version="1.3.0", org.osgi.util.tracker;version="1.5.0", diff --git a/org.adempiere.ui.zk/OSGI-INF/defaultformfactory.xml b/org.adempiere.ui.zk/OSGI-INF/defaultformfactory.xml index 115b169bd0..c1d6d91485 100644 --- a/org.adempiere.ui.zk/OSGI-INF/defaultformfactory.xml +++ b/org.adempiere.ui.zk/OSGI-INF/defaultformfactory.xml @@ -5,4 +5,5 @@ + diff --git a/org.adempiere.ui.zk/OSGI-INF/org.adempiere.webui.factory.DefaultScanBasedFormFactory.xml b/org.adempiere.ui.zk/OSGI-INF/org.adempiere.webui.factory.DefaultScanBasedFormFactory.xml new file mode 100644 index 0000000000..7d16c590d6 --- /dev/null +++ b/org.adempiere.ui.zk/OSGI-INF/org.adempiere.webui.factory.DefaultScanBasedFormFactory.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/AddAuthorizationForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/AddAuthorizationForm.java index 14597c5819..1bcf956de5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/AddAuthorizationForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/AddAuthorizationForm.java @@ -53,6 +53,7 @@ import org.zkoss.zul.Timer; * IDEMPIERE-3101 * @author Carlos Ruiz - globalqss */ +@org.idempiere.ui.zk.annotation.Form public class AddAuthorizationForm extends ADForm { /** * diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareCtxHelpSuggestion.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareCtxHelpSuggestion.java index dbc49418ab..89724751e3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareCtxHelpSuggestion.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareCtxHelpSuggestion.java @@ -40,6 +40,7 @@ import org.zkoss.zul.Vlayout; * @author hengsin * */ +@org.idempiere.ui.zk.annotation.Form public class CompareCtxHelpSuggestion extends ADForm { private static final String NEW_VALUE = "newValue"; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareFieldSuggestion.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareFieldSuggestion.java index 062a876a36..8dcd7d4b9e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareFieldSuggestion.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/CompareFieldSuggestion.java @@ -36,6 +36,7 @@ import org.zkoss.zul.Vlayout; * @author hengsin * */ +@org.idempiere.ui.zk.annotation.Form public class CompareFieldSuggestion extends ADForm { private static final String NEW_VALUE = "newValue"; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/MFARegisterForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/MFARegisterForm.java index b6997c3aa1..289c970f89 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/MFARegisterForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/MFARegisterForm.java @@ -57,6 +57,7 @@ import org.zkoss.zul.Space; * IDEMPIERE-4782 * @author Carlos Ruiz - globalqss - BX Service */ +@org.idempiere.ui.zk.annotation.Form public class MFARegisterForm extends ADForm { /** * diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java index 5180776b4e..3600b53487 100755 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java @@ -85,6 +85,7 @@ import static org.adempiere.webui.ClientInfo.*; * * Contributor : Fabian Aguilar - OFBConsulting - Multiallocation */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VAllocation") public class WAllocation extends Allocation implements IFormController, EventListener, WTableModelListener, ValueChangeListener { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java index ac975ee1fe..4ee0b1cdc6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java @@ -99,7 +99,7 @@ import org.zkoss.zul.impl.XulElement; * @author Niraj Sohun * @date September 28, 2007 */ - +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.ArchiveViewer") public class WArchiveViewer extends Archive implements IFormController, EventListener { private static final String ONCLOSE_TIMESTAMP_ATTR = "onclose.timestamp"; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAttributeGrid.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAttributeGrid.java index 0a38be2da2..6501848e7f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAttributeGrid.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAttributeGrid.java @@ -65,6 +65,7 @@ import org.zkoss.zul.Vbox; * @author Jorg Janke * @version $Id: VAttributeGrid.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VAttributeGrid") public class WAttributeGrid extends ADForm implements EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java index da0334479a..3725043d58 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WBOMDrop.java @@ -85,6 +85,7 @@ import org.zkoss.zul.Vlayout; +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VBOMDrop") public class WBOMDrop extends ADForm implements EventListener, ValueChangeListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java index 66037c5398..7ef43117f9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java @@ -67,6 +67,7 @@ import org.zkoss.zul.Separator; * @author Andrew Kimball * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VCharge") public class WCharge extends Charge implements IFormController, EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromForm.java index 95d4603f9f..d0612839a5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromForm.java @@ -49,6 +49,7 @@ import org.zkoss.zul.South; * @author Elaine * */ +@org.idempiere.ui.zk.annotation.Form public class WCreateFromForm extends ADForm implements EventListener, WTableModelListener, DialogEvents { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java index 15b674c408..89c5717c08 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java @@ -59,6 +59,7 @@ import org.zkoss.zul.Center; import org.zkoss.zul.North; import org.zkoss.zul.South; +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VFactReconcile") public class WFactReconcile extends FactReconcile implements IFormController, EventListener, WTableModelListener, ValueChangeListener{ diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java index f5775f64a5..14d589218f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFileImport.java @@ -75,6 +75,7 @@ import org.zkoss.zul.Vbox; * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VFileImport") public class WFileImport extends ADForm implements EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java index fe4c132df8..ff68cea6db 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java @@ -80,6 +80,7 @@ import org.zkoss.zul.South; * Generate custom form window * */ +@org.idempiere.ui.zk.annotation.Form public class WGenForm extends ADForm implements EventListener, WTableModelListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java index 7d75a27bf1..51e2903bcc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java @@ -52,6 +52,7 @@ import org.zkoss.zul.North; * Generate Shipment (manual) view class * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VInOutGen") public class WInOutGen extends InOutGen implements IFormController, EventListener, ValueChangeListener { private WGenForm form; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java index f4149b5deb..fc58b9411c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java @@ -52,6 +52,7 @@ import org.zkoss.zul.North; * Generate Invoice (manual) view class * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VInvoiceGen") public class WInvoiceGen extends InvoiceGen implements IFormController, EventListener, ValueChangeListener { private WGenForm form; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java index 219f413fce..6abbd042b1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java @@ -78,6 +78,7 @@ import org.zkoss.zul.Vlayout; * @author Jorg Janke * @version $Id: VMatch.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VMatch") public class WMatch extends Match implements IFormController, EventListener, WTableModelListener { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java index 31c2e02ed9..efb8f94425 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMerge.java @@ -55,6 +55,7 @@ import org.zkoss.zul.South; * @author Jorg Janke * @version $Id: VMerge.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VMerge") public class WMerge extends Merge implements IFormController, EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java index af89036da2..99dfcfd13f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java @@ -86,6 +86,7 @@ import com.lowagie.text.pdf.PdfReader; * Carlos Ruiz - GlobalQSS - FR 3132033 - Make payment export class configurable per bank * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VPayPrint") public class WPayPrint extends PayPrint implements IFormController, EventListener, ValueChangeListener { private CustomForm form = new CustomForm(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java index 5d637567fa..0d1fba4617 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java @@ -90,6 +90,7 @@ import org.zkoss.zul.Space; * @author Jorg Janke * @version $Id: VPaySelect.java,v 1.3 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VPaySelect") public class WPaySelect extends PaySelect implements IFormController, EventListener, WTableModelListener, IProcessUI, ValueChangeListener { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPluginManager.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPluginManager.java index 070f6621ef..358a19c479 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPluginManager.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPluginManager.java @@ -64,6 +64,7 @@ import org.zkoss.zul.Vbox; * @author Carlos Ruiz - globalqss - bxservice * */ +@org.idempiere.ui.zk.annotation.Form public class WPluginManager extends ADForm implements EventListener { /** * diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WProcessParameter.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WProcessParameter.java index f7370feb50..744f27675d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WProcessParameter.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WProcessParameter.java @@ -30,6 +30,7 @@ import org.compiere.util.Util; * @author hengsin * */ +@org.idempiere.ui.zk.annotation.Form public class WProcessParameter implements IFormController { private WProcessParameterForm parameterForm = null; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java index 70994cec63..a7a33c9577 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java @@ -74,6 +74,7 @@ import org.zkoss.zul.Separator; import org.zkoss.zul.Vbox; +@org.idempiere.ui.zk.annotation.Form public class WReportCustomization implements IFormController,EventListener { private CustomForm form = new CustomForm(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java index 24113e8c9f..233749fc3a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WResetPassword.java @@ -61,6 +61,7 @@ import org.zkoss.zul.South; * @author Elaine * @date September 18, 2012 */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VResetPassword") public class WResetPassword implements IFormController, EventListener, ValueChangeListener { private static final CLogger log = CLogger.getCLogger(WResetPassword.class); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java index 0e0380dac1..1cc574325f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSQLProcess.java @@ -55,6 +55,7 @@ import org.zkoss.zul.Center; * @author Andrew Kimball * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VSQLProcess") public class WSQLProcess extends ADForm implements EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSetupWizard.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSetupWizard.java index 8cd81d8076..27db801f43 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSetupWizard.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WSetupWizard.java @@ -76,6 +76,7 @@ import org.zkoss.zul.Vbox; * @author Carlos Ruiz * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VSetupWizard") public class WSetupWizard extends SetupWizard implements IFormController, EventListener { private CustomForm form = null; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WStatementCreateFromBatch.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WStatementCreateFromBatch.java index 80e46cd682..21b128c333 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WStatementCreateFromBatch.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WStatementCreateFromBatch.java @@ -62,6 +62,7 @@ import org.zkoss.zul.Hbox; * @author Elaine * */ +@org.idempiere.ui.zk.annotation.Form public class WStatementCreateFromBatch extends StatementCreateFromBatch implements IFormController, EventListener { private WCreateFromForm form; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTabEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTabEditor.java index 041dd95c33..737e9fd875 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTabEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTabEditor.java @@ -90,6 +90,7 @@ import org.zkoss.zul.West; * @author Carlos Ruiz * */ +@org.idempiere.ui.zk.annotation.Form public class WTabEditor extends TabEditor implements IFormController, EventListener, ValueChangeListener { // TODO: create messages Property, VisibleFields, NonVisibleField diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java index 5193fcaee9..ec80a36f13 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java @@ -70,6 +70,7 @@ import org.zkoss.zul.Treecols; import org.zkoss.zul.Treeitem; import org.zkoss.zul.West; +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VTreeBOM") public class WTreeBOM extends TreeBOM implements IFormController, EventListener { private int m_WindowNo = 0; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java index 0b067506ce..07955dd2a3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java @@ -68,6 +68,7 @@ import org.zkoss.zul.Treeitem; * @author Jorg Janke (modify: Sergio Oropeza sergioropeza@gmail.com, soropeza@dcsla.com 06/03/2014) * @version $Id: VTreeMaintenance.java,v 1.3 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VTreeMaintenance") public class WTreeMaintenance extends TreeMaintenance implements IFormController, EventListener { private CustomForm form = new CustomForm(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java index cd89b6ded0..5fa7a07a12 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java @@ -63,6 +63,7 @@ import org.zkoss.zul.South; * @author Jorg Janke * @version $Id: VTrxMaterial.java,v 1.3 2006/07/30 00:51:28 jjanke Exp $ */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.form.VTrxMaterial") public class WTrxMaterial extends TrxMaterial implements IFormController, EventListener, ValueChangeListener { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WViewPI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WViewPI.java index 465ba35395..e9c2592e96 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WViewPI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WViewPI.java @@ -3,6 +3,7 @@ package org.adempiere.webui.apps.graph; import org.adempiere.webui.panel.ADForm; import org.compiere.model.MGoal; +@org.idempiere.ui.zk.annotation.Form(name = "org.adempiere.apps.graph.ViewPI") public class WViewPI extends ADForm { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java index ec52412bb6..aefe0bc74d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WFEditor.java @@ -68,6 +68,7 @@ import org.zkoss.zul.Vbox; * @author Low Heng Sin * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.wf.WFPanel") public class WFEditor extends ADForm { /** * diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WWFActivity.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WWFActivity.java index ac13b286ea..f63090c565 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WWFActivity.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/wf/WWFActivity.java @@ -76,6 +76,7 @@ import org.zkoss.zul.Html; * @author hengsin * */ +@org.idempiere.ui.zk.annotation.Form(name = "org.compiere.apps.wf.WFActivity") public class WWFActivity extends ADForm implements EventListener { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultScanBasedFormFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultScanBasedFormFactory.java new file mode 100644 index 0000000000..0edbe99e98 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultScanBasedFormFactory.java @@ -0,0 +1,46 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.factory; + +import org.osgi.service.component.annotations.Component; + +/** + * + * @author hengsin + * + */ +@Component(immediate = true, service = IFormFactory.class, property = {"service.ranking:Integer=0"}) +public final class DefaultScanBasedFormFactory extends ScanBasedFormFactory { + + public DefaultScanBasedFormFactory() { + } + + @Override + protected String[] getPackages() { + return new String[] {"org.adempiere.webui.apps.form", "org.adempiere.webui.apps.graph", "org.adempiere.webui.apps.wf", + "org.adempiere.webui.panel"}; + } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IMappedFormFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IMappedFormFactory.java index b7a4f508f8..e4ef40f1d6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IMappedFormFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/IMappedFormFactory.java @@ -26,6 +26,8 @@ package org.adempiere.webui.factory; import org.adempiere.base.IMappedByNameFactory; import org.adempiere.webui.panel.ADForm; +import org.idempiere.ui.zk.annotation.Form; +import org.osgi.framework.BundleContext; /** * @@ -33,4 +35,10 @@ import org.adempiere.webui.panel.ADForm; * */ public interface IMappedFormFactory extends IMappedByNameFactory { + /** + * Scan packages for class with {@link Form} annotation and add mapping for it + * @param context + * @param packages + */ + public void scan(BundleContext context, String... packages); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/MappedFormFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/MappedFormFactory.java index 141be68b11..c79a9020bd 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/MappedFormFactory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/MappedFormFactory.java @@ -25,6 +25,11 @@ package org.adempiere.webui.factory; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.function.Supplier; +import java.util.logging.Level; + /** * * @author matheus.marcelino @@ -32,14 +37,26 @@ package org.adempiere.webui.factory; */ import org.adempiere.base.MappedByNameFactory; import org.adempiere.webui.panel.ADForm; +import org.adempiere.webui.panel.IFormController; +import org.compiere.util.CLogger; +import org.idempiere.ui.zk.annotation.Form; +import org.osgi.framework.BundleContext; +import org.osgi.framework.wiring.BundleWiring; import org.osgi.service.component.annotations.Component; +import io.github.classgraph.AnnotationInfo; +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.ScanResult; + @Component(name = "org.adempiere.webui.factory.MappedFormFactory", immediate = true, service = {IFormFactory.class, IMappedFormFactory.class}, property = {"service.ranking:Integer=1"}) public class MappedFormFactory extends MappedByNameFactory implements IFormFactory, IMappedFormFactory { + private final static CLogger s_log = CLogger.getCLogger(MappedFormFactory.class); + public MappedFormFactory() { } @@ -48,4 +65,69 @@ public class MappedFormFactory extends MappedByNameFactory implements IF return newInstance(formName); } + @Override + public void scan(BundleContext context, String... packages) { + ClassLoader classLoader = context.getBundle().adapt(BundleWiring.class).getClassLoader(); + ClassGraph graph = new ClassGraph() + .enableAnnotationInfo() + .overrideClassLoaders(classLoader) + .disableNestedJarScanning() + .disableModuleScanning() + .acceptPackagesNonRecursive(packages); + + try (ScanResult scanResult = graph.scan()) { + for (ClassInfo classInfo : scanResult.getClassesWithAnnotation(Form.class)) { + if (classInfo.isAbstract()) + continue; + String className = classInfo.getName(); + try { + Class clazz = (Class) classInfo.loadClass(); + Constructor constructor = clazz.getConstructor(); + FormSupplier supplier = new FormSupplier(constructor); + AnnotationInfo annotationInfo = classInfo.getAnnotationInfo(Form.class); + String alternateName = null; + if (annotationInfo != null) + alternateName = (String) annotationInfo.getParameterValues().getValue("name"); + + addMapping(className, supplier); + if (alternateName != null) + addMapping(alternateName, supplier); + } catch (Exception e) { + if (s_log.isLoggable(Level.INFO)) + s_log.log(Level.INFO, e.getMessage(), e); + } + } + } + + } + + private static final class FormSupplier implements Supplier { + + private Constructor constructor; + + private FormSupplier(Constructor constructor) { + this.constructor = constructor; + } + + @Override + public ADForm get() { + ADForm form = null; + try { + Object formObject = constructor.newInstance(); + if (formObject != null) { + if (formObject instanceof ADForm) { + form = (ADForm)formObject; + } else if (formObject instanceof IFormController) { + IFormController controller = (IFormController) formObject; + form = controller.getForm(); + form.setICustomForm(controller); + } + } + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + s_log.log(Level.WARNING, e.getMessage(), e); + } + return form; + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/ScanBasedFormFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/ScanBasedFormFactory.java new file mode 100644 index 0000000000..3d360b57cc --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/ScanBasedFormFactory.java @@ -0,0 +1,162 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.factory; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; + +import org.adempiere.webui.panel.ADForm; +import org.adempiere.webui.panel.IFormController; +import org.compiere.util.CLogger; +import org.compiere.util.Util; +import org.idempiere.ui.zk.annotation.Form; +import org.osgi.framework.BundleContext; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; + +import io.github.classgraph.AnnotationInfo; +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ClassInfo; +import io.github.classgraph.ScanResult; + +/** + * Scan, discover and regiser classes with {@link Form} annotation. + * @author hengsin + * + */ +public abstract class ScanBasedFormFactory implements IFormFactory { + + private final Map classCache = new HashMap<>(); + + private final Map[]> constructorCache = new ConcurrentHashMap<>(); + + private BundleContext bundleContext = null; + + private static final CLogger s_log = CLogger.getCLogger(ScanBasedFormFactory.class); + + public ScanBasedFormFactory() { + } + + @Override + public ADForm newFormInstance(String formName) { + ADForm form = null; + String realClassName = classCache.get(formName); + if (realClassName != null) { + Constructor constructor = getConstructor(formName); + try { + Object formObject = constructor.newInstance(); + if (formObject != null) { + if (formObject instanceof ADForm) { + form = (ADForm)formObject; + } else if (formObject instanceof IFormController) { + IFormController controller = (IFormController) formObject; + form = controller.getForm(); + form.setICustomForm(controller); + } + } + } catch (Exception e) { + s_log.log(Level.WARNING, e.getMessage(), e); + } + if (form == null) + constructorCache.put(realClassName, new Constructor[0]); + } + return form; + } + + /** + * + * @param formName + * @return class default constructor + */ + public Constructor getConstructor(String formName) { + String className = classCache.get(formName); + Constructor[] constructors = null; + if (className != null) { + constructors = constructorCache.get(className); + if (constructors == null) { + ClassLoader classLoader = bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader(); + try { + Class clazz = classLoader.loadClass(className); + Constructor constructor = clazz.getDeclaredConstructor(); + if (constructor != null) { + constructors = new Constructor[] {constructor}; + } else { + constructors = new Constructor[0]; + } + constructorCache.put(className, constructors); + } catch (Exception e) { + s_log.log(Level.WARNING, e.getMessage(), e); + constructors = new Constructor[0]; + constructorCache.put(className, constructors); + } + } + } + if (constructors != null && constructors.length == 1) { + return constructors[0]; + } else { + return null; + } + } + + protected abstract String[] getPackages(); + + @Activate + public void activate(ComponentContext context) throws ClassNotFoundException { + long start = System.currentTimeMillis(); + bundleContext = context.getBundleContext(); + ClassLoader classLoader = bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader(); + + ClassGraph graph = new ClassGraph() + .enableAnnotationInfo() + .overrideClassLoaders(classLoader) + .disableNestedJarScanning() + .disableModuleScanning() + .acceptPackagesNonRecursive(getPackages()); + + try (ScanResult scanResult = graph.scan()) + { + + for (ClassInfo classInfo : scanResult.getClassesWithAnnotation(Form.class)) { + if (classInfo.isAbstract()) + continue; + String className = classInfo.getName(); + AnnotationInfo annotationInfo = classInfo.getAnnotationInfo(Form.class); + String alternateName = (String) annotationInfo.getParameterValues().getValue("name"); + + classCache.put(className, className); + if (!Util.isEmpty(alternateName, true)) + classCache.put(alternateName, className); + } + } + long end = System.currentTimeMillis(); + if (s_log.isLoggable(Level.INFO)) + s_log.info(this.getClass().getSimpleName() + " loaded "+classCache.size() +" classes in " + +((end-start)/1000f) + "s"); + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java index adaf628f10..c4bbbfab28 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java @@ -1,5 +1,6 @@ package org.adempiere.webui.panel; +@org.idempiere.ui.zk.annotation.Form public class CustomForm extends ADForm { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java index 8cea3ca4e8..e02314b13e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java @@ -42,6 +42,7 @@ import org.zkoss.zul.Hbox; import org.zkoss.zul.Html; import org.zkoss.zul.Vlayout; +@org.idempiere.ui.zk.annotation.Form public class WProcessParameterForm extends ADForm { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WTabEditorForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WTabEditorForm.java index 0c48b67585..f608433eef 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WTabEditorForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WTabEditorForm.java @@ -16,6 +16,7 @@ package org.adempiere.webui.panel; import org.adempiere.webui.apps.form.WTabEditor; +@org.idempiere.ui.zk.annotation.Form public class WTabEditorForm extends ADForm { /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/annotation/Form.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/annotation/Form.java new file mode 100644 index 0000000000..7e3a4080b0 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/annotation/Form.java @@ -0,0 +1,47 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.ui.zk.annotation; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(ElementType.TYPE) +/** + * Annotation for web ui form + * @author hengsin + * + */ +public @interface Form { + + /** + * Optional alternate name for form (in addition to class name) + * @return alternate name + */ + String name() default "String"; +} diff --git a/org.idempiere.test/src/org/idempiere/test/model/FormTest.java b/org.idempiere.test/src/org/idempiere/test/model/FormTest.java new file mode 100644 index 0000000000..eb6f21964c --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/model/FormTest.java @@ -0,0 +1,76 @@ +/*********************************************************************** + * 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: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.model; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.lang.reflect.Constructor; +import java.util.List; + +import org.adempiere.base.IServiceReferenceHolder; +import org.adempiere.base.Service; +import org.adempiere.webui.factory.DefaultScanBasedFormFactory; +import org.adempiere.webui.factory.IFormFactory; +import org.compiere.model.MForm; +import org.compiere.model.Query; +import org.compiere.util.Env; +import org.idempiere.test.AbstractTestCase; +import org.junit.jupiter.api.Test; + +/** + * + * @author hengsin + * + */ +public class FormTest extends AbstractTestCase { + + public FormTest() { + } + + @Test + public void testCoreFormMapping() { + DefaultScanBasedFormFactory formFactory = null; + List> factories = Service.locator().list(IFormFactory.class).getServiceReferences(); + if (factories != null) { + for(IServiceReferenceHolder factory : factories) { + IFormFactory service = factory.getService(); + if (service != null && service instanceof DefaultScanBasedFormFactory) { + formFactory = (DefaultScanBasedFormFactory) service; + break; + } + } + } + + assertNotNull(formFactory, "Failed to locate DefaultScanBasedFormFactory"); + + Query query = new Query(Env.getCtx(), MForm.Table_Name, "AD_Form_ID < 1000000 AND ClassName IS NOT NULL " + + " AND EXISTS (select 1 from ad_menu where isactive='Y' and ad_form_id=ad_form.ad_form_id)", getTrxName()); + List forms = query.setOnlyActiveRecords(true).list(); + for (MForm form : forms) { + Constructor constructor = formFactory.getConstructor(form.getClassname()); + assertNotNull(constructor, "Failed to find class for " + form.toString() + ", " + form.getClassname()); + } + } +}