From 410c9a11314d700692943f8cd3a8449f0f522378 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 12 Feb 2014 09:31:14 -0500 Subject: [PATCH] IDEMPIERE-1749 Add window event validator for AD_Window --- org.adempiere.ui.zk/META-INF/MANIFEST.MF | 2 + .../org/adempiere/webui/WebUIActivator.java | 4 + .../adempiere/webui/adwindow/ADWindow.java | 12 + .../webui/adwindow/ADWindowContent.java | 8 +- .../adwindow/AbstractADWindowContent.java | 246 ++++++++++++++++-- .../adwindow/validator/WindowValidator.java | 7 + .../validator/WindowValidatorEvent.java | 21 ++ .../validator/WindowValidatorEventType.java | 26 ++ .../validator/WindowValidatorManager.java | 140 ++++++++++ 9 files changed, 436 insertions(+), 30 deletions(-) create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidator.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEvent.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEventType.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorManager.java diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 68a249b77c..24437840a3 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -16,6 +16,7 @@ Import-Package: javax.activation;version="1.1.1", org.compiere.css, org.osgi.framework;version="1.5.0", org.osgi.service.event;version="1.3.0", + org.osgi.util.tracker;version="1.5.0", org.slf4j;version="1.6.1", org.slf4j.helpers;version="1.6.1", org.slf4j.spi;version="1.6.1" @@ -31,6 +32,7 @@ Export-Package: fi.jawsy.jawwa.zk.atmosphere, org.adempiere.webui.acct, org.adempiere.webui.action, org.adempiere.webui.adwindow, + org.adempiere.webui.adwindow.validator, org.adempiere.webui.apps, org.adempiere.webui.apps.form, org.adempiere.webui.apps.graph, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java index 4ec465ebf5..b4f64e0b57 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WebUIActivator.java @@ -13,6 +13,7 @@ *****************************************************************************/ package org.adempiere.webui; +import org.adempiere.webui.adwindow.validator.WindowValidatorManager; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -30,6 +31,8 @@ public class WebUIActivator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { bundleContext = context; + WindowValidatorManager validatorMgr = new WindowValidatorManager(); + validatorMgr.start(context); } /* (non-Javadoc) @@ -38,6 +41,7 @@ public class WebUIActivator implements BundleActivator { @Override public void stop(BundleContext context) throws Exception { bundleContext = null; + WindowValidatorManager.getInstance().stop(context); } public static BundleContext getBundleContext() { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java index 634d7e145b..16816d7249 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindow.java @@ -33,6 +33,7 @@ import org.compiere.model.MQuery; import org.compiere.model.MRole; import org.compiere.model.MToolBarButton; import org.compiere.model.MToolBarButtonRestrict; +import org.compiere.model.MWindow; import org.compiere.model.X_AD_ToolBarButton; import org.compiere.util.CCache; import org.compiere.util.Env; @@ -66,6 +67,7 @@ public class ADWindow extends AbstractUIPart private List windowToolbarRestrictList = null; private List windowToolbarAdvancedList = null; + private String adWindowUUID; /** * @@ -90,6 +92,7 @@ public class ADWindow extends AbstractUIPart this.ctx = ctx; this.adWindowId = adWindowId; + this.adWindowUUID = MWindow.get(ctx, adWindowId).getAD_Window_UU(); windowNo = SessionManager.getAppDesktop().registerWindow(this); this.query = query; try { @@ -103,6 +106,7 @@ public class ADWindow extends AbstractUIPart private void init() { windowContent = new ADWindowContent(ctx, windowNo, adWindowId); + windowContent.setADWindow(this); _title = windowContent.getTitle(); image = windowContent.getImage(); } @@ -222,6 +226,14 @@ public class ADWindow extends AbstractUIPart } return windowToolbarAdvancedList; } + + public int getAD_Window_ID() { + return adWindowId; + } + + public String getAD_Window_UU() { + return adWindowUUID; + } /** * diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java index 1780e33710..f4376f8a63 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java @@ -67,7 +67,7 @@ public class ADWindowContent extends AbstractADWindowContent private Div contentArea; - public ADWindowContent(Properties ctx, int windowNo, int adWindowId) + public ADWindowContent(Properties ctx, int windowNo, int adWindowId) { super(ctx, windowNo, adWindowId); } @@ -226,9 +226,9 @@ public class ADWindowContent extends AbstractADWindowContent * generated serial id */ private static final long serialVersionUID = 6104341168705201721L; - private ADWindowContent content; + private AbstractADWindowContent content; - protected ADWindowVlayout(ADWindowContent content) { + protected ADWindowVlayout(AbstractADWindowContent content) { super(); this.content = content; } @@ -240,5 +240,5 @@ public class ADWindowContent extends AbstractADWindowContent SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, content); } catch (Exception e){} } - } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index 8de6112b59..15f5df2531 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -38,6 +38,9 @@ import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.WArchive; import org.adempiere.webui.WRequest; import org.adempiere.webui.WZoomAcross; +import org.adempiere.webui.adwindow.validator.WindowValidatorEvent; +import org.adempiere.webui.adwindow.validator.WindowValidatorEventType; +import org.adempiere.webui.adwindow.validator.WindowValidatorManager; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.BusyDialogTemplate; import org.adempiere.webui.apps.HelpWindow; @@ -861,6 +864,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements private Div mask; + protected ADWindow adwindow; + /** * @see ToolbarListener#onLock() */ @@ -1716,14 +1721,38 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements SessionManager.getAppDesktop().showWindow(new HelpWindow(gridWindow), "center"); } - /** - * @see ToolbarListener#onNew() - */ + @Override public void onNew() + { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_NEW.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null); + } + } + }; + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onNewCallback(postCallback); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_NEW.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + private void onNewCallback(final Callback postCallback) { if (!adTabbox.getSelectedGridTab().isInsertRecord()) { logger.warning("Insert Record disabled for Tab"); + if (postCallback != null) + postCallback.onCallback(false); return; } @@ -1757,26 +1786,59 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { adTabbox.getSelectedTabpanel().getGridView().onEditCurrentRow(); } + if (postCallback != null) + postCallback.onCallback(true); } else { logger.severe("Could not create new record"); + if (postCallback != null) + postCallback.onCallback(false); } focusToActivePanel(); } + else + { + if (postCallback != null) + postCallback.onCallback(result); + } } }); } - // Elaine 2008/11/19 - /** - * @see ToolbarListener#onCopy() - */ + @Override public void onCopy() + { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_COPY.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null); + } + } + }; + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onCopyCallback(postCallback); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_COPY.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + // Elaine 2008/11/19 + private void onCopyCallback(Callback postCallback) { if (!adTabbox.getSelectedGridTab().isInsertRecord()) { logger.warning("Insert Record disabled for Tab"); + if (postCallback != null) + postCallback.onCallback(false); return; } @@ -1793,10 +1855,15 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements toolbar.enableIgnore(true); toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted()); toolbar.enableReport(true); + if (postCallback != null) + postCallback.onCallback(true); + } else { logger.severe("Could not create new record"); + if (postCallback != null) + postCallback.onCallback(false); } focusToActivePanel(); } @@ -1878,10 +1945,32 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements LayoutUtils.openEmbeddedWindow(toolbar, findWindow, "after_start"); } - /** - * @see ToolbarListener#onIgnore() - */ - public void onIgnore() + @Override + public void onIgnore() + { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_IGNORE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null); + } + } + }; + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onIgnoreCallback(postCallback); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_IGNORE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + private void onIgnoreCallback(Callback postCallback) { IADTabpanel dirtyTabpanel = adTabbox.getDirtyADTabpanel(); boolean newrecod = adTabbox.getSelectedGridTab().isNew(); @@ -1912,15 +2001,19 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements focusToActivePanel(); updateToolbar(); + + if (postCallback != null) + postCallback.onCallback(true); } /** * @see ToolbarListener#onSave() */ + @Override public void onSave() { final IADTabpanel dirtyTabpanel = adTabbox.getDirtyADTabpanel(); - onSave(true, false, new Callback() { + onSave(true, false, new Callback() { @Override public void onCallback(Boolean result) { @@ -1941,7 +2034,35 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements }); } - public void onSavePayment() + private void onSave(final boolean onSaveEvent, final boolean onNavigationEvent, final Callback callback) { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_SAVE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, callback); + } else { + callback.onCallback(result); + } + } + }; + + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onSaveCallback(onSaveEvent, onNavigationEvent, postCallback); + } else if (callback != null) { + callback.onCallback(result); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_SAVE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + public void onSavePayment() { onSave(false, false, new Callback() { @@ -1956,7 +2077,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements /** * @param onSaveEvent */ - private void onSave(final boolean onSaveEvent, final boolean onNavigationEvent, final Callback callback) + private void onSaveCallback(final boolean onSaveEvent, final boolean onNavigationEvent, final Callback callback) { final boolean wasChanged = toolbar.isSaveEnable(); IADTabpanel dirtyTabpanel = adTabbox.getDirtyADTabpanel(); @@ -2106,13 +2227,37 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements }); } - /** - * @see ToolbarListener#onDelete() - */ - public void onDelete() + @Override + public void onDelete() + { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_DELETE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null); + } + } + }; + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onDeleteCallback(postCallback); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_DELETE.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + private void onDeleteCallback(final Callback postCallback) { if (adTabbox.getSelectedGridTab().isReadOnly()) { + if (postCallback != null) + postCallback.onCallback(false); return; } @@ -2120,7 +2265,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements final int[] indices = adTabbox.getSelectedGridTab().getSelection(); if (indices.length > 0 && adTabbox.getSelectedTabpanel().isGridView()) { - onDeleteSelected(); + onDeleteSelected(postCallback); return; } @@ -2136,17 +2281,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements adTabbox.getSelectedTabpanel().dynamicDisplay(0); focusToActivePanel(); - MRecentItem.publishChangedEvent(Env.getAD_User_ID(ctx)); + MRecentItem.publishChangedEvent(Env.getAD_User_ID(ctx)); } + if (postCallback != null) + postCallback.onCallback(result); } }); } // Elaine 2008/12/01 - private void onDeleteSelected() + private void onDeleteSelected(final Callback postCallback) { if (adTabbox.getSelectedGridTab().isReadOnly() || !adTabbox.getSelectedTabpanel().isGridView()) { + if (postCallback != null) + postCallback.onCallback(false); return; } @@ -2176,18 +2325,43 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements adTabbox.getSelectedTabpanel().dynamicDisplay(0); statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Deleted")+": "+count, false); } + if (postCallback != null) + postCallback.onCallback(result); } }); } else { statusBar.setStatusLine(Msg.getMsg(Env.getCtx(), "Selected")+": 0", false); + if (postCallback != null) + postCallback.onCallback(false); } } // - /** - * @see ToolbarListener#onPrint() - */ - public void onPrint() { + @Override + public void onPrint() { + final Callback postCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.AFTER_PRINT.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, null); + } + } + }; + Callback preCallback = new Callback() { + @Override + public void onCallback(Boolean result) { + if (result) { + onPrintCallback(postCallback); + } + } + }; + + WindowValidatorEvent event = new WindowValidatorEvent(adwindow, WindowValidatorEventType.BEFORE_PRINT.getName()); + WindowValidatorManager.getInstance().fireWindowValidatorEvent(event, preCallback); + } + + private void onPrintCallback(final Callback postCallback) { //Get process defined for this tab final int AD_Process_ID = adTabbox.getSelectedGridTab().getAD_Process_ID(); //log.info("ID=" + AD_Process_ID); @@ -2207,15 +2381,27 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements int table_ID = adTabbox.getSelectedGridTab().getAD_Table_ID(); int record_ID = adTabbox.getSelectedGridTab().getRecord_ID(); - ProcessModalDialog dialog = new ProcessModalDialog(AbstractADWindowContent.this, getWindowNo(), AD_Process_ID,table_ID, record_ID, true); + final ProcessModalDialog dialog = new ProcessModalDialog(AbstractADWindowContent.this, getWindowNo(), AD_Process_ID,table_ID, record_ID, true); if (dialog.isValid()) { dialog.setWidth("500px"); dialog.setBorder("normal"); getComponent().getParent().appendChild(dialog); showBusyMask(dialog); LayoutUtils.openOverlappedWindow(getComponent(), dialog, "middle_center"); + if (postCallback != null) { + dialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + postCallback.onCallback(dialog.isCancel()); + } + }); + } dialog.focus(); + } else if (postCallback != null) { + postCallback.onCallback(result); } + } else if (postCallback != null) { + postCallback.onCallback(result); } } }; @@ -2924,6 +3110,14 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements return boolChanges; } + public void setADWindow(ADWindow adwindow) { + this.adwindow = adwindow; + } + + public ADWindow getADWindow() { + return adwindow; + } + private void clearTitleRelatedContext() { // IDEMPIERE-1328 // clear the values for the tab header diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidator.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidator.java new file mode 100644 index 0000000000..29862e49cc --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidator.java @@ -0,0 +1,7 @@ +package org.adempiere.webui.adwindow.validator; + +import org.adempiere.util.Callback; + +public interface WindowValidator { + public void onWindowEvent(WindowValidatorEvent event, Callback callback); +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEvent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEvent.java new file mode 100644 index 0000000000..50a6a10ba6 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEvent.java @@ -0,0 +1,21 @@ +package org.adempiere.webui.adwindow.validator; + +import org.adempiere.webui.adwindow.ADWindow; + +public class WindowValidatorEvent { + private ADWindow window; + private String name; + + public WindowValidatorEvent(ADWindow window, String name) { + this.window = window; + this.name = name; + } + + public ADWindow getWindow() { + return this.window; + } + + public String getName() { + return this.name; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEventType.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEventType.java new file mode 100644 index 0000000000..4b67aa2188 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorEventType.java @@ -0,0 +1,26 @@ +package org.adempiere.webui.adwindow.validator; + +public enum WindowValidatorEventType { + BEFORE_IGNORE("beforeIgnore"), + AFTER_IGNORE("afterIgnore"), + BEFORE_NEW("beforeNew"), + AFTER_NEW("afterNew"), + BEFORE_PRINT("beforePrint"), + AFTER_PRINT("afterPrint"), + BEFORE_DELETE("beforeDelete"), + AFTER_DELETE("afterDelete"), + BEFORE_SAVE("beforeSave"), + AFTER_SAVE("afterSave"), + BEFORE_COPY("beforeCopy"), + AFTER_COPY("afterCopy"); + + private String name; + + private WindowValidatorEventType(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorManager.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorManager.java new file mode 100644 index 0000000000..268683ef09 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/validator/WindowValidatorManager.java @@ -0,0 +1,140 @@ +package org.adempiere.webui.adwindow.validator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.adempiere.util.Callback; +import org.adempiere.webui.adwindow.ADWindow; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + +public class WindowValidatorManager implements BundleActivator, ServiceTrackerCustomizer { + + private static WindowValidatorManager instance = null; + + private BundleContext context; + private Map> validatorMap = new HashMap>(); + private List globalValidators = new ArrayList(); + + private ServiceTracker serviceTracker; + + @Override + public WindowValidator addingService( + ServiceReference reference) { + WindowValidator service = context.getService(reference); + String uuid = (String) reference.getProperty("AD_Window_UU"); + if (uuid == null || "*".equals(uuid)) + globalValidators.add(service); + + List list = validatorMap.get(uuid); + if (list == null) { + list = new ArrayList(); + validatorMap.put(uuid, list); + } + list.add(service); + + return service; + } + + @Override + public void modifiedService(ServiceReference reference, + WindowValidator service) { + } + + @Override + public void removedService(ServiceReference reference, + WindowValidator service) { + String uuid = (String) reference.getProperty("AD_Window_UU"); + if (uuid == null || "*".equals(uuid)) { + globalValidators.remove(service); + } else { + List list = validatorMap.get(uuid); + if (list != null) { + list.remove(service); + } + } + } + + @Override + public void start(BundleContext context) throws Exception { + this.context = context; + serviceTracker = new ServiceTracker(context, WindowValidator.class.getName(), this); + serviceTracker.open(); + + instance = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + serviceTracker.close(); + this.context = null; + instance = null; + } + + public static WindowValidatorManager getInstance() { + return instance; + } + + public void fireWindowValidatorEvent(WindowValidatorEvent event, Callback callback) { + ADWindow window = event.getWindow(); + String uuid = window.getAD_Window_UU(); + List list = validatorMap.get(uuid); + int listSize = list != null ? list.size() : 0; + WindowValidator[] validators = new WindowValidator[listSize+globalValidators.size()]; + int index = -1; + if (listSize > 0) { + for(WindowValidator validator : list) { + index++; + validators[index] = validator; + } + } + for(WindowValidator validator : globalValidators) { + index++; + validators[index] = validator; + } + ChainCallback chain = new ChainCallback(event, validators, callback); + chain.start(); + } + + private static class ChainCallback implements Callback { + + private Callback callback; + private WindowValidator[] validators; + private WindowValidatorEvent event; + private int index = -1; + + public ChainCallback(WindowValidatorEvent event, WindowValidator[] validators, Callback callback) { + this.event = event; + this.validators = validators; + this.callback = callback; + } + + public void start() { + index = 0; + if (index < validators.length) + validators[index].onWindowEvent(event, this); + else if (callback != null) + callback.onCallback(true); + } + + @Override + public void onCallback(Boolean result) { + if (result) { + if (index < validators.length-1) { + index++; + validators[index].onWindowEvent(event, this); + } else if (callback != null){ + callback.onCallback(result); + } + } else if (callback != null){ + callback.onCallback(result); + } + } + + } +}