diff --git a/event.test/.classpath b/event.test/.classpath
new file mode 100644
index 0000000000..ad32c83a78
--- /dev/null
+++ b/event.test/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/event.test/.project b/event.test/.project
new file mode 100644
index 0000000000..161f7edb9f
--- /dev/null
+++ b/event.test/.project
@@ -0,0 +1,33 @@
+
+
+ event.test
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.pde.ds.core.builder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/event.test/.settings/org.eclipse.jdt.core.prefs b/event.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..18d2a1601c
--- /dev/null
+++ b/event.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun Dec 05 18:12:35 MYT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/event.test/META-INF/MANIFEST.MF b/event.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..670ef0d376
--- /dev/null
+++ b/event.test/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Test
+Bundle-SymbolicName: event.test
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: event.test.Activator
+Require-Bundle: org.adempiere.base;bundle-version="1.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Import-Package: org.eclipse.equinox.events;version="1.0.0",
+ org.osgi.framework,
+ org.osgi.service.event;version="1.2.0"
+Service-Component: OSGI-INF/event.xml
diff --git a/event.test/OSGI-INF/event.xml b/event.test/OSGI-INF/event.xml
new file mode 100644
index 0000000000..4b33a64fa5
--- /dev/null
+++ b/event.test/OSGI-INF/event.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/event.test/build.properties b/event.test/build.properties
new file mode 100644
index 0000000000..9ea938077d
--- /dev/null
+++ b/event.test/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/event.xml
+source.. = src/
diff --git a/event.test/src/event/test/Activator.java b/event.test/src/event/test/Activator.java
new file mode 100644
index 0000000000..d6b4ed6432
--- /dev/null
+++ b/event.test/src/event/test/Activator.java
@@ -0,0 +1,30 @@
+package event.test;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
diff --git a/event.test/src/event/test/MyEventHandler.java b/event.test/src/event/test/MyEventHandler.java
new file mode 100644
index 0000000000..85f9b377d1
--- /dev/null
+++ b/event.test/src/event/test/MyEventHandler.java
@@ -0,0 +1,39 @@
+package event.test;
+
+import org.adempiere.base.event.IEventManager;
+import org.adempiere.base.event.IEventTopics;
+import org.adempiere.base.event.LoginEventData;
+import org.compiere.model.PO;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class MyEventHandler implements EventHandler {
+
+ @Override
+ public void handleEvent(Event event) {
+ if (event.getTopic().equals(IEventTopics.AFTER_LOGIN)) {
+ LoginEventData eventData = (LoginEventData) event.getProperty(IEventManager.EVENT_DATA);
+ System.out.println(" topic="+event.getTopic()+" AD_Client_ID="+eventData.getAD_Client_ID()
+ +" AD_Org_ID="+eventData.getAD_Org_ID()+" AD_Role_ID="+eventData.getAD_Role_ID()
+ +" AD_User_ID="+eventData.getAD_User_ID());
+ } else if (event.getTopic().equals(IEventTopics.PO_AFTER_NEW)) {
+ PO po = (PO) event.getProperty(IEventManager.EVENT_DATA);
+ System.out.println(" topic="+event.getTopic()+" po="+po);
+ }
+
+ }
+
+ public void bindEventManager(IEventManager eventManager) {
+ eventManager.register(IEventTopics.AFTER_LOGIN, this);
+ eventManager.register(IEventTopics.PO_AFTER_NEW, "(tableName=C_Order)", this);
+ }
+
+ public void unbindEventManager(IEventManager eventManager) {
+ eventManager.unregister(this);
+ }
+}
diff --git a/org.adempiere.base-feature/feature.xml b/org.adempiere.base-feature/feature.xml
index 3cb8280f16..c1ce1be344 100644
--- a/org.adempiere.base-feature/feature.xml
+++ b/org.adempiere.base-feature/feature.xml
@@ -300,4 +300,25 @@
version="0.0.0"
unpack="false"/>
+
+
+
+
+
+
diff --git a/org.adempiere.base/.project b/org.adempiere.base/.project
index cba43891c4..f4aae4f2b0 100644
--- a/org.adempiere.base/.project
+++ b/org.adempiere.base/.project
@@ -34,6 +34,11 @@
+
+ org.eclipse.pde.ds.core.builder
+
+
+
org.eclipse.jem.workbench.JavaEMFNature
diff --git a/org.adempiere.base/META-INF/MANIFEST.MF b/org.adempiere.base/META-INF/MANIFEST.MF
index 0953248ab6..b557e4c637 100644
--- a/org.adempiere.base/META-INF/MANIFEST.MF
+++ b/org.adempiere.base/META-INF/MANIFEST.MF
@@ -59,6 +59,7 @@ Export-Package: bsh,
net.sourceforge.barbecue.twod.pdf417,
org.adempiere.apps.graph,
org.adempiere.base,
+ org.adempiere.base.event,
org.adempiere.exceptions,
org.adempiere.impexp,
org.adempiere.model,
@@ -164,6 +165,7 @@ Import-Package: com.sun.mail.smtp;version="1.4.0",
org.eclipse.osgi.framework.console;version="1.1.0",
org.eclipse.osgi.service.datalocation,
org.osgi.framework,
+ org.osgi.service.event;version="1.2.0",
org.restlet,
org.restlet.data,
org.restlet.representation,
@@ -171,3 +173,5 @@ Import-Package: com.sun.mail.smtp;version="1.4.0",
Eclipse-BuddyPolicy: registered
Eclipse-ExtensibleAPI: true
Bundle-Activator: org.adempiere.base.BaseActivator
+Service-Component: OSGI-INF/eventmanager.xml
+Bundle-ActivationPolicy: lazy
diff --git a/org.adempiere.base/OSGI-INF/eventmanager.xml b/org.adempiere.base/OSGI-INF/eventmanager.xml
new file mode 100644
index 0000000000..2f30624198
--- /dev/null
+++ b/org.adempiere.base/OSGI-INF/eventmanager.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/org.adempiere.base/build.properties b/org.adempiere.base/build.properties
index f156f1bc4e..b72d202993 100644
--- a/org.adempiere.base/build.properties
+++ b/org.adempiere.base/build.properties
@@ -1,5 +1,3 @@
-source.base.jar = src/
-output.base.jar = build/
bin.includes = META-INF/,\
base.jar,\
plugin.xml,\
@@ -14,4 +12,7 @@ bin.includes = META-INF/,\
iText-2.1.7.jar,\
jcommon-1.0.16.jar,\
jfreechart-1.0.13.jar,\
- jnlp.jar
+ jnlp.jar,\
+ OSGI-INF/eventmanager.xml
+output.base.jar = build/
+source.base.jar = src/
diff --git a/org.adempiere.base/src/org/adempiere/base/BaseActivator.java b/org.adempiere.base/src/org/adempiere/base/BaseActivator.java
index ad59c7c220..108b3b283c 100644
--- a/org.adempiere.base/src/org/adempiere/base/BaseActivator.java
+++ b/org.adempiere.base/src/org/adempiere/base/BaseActivator.java
@@ -24,8 +24,10 @@ import org.osgi.framework.BundleContext;
*/
public class BaseActivator implements BundleActivator {
+ private static BundleContext bundleContext = null;
+
/**
- *
+ * default constructor
*/
public BaseActivator() {
}
@@ -35,6 +37,7 @@ public class BaseActivator implements BundleActivator {
*/
@Override
public void start(BundleContext context) throws Exception {
+ bundleContext = context;
context.registerService(CommandProvider.class.getName(), new StackTraceCommand(), null);
}
@@ -43,6 +46,10 @@ public class BaseActivator implements BundleActivator {
*/
@Override
public void stop(BundleContext context) throws Exception {
+ bundleContext = null;
}
+ public static BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
diff --git a/org.adempiere.base/src/org/adempiere/base/event/EventManager.java b/org.adempiere.base/src/org/adempiere/base/event/EventManager.java
new file mode 100644
index 0000000000..d798126c2d
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/EventManager.java
@@ -0,0 +1,211 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.adempiere.base.BaseActivator;
+import org.compiere.util.CLogger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+
+/**
+ * Simple wrapper for the osgi event admin service.
+ * Usage: EventManager.getInstance().sendEvent/postEvent
+ * @author hengsin
+ *
+ */
+public class EventManager implements IEventManager {
+
+ private EventAdmin eventAdmin;
+ private static IEventManager instance = null;
+ private final static CLogger log = CLogger.getCLogger(EventManager.class);
+
+ private Map> registrations = new HashMap>();
+
+ /**
+ * @param eventAdmin
+ */
+ public void bindEventAdmin(EventAdmin eventAdmin) {
+ if (instance == null)
+ instance = this;
+ this.eventAdmin = eventAdmin;
+ }
+
+ /**
+ * @param eventAdmin
+ */
+ public void unbindEventAdmin(EventAdmin eventAdmin) {
+ this.eventAdmin = null;
+ }
+
+ /**
+ * Get the singleton instance created by the osgi service framework
+ * @return EventManager
+ */
+ public static IEventManager getInstance() {
+ return instance;
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#postEvent(org.osgi.service.event.Event)
+ */
+ @Override
+ public boolean postEvent(Event event) {
+ if (eventAdmin != null) {
+ eventAdmin.postEvent(event);
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#sendEvent(org.osgi.service.event.Event)
+ */
+ @Override
+ public boolean sendEvent(Event event) {
+ if (eventAdmin != null) {
+ eventAdmin.postEvent(event);
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#register(java.lang.String, org.osgi.service.event.EventHandler)
+ */
+ @Override
+ public boolean register(String topic, EventHandler eventHandler) {
+ return register(topic, null, eventHandler);
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#register(java.lang.String[], org.osgi.service.event.EventHandler)
+ */
+ @Override
+ public boolean register(String[] topics, EventHandler eventHandler) {
+ return register(topics, null, eventHandler);
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#register(java.lang.String, java.lang.String, org.osgi.service.event.EventHandler)
+ */
+ @Override
+ public boolean register(String topic, String filter, EventHandler eventHandler) {
+ String[] topics = new String[] {topic};
+ return register(topics, filter, eventHandler);
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#register(java.lang.String[], java.lang.String, org.osgi.service.event.EventHandler)
+ */
+ @Override
+ public boolean register(String[] topics, String filter, EventHandler eventHandler) {
+ BundleContext bundleContext = BaseActivator.getBundleContext();
+ if (bundleContext == null) {
+ log.severe("No bundle context. Topic="+Arrays.toString(topics));
+ return false;
+ }
+ Dictionary d = new Hashtable();
+ d.put(EventConstants.EVENT_TOPIC, topics);
+ if (filter != null)
+ d.put(EventConstants.EVENT_FILTER, filter);
+ ServiceRegistration registration = bundleContext.registerService(EventHandler.class.getName(), eventHandler, d);
+ synchronized(registrations) {
+ List list = registrations.get(eventHandler);
+ if (list == null) {
+ list = new ArrayList();
+ registrations.put(eventHandler, list);
+ }
+ list.add(registration);
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.adempiere.base.event.IEventManager#unregister(org.osgi.service.event.EventHandler)
+ */
+ @Override
+ public boolean unregister(EventHandler eventHandler) {
+ List serviceRegistrations = null;
+ synchronized(registrations) {
+ serviceRegistrations = registrations.remove(eventHandler);
+ }
+ if (serviceRegistrations == null)
+ return false;
+ for (ServiceRegistration registration : serviceRegistrations)
+ registration.unregister();
+ return true;
+ }
+
+ /**
+ * @param topic
+ * @param parameter
+ */
+ @SuppressWarnings("unchecked")
+ public static Event newEvent(String topic, Object data) {
+ Event event = null;
+ if (data instanceof Dictionary,?>) {
+ Dictionarydict = (Dictionary)data;
+ if (dict.get(EVENT_ERROR_MESSAGES) == null)
+ dict.put(EVENT_ERROR_MESSAGES, new ArrayList());
+ event = new Event(topic, dict);
+ } else if (data instanceof Map, ?>) {
+ Map map = (Map)data;
+ if (!map.containsKey(EVENT_ERROR_MESSAGES))
+ map.put(EVENT_ERROR_MESSAGES, new ArrayList());
+ event = new Event(topic, map);
+ } else {
+ Map map = new HashMap(3);
+ map.put(EventConstants.EVENT_TOPIC, topic);
+ if (data != null)
+ map.put(EVENT_DATA, data);
+ map.put(EVENT_ERROR_MESSAGES, new ArrayList());
+ event = new Event(topic, map);
+ }
+ return event;
+ }
+
+ /**
+ *
+ * @param topic
+ * @param properties
+ * @return event object
+ */
+ public static Event newEvent(String topic, EventProperty ...properties) {
+ Event event = null;
+ Map map = new HashMap(3);
+ if (properties != null) {
+ for(int i = 0; i < properties.length; i++) {
+ map.put(properties[i].name, properties[i].value);
+ }
+ if (!map.containsKey(EventConstants.EVENT_TOPIC))
+ map.put(EventConstants.EVENT_TOPIC, topic);
+ if (!map.containsKey(EVENT_ERROR_MESSAGES))
+ map.put(EVENT_ERROR_MESSAGES, new ArrayList());
+ }
+ event = new Event(topic, map);
+ return event;
+ }
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/event/EventProperty.java b/org.adempiere.base/src/org/adempiere/base/event/EventProperty.java
new file mode 100644
index 0000000000..05260d46f4
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/EventProperty.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class EventProperty {
+ public String name;
+ public Object value;
+
+ /**
+ * @param name
+ * @param value
+ */
+ public EventProperty(String name, Object value) {
+ super();
+ this.name = name;
+ this.value = value;
+ }
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/event/FactsEventData.java b/org.adempiere.base/src/org/adempiere/base/event/FactsEventData.java
new file mode 100644
index 0000000000..014eb58ae2
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/FactsEventData.java
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+import java.util.List;
+
+import org.compiere.acct.Fact;
+import org.compiere.model.MAcctSchema;
+import org.compiere.model.PO;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class FactsEventData {
+ private MAcctSchema acctSchema;
+ private List facts;
+ private PO po;
+
+ /**
+ * @param acctSchema
+ * @param facts
+ * @param po
+ */
+ public FactsEventData(MAcctSchema acctSchema, List facts, PO po) {
+ super();
+ this.acctSchema = acctSchema;
+ this.facts = facts;
+ this.po = po;
+ }
+
+ /**
+ * @return the acctSchema
+ */
+ public MAcctSchema getAcctSchema() {
+ return acctSchema;
+ }
+
+ /**
+ * @return the facts
+ */
+ public List getFacts() {
+ return facts;
+ }
+
+ /**
+ * @return the po
+ */
+ public PO getPo() {
+ return po;
+ }
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java b/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java
new file mode 100644
index 0000000000..e337830e12
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public interface IEventManager {
+
+ public static final String EVENT_DATA = "event.data";
+ public static final String EVENT_ERROR_MESSAGES = "event.errorMessages";
+
+ /**
+ * Initiate asynchronous delivery of an event. This method returns to the
+ * caller before delivery of the event is completed.
+ *
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
+ *
+ * @throws SecurityException If the caller does not have
+ * TopicPermission[topic,PUBLISH]
for the topic
+ * specified in the event.
+ */
+ public abstract boolean postEvent(Event event);
+
+ /**
+ * Initiate synchronous delivery of an event. This method does not return to
+ * the caller until delivery of the event is completed.
+ *
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
+ *
+ * @throws SecurityException If the caller does not have
+ * TopicPermission[topic,PUBLISH]
for the topic
+ * specified in the event.
+ */
+ public abstract boolean sendEvent(Event event);
+
+ /**
+ * register a new event handler
+ * @param topic
+ * @param eventHandler
+ * @return true if registration is successful, false otherwise
+ */
+ public abstract boolean register(String topic, EventHandler eventHandler);
+
+ /**
+ * register a new event handler
+ * @param topics
+ * @param eventHandler
+ * @return true if registration is successful, false otherwise
+ */
+ public abstract boolean register(String[] topics, EventHandler eventHandler);
+
+ /**
+ * register a new event handler
+ * @param topic
+ * @param filter
+ * @param eventHandler
+ * @return true if registration is successful, false otherwise
+ */
+ public abstract boolean register(String topic, String filter,
+ EventHandler eventHandler);
+
+ /**
+ * register a new event handler
+ * @param topics
+ * @param filter
+ * @param eventHandler
+ * @return true if registration is successful, false otherwise
+ */
+ public abstract boolean register(String[] topics, String filter,
+ EventHandler eventHandler);
+
+ /**
+ * un-register an event handler
+ * @param eventHandler
+ * @return true if unregistration is done, false otherwise
+ */
+ public abstract boolean unregister(EventHandler eventHandler);
+
+}
\ No newline at end of file
diff --git a/org.adempiere.base/src/org/adempiere/base/event/IEventTopics.java b/org.adempiere.base/src/org/adempiere/base/event/IEventTopics.java
new file mode 100644
index 0000000000..9cb100a673
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/IEventTopics.java
@@ -0,0 +1,94 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public interface IEventTopics {
+
+ public static final String MODEL_EVENT_PREFIX = "adempiere/po/";
+ /** Model Change Type New */
+ public static final String PO_BEFORE_NEW = MODEL_EVENT_PREFIX+"beforeNew";
+ public static final String PO_AFTER_NEW = MODEL_EVENT_PREFIX+"afterNew";
+ public static final String PO_AFTER_NEW_REPLICATION = MODEL_EVENT_PREFIX+"afterNewReplication"; // @Trifon
+ /** Model Change Type Change */
+ public static final String PO_BEFORE_CHANGE = MODEL_EVENT_PREFIX+"beforeChange";
+ public static final String PO_AFTER_CHANGE = MODEL_EVENT_PREFIX+"afterChange";
+ public static final String PO_AFTER_CHANGE_REPLICATION = MODEL_EVENT_PREFIX+"afterChangeReplication"; // @Trifon
+ /** Model Change Type Delete */
+ public static final String PO_BEFORE_DELETE = MODEL_EVENT_PREFIX+"beforeDelete";
+ public static final String PO_AFTER_DELETE = MODEL_EVENT_PREFIX+"afterDelete";
+ public static final String PO_BEFORE_DELETE_REPLICATION = MODEL_EVENT_PREFIX+"beforeDeleteReplication"; // @Trifon
+ //asynchrous model event
+ public static final String PO_POST_CREATE = MODEL_EVENT_PREFIX+"postCreate";
+ public static final String PO_POST_UPADTE = MODEL_EVENT_PREFIX+"postUpdate";
+ public static final String PO_POST_DELETE = MODEL_EVENT_PREFIX+"postDelete";
+ public static final String PO_ALL = MODEL_EVENT_PREFIX+"*";
+
+ public static final String DOC_EVENT_PREFIX = "adempiere/doc/";
+ /** Called before document is prepared */
+ public static final String DOC_BEFORE_PREPARE = DOC_EVENT_PREFIX+"beforePrepare";
+ /** Called before document is void */
+ public static final String DOC_BEFORE_VOID = DOC_EVENT_PREFIX+"beforeVoid";
+ /** Called before document is close */
+ public static final String DOC_BEFORE_CLOSE = DOC_EVENT_PREFIX+"beforeClose";
+ /** Called before document is reactivate */
+ public static final String DOC_BEFORE_REACTIVATE = DOC_EVENT_PREFIX+"beforeReactivate";
+ /** Called before document is reversecorrect */
+ public static final String DOC_BEFORE_REVERSECORRECT = DOC_EVENT_PREFIX+"beforeReverseCorrect";
+ /** Called before document is reverseaccrual */
+ public static final String DOC_BEFORE_REVERSEACCRUAL = DOC_EVENT_PREFIX+"beforeReverseAccrual";
+ /** Called before document is completed */
+ public static final String DOC_BEFORE_COMPLETE = DOC_EVENT_PREFIX+"beforeComplete";
+ /** Called after document is prepared */
+ public static final String DOC_AFTER_PREPARE = DOC_EVENT_PREFIX+"afterPrepare";
+ /** Called after document is completed */
+ public static final String DOC_AFTER_COMPLETE = DOC_EVENT_PREFIX+"afterComplete";
+ /** Called after document is void */
+ public static final String DOC_AFTER_VOID = DOC_EVENT_PREFIX+"afterVoid";
+ /** Called after document is closed */
+ public static final String DOC_AFTER_CLOSE = DOC_EVENT_PREFIX+"afterClose";
+ /** Called after document is reactivated */
+ public static final String DOC_AFTER_REACTIVATE = DOC_EVENT_PREFIX+"afterReactivate";
+ /** Called after document is reversecorrect */
+ public static final String DOC_AFTER_REVERSECORRECT = DOC_EVENT_PREFIX+"afterReverseCorrect";
+ /** Called after document is reverseaccrual */
+ public static final String DOC_AFTER_REVERSEACCRUAL = DOC_EVENT_PREFIX+"afterReverseAccrual";
+ /** Called before document is posted */
+ public static final String DOC_BEFORE_POST = DOC_EVENT_PREFIX+"beforePost";
+ /** Called after document is posted */
+ public static final String DOC_AFTER_POST = DOC_EVENT_PREFIX+"afterPost";
+ public static final String DOC_ALL = DOC_EVENT_PREFIX+"*";
+
+ public static final String AFTER_LOGIN = "adempiere/afterLogin";
+
+ public static final String ACCT_FACTS_VALIDATE = "adempiere/acct/factsValidate";
+
+ /** Import Events **/
+ public static final String IMPORT_PREFIX = "adempiere/import/";
+ /** Event triggered before all import records are validated */
+ public static final String IMPORT_BEFORE_VALIDATE = IMPORT_PREFIX+"beforeValidate";
+ /** Event triggered after all import records are validated */
+ public static final String IMPORT_AFTER_VALIDATE = IMPORT_PREFIX+"afterValidate";
+ /** Event triggered before an import record is processed */
+ public static final String IMPORT_BEFORE_IMPORT = IMPORT_PREFIX+"beforeImport";
+ /** Event triggered after an import record is processed */
+ public static final String IMPORT_AFTER_IMPORT = IMPORT_PREFIX+"afterImport";
+
+ public static final String PREF_AFTER_LOAD = "adempiere/pref/afterLoad";
+}
+
diff --git a/org.adempiere.base/src/org/adempiere/base/event/ImportEventData.java b/org.adempiere.base/src/org/adempiere/base/event/ImportEventData.java
new file mode 100644
index 0000000000..5bd3818c2a
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/ImportEventData.java
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+import org.adempiere.process.ImportProcess;
+import org.compiere.model.PO;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class ImportEventData {
+ private ImportProcess importProcess;
+ private PO source;
+ private PO target;
+
+ /**
+ * @param importProcess
+ * @param source
+ * @param target
+ */
+ public ImportEventData(ImportProcess importProcess, PO source, PO target) {
+ super();
+ this.importProcess = importProcess;
+ this.source = source;
+ this.target = target;
+ }
+
+ /**
+ * @return the importProcess
+ */
+ public ImportProcess getImportProcess() {
+ return importProcess;
+ }
+
+ /**
+ * @return the source
+ */
+ public PO getSource() {
+ return source;
+ }
+
+ /**
+ * @return the target
+ */
+ public PO getTarget() {
+ return target;
+ }
+}
diff --git a/org.adempiere.base/src/org/adempiere/base/event/LoginEventData.java b/org.adempiere.base/src/org/adempiere/base/event/LoginEventData.java
new file mode 100644
index 0000000000..408e80eeed
--- /dev/null
+++ b/org.adempiere.base/src/org/adempiere/base/event/LoginEventData.java
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution *
+ * Copyright (C) 2010 Heng Sin Low *
+ * 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. *
+ *****************************************************************************/
+package org.adempiere.base.event;
+
+/**
+ *
+ * @author hengsin
+ *
+ */
+public class LoginEventData {
+ private int AD_Client_ID;
+ private int AD_Org_ID;
+ private int AD_Role_ID;
+ private int AD_User_ID;
+
+ /**
+ * @param aD_Client_ID
+ * @param aD_Org_ID
+ * @param aD_Role_ID
+ * @param aD_User_ID
+ */
+ public LoginEventData(int aD_Client_ID, int aD_Org_ID, int aD_Role_ID,
+ int aD_User_ID) {
+ super();
+ AD_Client_ID = aD_Client_ID;
+ AD_Org_ID = aD_Org_ID;
+ AD_Role_ID = aD_Role_ID;
+ AD_User_ID = aD_User_ID;
+ }
+
+ /**
+ * @return the aD_Client_ID
+ */
+ public int getAD_Client_ID() {
+ return AD_Client_ID;
+ }
+
+ /**
+ * @return the aD_Org_ID
+ */
+ public int getAD_Org_ID() {
+ return AD_Org_ID;
+ }
+
+ /**
+ * @return the aD_Role_ID
+ */
+ public int getAD_Role_ID() {
+ return AD_Role_ID;
+ }
+
+ /**
+ * @return the aD_User_ID
+ */
+ public int getAD_User_ID() {
+ return AD_User_ID;
+ }
+
+}
diff --git a/org.adempiere.base/src/org/compiere/model/ModelValidationEngine.java b/org.adempiere.base/src/org/compiere/model/ModelValidationEngine.java
index 3d53b678dd..faab982dfa 100644
--- a/org.adempiere.base/src/org/compiere/model/ModelValidationEngine.java
+++ b/org.adempiere.base/src/org/compiere/model/ModelValidationEngine.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.logging.Level;
@@ -27,12 +28,20 @@ import java.util.logging.Level;
import javax.script.ScriptEngine;
import org.adempiere.base.Core;
+import org.adempiere.base.event.EventManager;
+import org.adempiere.base.event.EventProperty;
+import org.adempiere.base.event.FactsEventData;
+import org.adempiere.base.event.IEventManager;
+import org.adempiere.base.event.IEventTopics;
+import org.adempiere.base.event.ImportEventData;
+import org.adempiere.base.event.LoginEventData;
import org.adempiere.model.ImportValidator;
import org.adempiere.process.ImportProcess;
import org.compiere.acct.Fact;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
+import org.osgi.service.event.Event;
/**
* Model Validation Engine
@@ -146,7 +155,7 @@ public class ModelValidationEngine
{
//
ModelValidator validator = null;
- if (Core.isExtension(className))
+ if (Core.isExtension(className))
{
validator = Core.getModelValidator(className);
}
@@ -250,7 +259,15 @@ public class ModelValidationEngine
}
}
}
- //
+
+ //now process osgi event handler
+ LoginEventData eventData = new LoginEventData(AD_Client_ID, AD_Org_ID, AD_Role_ID, AD_User_ID);
+ Event event = EventManager.newEvent(IEventTopics.AFTER_LOGIN, eventData);
+ EventManager.getInstance().sendEvent(event);
+ @SuppressWarnings("unchecked")
+ List errors = (List) event.getProperty(IEventManager.EVENT_ERROR_MESSAGES);
+ if (errors != null && !errors.isEmpty())
+ return errors.get(0);
if (AD_User_ID == 0 && AD_Role_ID == 0)
; // don't validate for user system on role system
@@ -378,7 +395,15 @@ public class ModelValidationEngine
}
}
}
- //
+
+ //now process osgi event handlers
+ Event event = EventManager.newEvent(ModelValidator.tableEventTopics[changeType],
+ new EventProperty(EventManager.EVENT_DATA, po), new EventProperty("tableName", po.get_TableName()));
+ EventManager.getInstance().sendEvent(event);
+ @SuppressWarnings("unchecked")
+ List errors = (List) event.getProperty(IEventManager.EVENT_ERROR_MESSAGES);
+ if (errors != null && !errors.isEmpty())
+ return errors.get(0);
return null;
} // fireModelChange
@@ -534,7 +559,15 @@ public class ModelValidationEngine
}
}
}
- //
+
+ //now process osgi event handlers
+ Event event = EventManager.newEvent(ModelValidator.documentEventTopics[docTiming],
+ new EventProperty(EventManager.EVENT_DATA, po), new EventProperty("tableName", po.get_TableName()));
+ EventManager.getInstance().sendEvent(event);
+ @SuppressWarnings("unchecked")
+ List errors = (List) event.getProperty(IEventManager.EVENT_ERROR_MESSAGES);
+ if (errors != null && !errors.isEmpty())
+ return errors.get(0);
return null;
} // fireDocValidate
@@ -676,6 +709,15 @@ public class ModelValidationEngine
return error;
}
+ //process osgi event handlers
+ FactsEventData eventData = new FactsEventData(schema, facts, po);
+ Event event = EventManager.newEvent(IEventTopics.ACCT_FACTS_VALIDATE,
+ new EventProperty(EventManager.EVENT_DATA, eventData), new EventProperty("tableName", po.get_TableName()));
+ @SuppressWarnings("unchecked")
+ List errors = (List) event.getProperty(IEventManager.EVENT_ERROR_MESSAGES);
+ if (errors != null && !errors.isEmpty())
+ return errors.get(0);
+
return null;
} // fireFactsValidate
@@ -737,6 +779,20 @@ public class ModelValidationEngine
validator.validate(process, importModel, targetModel, timing);
}
}
+
+ //osgi event handler
+ ImportEventData eventData = new ImportEventData(process, importModel, targetModel);
+ String topic = null;
+ if (timing == ImportValidator.TIMING_AFTER_IMPORT)
+ topic = IEventTopics.IMPORT_AFTER_IMPORT;
+ else if (timing == ImportValidator.TIMING_AFTER_VALIDATE)
+ topic = IEventTopics.IMPORT_AFTER_VALIDATE;
+ else if (timing == ImportValidator.TIMING_BEFORE_IMPORT)
+ topic = IEventTopics.IMPORT_BEFORE_IMPORT;
+ else if (timing == ImportValidator.TIMING_BEFORE_VALIDATE)
+ topic = IEventTopics.IMPORT_BEFORE_VALIDATE;
+ Event event = EventManager.newEvent(topic, new EventProperty(EventManager.EVENT_DATA, eventData), new EventProperty("importTableName", process.getImportTableName()));
+ EventManager.getInstance().sendEvent(event);
}
/**
@@ -827,6 +883,11 @@ public class ModelValidationEngine
}
}
}
+
+ //osgi event handlers
+ @SuppressWarnings("rawtypes")
+ Event event = new Event(IEventTopics.PREF_AFTER_LOAD, (Map)null);
+ EventManager.getInstance().sendEvent(event);
}
/**
diff --git a/org.adempiere.base/src/org/compiere/model/ModelValidator.java b/org.adempiere.base/src/org/compiere/model/ModelValidator.java
index de3329bbd8..bb3c3d1623 100644
--- a/org.adempiere.base/src/org/compiere/model/ModelValidator.java
+++ b/org.adempiere.base/src/org/compiere/model/ModelValidator.java
@@ -17,35 +17,37 @@
*****************************************************************************/
package org.compiere.model;
+import org.adempiere.base.event.IEventTopics;
+
/**
* Model Validator
- *
+ *
* @author Jorg Janke
* @version $Id: ModelValidator.java,v 1.2 2006/07/30 00:58:18 jjanke Exp $
- *
+ *
* 2007/02/26 laydasalasc - globalqss - Add new timings for all before/after events on documents
*/
public interface ModelValidator
{
/** Model Change Type New */
- public static final int TYPE_BEFORE_NEW = 1; // teo_sarca [ 1675490 ]
+ public static final int TYPE_BEFORE_NEW = 1; // teo_sarca [ 1675490 ]
public static final int TYPE_NEW = 1;
public static final int CHANGETYPE_NEW = 1; // Compatibility with Compiere 260c
- public static final int TYPE_AFTER_NEW = 4; // teo_sarca [ 1675490 ]
+ public static final int TYPE_AFTER_NEW = 4; // teo_sarca [ 1675490 ]
public static final int TYPE_AFTER_NEW_REPLICATION = 7; // @Trifon
/** Model Change Type Change */
- public static final int TYPE_BEFORE_CHANGE = 2; // teo_sarca [ 1675490 ]
+ public static final int TYPE_BEFORE_CHANGE = 2; // teo_sarca [ 1675490 ]
public static final int TYPE_CHANGE = 2;
public static final int CHANGETYPE_CHANGE = 2; // Compatibility with Compiere 260c
- public static final int TYPE_AFTER_CHANGE = 5; // teo_sarca [ 1675490 ]
+ public static final int TYPE_AFTER_CHANGE = 5; // teo_sarca [ 1675490 ]
public static final int TYPE_AFTER_CHANGE_REPLICATION = 8; // @Trifon
/** Model Change Type Delete */
- public static final int TYPE_BEFORE_DELETE = 3; // teo_sarca [ 1675490 ]
+ public static final int TYPE_BEFORE_DELETE = 3; // teo_sarca [ 1675490 ]
public static final int TYPE_DELETE = 3;
public static final int CHANGETYPE_DELETE = 3; // Compatibility with Compiere 260c
public static final int TYPE_AFTER_DELETE = 6; // teo_sarca [ 1675490 ]
- public static final int TYPE_BEFORE_DELETE_REPLICATION = 9; // @Trifon
-
+ public static final int TYPE_BEFORE_DELETE_REPLICATION = 9; // @Trifon
+
// Correlation between constant events and list of event script model validators
public static String[] tableEventValidators = new String[] {
"", // 0
@@ -54,12 +56,26 @@ public interface ModelValidator
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeDelete, // TYPE_BEFORE_DELETE = 3
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterNew, // TYPE_AFTER_NEW = 4
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterChange, // TYPE_AFTER_CHANGE = 5
- X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterDelete, // TYPE_AFTER_DELETE = 6
+ X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterDelete, // TYPE_AFTER_DELETE = 6
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterNewReplication, // TYPE_AFTER_NEW_REPLICATION = 7
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterChangeReplication, // TYPE_AFTER_CHANGE_REPLICATION = 8
- X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeDeleteReplication // TYPE_BEFORE_DELETE_REPLICATION = 9
+ X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeDeleteReplication // TYPE_BEFORE_DELETE_REPLICATION = 9
};
-
+
+ // Correlation between constant events and list of osgi event topic
+ public static String[] tableEventTopics = new String[] {
+ "", // 0
+ IEventTopics.PO_BEFORE_NEW, // TYPE_BEFORE_NEW = 1
+ IEventTopics.PO_BEFORE_CHANGE, // TYPE_BEFORE_CHANGE = 2
+ IEventTopics.PO_BEFORE_DELETE, // TYPE_BEFORE_DELETE = 3
+ IEventTopics.PO_AFTER_NEW, // TYPE_AFTER_NEW = 4
+ IEventTopics.PO_AFTER_CHANGE, // TYPE_AFTER_CHANGE = 5
+ IEventTopics.PO_AFTER_DELETE, // TYPE_AFTER_DELETE = 6
+ IEventTopics.PO_AFTER_NEW_REPLICATION, // TYPE_AFTER_NEW_REPLICATION = 7
+ IEventTopics.PO_AFTER_CHANGE_REPLICATION, // TYPE_AFTER_CHANGE_REPLICATION = 8
+ IEventTopics.PO_BEFORE_DELETE_REPLICATION// TYPE_BEFORE_DELETE_REPLICATION = 9
+ };
+
/** Called before document is prepared */
public static final int TIMING_BEFORE_PREPARE = 1;
public static final int DOCTIMING_BEFORE_PREPARE = 1; // Compatibility with Compiere 260c
@@ -94,7 +110,7 @@ public interface ModelValidator
public static final int TIMING_BEFORE_POST = 15;
/** Called after document is posted */
public static final int TIMING_AFTER_POST = 16;
-
+
// Correlation between constant events and list of event script model validators
public static String[] documentEventValidators = new String[] {
"", // 0
@@ -115,10 +131,31 @@ public interface ModelValidator
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforePost, // TIMING_BEFORE_POST = 15
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterPost // TIMING_AFTER_POST = 16
};
-
+
+ // Correlation between constant events and list of osgi event topics
+ public static String[] documentEventTopics = new String[] {
+ "", // 0
+ IEventTopics.DOC_BEFORE_PREPARE, // TIMING_BEFORE_PREPARE = 1
+ IEventTopics.DOC_BEFORE_VOID, // TIMING_BEFORE_VOID = 2
+ IEventTopics.DOC_BEFORE_CLOSE, // TIMING_BEFORE_CLOSE = 3
+ IEventTopics.DOC_BEFORE_REACTIVATE, // TIMING_BEFORE_REACTIVATE = 4
+ IEventTopics.DOC_BEFORE_REVERSECORRECT, // TIMING_BEFORE_REVERSECORRECT = 5
+ IEventTopics.DOC_BEFORE_REVERSEACCRUAL, // TIMING_BEFORE_REVERSEACCRUAL = 6
+ IEventTopics.DOC_BEFORE_COMPLETE, // TIMING_BEFORE_COMPLETE = 7
+ IEventTopics.DOC_AFTER_PREPARE, // TIMING_AFTER_PREPARE = 8
+ IEventTopics.DOC_AFTER_COMPLETE, // TIMING_AFTER_COMPLETE = 9
+ IEventTopics.DOC_AFTER_VOID, // TIMING_AFTER_VOID = 10
+ IEventTopics.DOC_AFTER_CLOSE, // TIMING_AFTER_CLOSE = 11
+ IEventTopics.DOC_AFTER_REACTIVATE, // TIMING_AFTER_REACTIVATE = 12
+ IEventTopics.DOC_AFTER_REVERSECORRECT, // TIMING_AFTER_REVERSECORRECT = 13
+ IEventTopics.DOC_AFTER_REVERSEACCRUAL, // TIMING_AFTER_REVERSEACCRUAL = 14
+ IEventTopics.DOC_BEFORE_POST, // TIMING_BEFORE_POST = 15
+ IEventTopics.DOC_AFTER_POST // TIMING_AFTER_POST = 16
+ };
+
/**
* Initialize Validation
- * @param engine validation engine
+ * @param engine validation engine
* @param client client
*/
public void initialize (ModelValidationEngine engine, MClient client);
@@ -128,9 +165,9 @@ public interface ModelValidator
* @return AD_Client_ID
*/
public int getAD_Client_ID();
-
+
/**
- * User logged in
+ * User logged in
* Called before preferences are set
* @param AD_Org_ID org
* @param AD_Role_ID role
@@ -139,10 +176,10 @@ public interface ModelValidator
*/
public String login (int AD_Org_ID, int AD_Role_ID, int AD_User_ID);
-
+
/**
* Model Change of a monitored Table.
- * Called after PO.beforeSave/PO.beforeDelete
+ * Called after PO.beforeSave/PO.beforeDelete
* when you called addModelChange for the table
* @param po persistent object
* @param type TYPE_
@@ -151,18 +188,18 @@ public interface ModelValidator
*/
public String modelChange (PO po, int type) throws Exception;
-
+
/**
* Validate Document.
- * Called as first step of DocAction.prepareIt
+ * Called as first step of DocAction.prepareIt
* or at the end of DocAction.completeIt
* when you called addDocValidate for the table.
* Note that totals, etc. may not be correct before the prepare stage.
* @param po persistent object
* @param timing see TIMING_ constants
- * @return error message or null -
+ * @return error message or null -
* if not null, the document will be marked as Invalid.
*/
public String docValidate (PO po, int timing);
-
+
} // ModelValidator
diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java
index afbc9b1448..75862afb2f 100644
--- a/org.adempiere.base/src/org/compiere/model/PO.java
+++ b/org.adempiere.base/src/org/compiere/model/PO.java
@@ -41,6 +41,8 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.adempiere.base.event.EventManager;
+import org.adempiere.base.event.IEventTopics;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere;
@@ -57,6 +59,7 @@ import org.compiere.util.SecureEngine;
import org.compiere.util.Trace;
import org.compiere.util.Trx;
import org.compiere.util.ValueNamePair;
+import org.osgi.service.event.Event;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -2219,6 +2222,11 @@ public abstract class PO
// OK
if (success)
{
+ //post osgi event
+ String topic = newRecord ? IEventTopics.PO_POST_CREATE : IEventTopics.PO_POST_UPADTE;
+ Event event = EventManager.newEvent(topic, this);
+ EventManager.getInstance().postEvent(event);
+
if (s_docWFMgr == null)
{
try
@@ -3053,6 +3061,10 @@ public abstract class PO
// Reset
if (success)
{
+ //osgi event handler
+ Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this);
+ EventManager.getInstance().postEvent(event);
+
m_idOld = 0;
int size = p_info.getColumnCount();
m_oldValues = new Object[size];
diff --git a/org.adempiere.install/install.app.launch b/org.adempiere.install/install.app.launch
index 54d86821eb..902b6eb1ad 100644
--- a/org.adempiere.install/install.app.launch
+++ b/org.adempiere.install/install.app.launch
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/org.adempiere.install/install.console.app.launch b/org.adempiere.install/install.console.app.launch
index eeef1dc5c0..4cdf35d867 100644
--- a/org.adempiere.install/install.console.app.launch
+++ b/org.adempiere.install/install.console.app.launch
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/org.adempiere.server-feature/server.product b/org.adempiere.server-feature/server.product
index 7d6b1026e8..12bec589ee 100644
--- a/org.adempiere.server-feature/server.product
+++ b/org.adempiere.server-feature/server.product
@@ -33,6 +33,7 @@
+
@@ -41,11 +42,12 @@
-
+
+
-
+
diff --git a/org.adempiere.server-feature/server.product.eventtest.launch b/org.adempiere.server-feature/server.product.eventtest.launch
new file mode 100644
index 0000000000..ea522c7af7
--- /dev/null
+++ b/org.adempiere.server-feature/server.product.eventtest.launch
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.adempiere.server-feature/server.product.launch b/org.adempiere.server-feature/server.product.launch
index c223091b07..3762427c39 100644
--- a/org.adempiere.server-feature/server.product.launch
+++ b/org.adempiere.server-feature/server.product.launch
@@ -7,7 +7,7 @@
-
+
@@ -21,8 +21,8 @@
-
-
+
+
diff --git a/org.adempiere.ui.swing-feature/swingclient.product b/org.adempiere.ui.swing-feature/swingclient.product
index e7e2485459..a860309522 100644
--- a/org.adempiere.ui.swing-feature/swingclient.product
+++ b/org.adempiere.ui.swing-feature/swingclient.product
@@ -31,6 +31,10 @@
+
+
+
+
diff --git a/org.adempiere.ui.swing-feature/swingclient.product.launch b/org.adempiere.ui.swing-feature/swingclient.product.launch
index 042c44455a..d76031eac3 100644
--- a/org.adempiere.ui.swing-feature/swingclient.product.launch
+++ b/org.adempiere.ui.swing-feature/swingclient.product.launch
@@ -21,8 +21,8 @@
-
-
+
+