Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Alexander Kuppe2013-07-05 10:48:26 +0000
committerMarkus Alexander Kuppe2013-07-05 10:57:10 +0000
commit5c3c256bf85388a923d3a556497f2162224ae6b2 (patch)
treee0e2bf1a1b608d81ebda124d3cbe4191d2cfeb8c /server-side
parent1ef01d57da1ca89b55b1b4a4e3bccabdedeb1941 (diff)
downloadorg.eclipse.ecf-5c3c256bf85388a923d3a556497f2162224ae6b2.tar.gz
org.eclipse.ecf-5c3c256bf85388a923d3a556497f2162224ae6b2.tar.xz
org.eclipse.ecf-5c3c256bf85388a923d3a556497f2162224ae6b2.zip
NEW - bug 412186: [Distributed EventAdmin] Revert to
"SmartSerialization" if event data not serializable https://bugs.eclipse.org/bugs/show_bug.cgi?id=412186
Diffstat (limited to 'server-side')
-rw-r--r--server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/META-INF/MANIFEST.MF3
-rw-r--r--server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/internal/remoteservice/eventadmin/DefaultSerializationHandler.java50
-rw-r--r--server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/DistributedEventAdmin.java48
-rw-r--r--server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/EventMessage.java35
-rw-r--r--server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/serialization/SerializationHandler.java29
5 files changed, 157 insertions, 8 deletions
diff --git a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/META-INF/MANIFEST.MF b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/META-INF/MANIFEST.MF
index a60680409..f86800d82 100644
--- a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/META-INF/MANIFEST.MF
+++ b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/META-INF/MANIFEST.MF
@@ -17,4 +17,5 @@ Import-Package: org.eclipse.ecf.core.sharedobject,
Require-Bundle: org.eclipse.equinox.common,
org.eclipse.ecf
Export-Package: org.eclipse.ecf.internal.remoteservice.eventadmin;x-internal:=true,
- org.eclipse.ecf.remoteservice.eventadmin;version="1.1.100"
+ org.eclipse.ecf.remoteservice.eventadmin;version="1.1.100",
+ org.eclipse.ecf.remoteservice.eventadmin.serialization
diff --git a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/internal/remoteservice/eventadmin/DefaultSerializationHandler.java b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/internal/remoteservice/eventadmin/DefaultSerializationHandler.java
new file mode 100644
index 000000000..4331f7b82
--- /dev/null
+++ b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/internal/remoteservice/eventadmin/DefaultSerializationHandler.java
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * Copyright (c) 2013 Markus Alexander Kuppe and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.ecf.internal.remoteservice.eventadmin;
+
+import java.io.Externalizable;
+import java.io.NotSerializableException;
+import java.io.Serializable;
+
+import org.eclipse.ecf.remoteservice.eventadmin.serialization.SerializationHandler;
+
+/**
+ * The default is to serialize what is already serialized or externalizable
+ * and fail fast for the rest
+ */
+public class DefaultSerializationHandler extends SerializationHandler {
+
+ public static final SerializationHandler INST = new DefaultSerializationHandler();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.remoteservice.eventadmin.serialization.SmartSerializationHandler#serialize(java.lang.Object)
+ */
+ public Object serialize(Object val) throws NotSerializableException {
+ if (!(val instanceof Serializable || val instanceof Externalizable)) {
+ throw new NotSerializableException("Cannot serialize property value="+val);
+ }
+ return val;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.remoteservice.eventadmin.serialization.SmartSerializationHandler#deserialize(java.lang.Object)
+ */
+ public Object deserialize(Object val) {
+ return super.deserialize(val);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ecf.remoteservice.eventadmin.serialization.SerializationHandler#getTopic()
+ */
+ public Object getTopic() {
+ return "/ECF__NoSuchTopicNoSuchName__ECF/"; // invalid characters will make sure that topic is unique
+ }
+}
diff --git a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/DistributedEventAdmin.java b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/DistributedEventAdmin.java
index dcd74ccce..5bfb8219c 100644
--- a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/DistributedEventAdmin.java
+++ b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/DistributedEventAdmin.java
@@ -16,9 +16,11 @@ import java.io.IOException;
import java.io.NotSerializableException;
import java.security.Permission;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
@@ -28,9 +30,11 @@ import org.eclipse.ecf.core.sharedobject.BaseSharedObject;
import org.eclipse.ecf.core.sharedobject.SharedObjectMsg;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectCreateResponseEvent;
import org.eclipse.ecf.core.sharedobject.events.ISharedObjectMessageEvent;
+import org.eclipse.ecf.internal.remoteservice.eventadmin.DefaultSerializationHandler;
import org.eclipse.ecf.internal.remoteservice.eventadmin.EventHandlerTracker;
import org.eclipse.ecf.internal.remoteservice.eventadmin.EventHandlerWrapper;
import org.eclipse.ecf.internal.remoteservice.eventadmin.LogTracker;
+import org.eclipse.ecf.remoteservice.eventadmin.serialization.SerializationHandler;
import org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap;
import org.eclipse.osgi.framework.eventmgr.EventManager;
import org.eclipse.osgi.framework.eventmgr.ListenerQueue;
@@ -62,12 +66,15 @@ public class DistributedEventAdmin extends BaseSharedObject implements
private LogService log;
private EventManager eventManager;
private ServiceTracker etfServiceTracker;
+ private ServiceTracker shServiceTracker;
private final Set eventFilters = new HashSet();
+ private final Map topic2serializationHandler = new HashMap();
private static final String SHARED_OBJECT_MESSAGE_METHOD = "__handlePostEventSharedObjectMsg";
/**
* @since 1.2
+ * @noreference This field is not intended to be referenced by clients.
*/
protected EventHandlerTracker eventHandlerTracker;
/**
@@ -159,6 +166,27 @@ public class DistributedEventAdmin extends BaseSharedObject implements
}
});
etfServiceTracker.open();
+
+ // SerializationHandler are responsible to handle serialization of Event properties
+ shServiceTracker = new ServiceTracker(this.context, SerializationHandler.class, new ServiceTrackerCustomizer() {
+ public Object addingService(ServiceReference reference) {
+ final SerializationHandler sh = (SerializationHandler) context.getService(reference);
+ topic2serializationHandler.put(sh.getTopic(), sh);
+ return sh;
+ }
+
+ public void modifiedService(ServiceReference reference,
+ Object service) {
+ // nop
+ }
+
+ public void removedService(ServiceReference reference,
+ Object service) {
+ final SerializationHandler sh = (SerializationHandler) service;
+ topic2serializationHandler.remove(sh.getTopic());
+ }
+ });
+ shServiceTracker.open();
}
/**
@@ -178,6 +206,10 @@ public class DistributedEventAdmin extends BaseSharedObject implements
etfServiceTracker.close();
etfServiceTracker = null;
}
+ if (shServiceTracker != null) {
+ shServiceTracker.close();
+ shServiceTracker = null;
+ }
}
/**
@@ -310,11 +342,22 @@ public class DistributedEventAdmin extends BaseSharedObject implements
*/
protected Object[] createMessageDataFromEvent(ID target, Event eventToSend)
throws NotSerializableException {
- Object[] results = { new EventMessage(eventToSend) };
+ final Object[] results = { new EventMessage(eventToSend, getSerializationHandler(eventToSend.getTopic())) };
return results;
}
/**
+ * @since 1.2
+ */
+ protected SerializationHandler getSerializationHandler(String topic) {
+ final SerializationHandler sh = (SerializationHandler) topic2serializationHandler.get(topic);
+ if (sh == null) {
+ return DefaultSerializationHandler.INST;
+ }
+ return sh;
+ }
+
+ /**
* Create a local {@link Event} from deserialized messageData. The fromID
* will be a non-<code>null</code> {@link ID} instance that is the container
* ID of the sender DistributedEventAdmin. The default implementation
@@ -338,7 +381,8 @@ public class DistributedEventAdmin extends BaseSharedObject implements
* @since 1.1
*/
protected Event createEventFromMessageData(ID fromID, Object[] messageData) {
- EventMessage eventMessage = (EventMessage) messageData[0];
+ final EventMessage eventMessage = (EventMessage) messageData[0];
+ eventMessage.setSerializationHandler(getSerializationHandler(eventMessage.getTopic()));
return eventMessage.getEvent();
}
diff --git a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/EventMessage.java b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/EventMessage.java
index 21fb3a63d..a5f6479dd 100644
--- a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/EventMessage.java
+++ b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/EventMessage.java
@@ -10,12 +10,15 @@
*****************************************************************************/
package org.eclipse.ecf.remoteservice.eventadmin;
-import java.io.Externalizable;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
+import org.eclipse.ecf.internal.remoteservice.eventadmin.DefaultSerializationHandler;
+import org.eclipse.ecf.remoteservice.eventadmin.serialization.SerializationHandler;
import org.osgi.service.event.Event;
/**
@@ -27,6 +30,7 @@ public class EventMessage implements Serializable {
private String topic;
private Map properties;
+ private transient SerializationHandler sh = new DefaultSerializationHandler();
private transient Event localEvent;
public EventMessage(Event event)
@@ -34,6 +38,16 @@ public class EventMessage implements Serializable {
this.topic = event.getTopic();
this.properties = createPropertiesFromEvent(event);
}
+
+ /**
+ * @since 1.2
+ */
+ public EventMessage(Event event,
+ SerializationHandler serializationHandler) throws NotSerializableException {
+ this.sh = serializationHandler;
+ this.topic = event.getTopic();
+ this.properties = createPropertiesFromEvent(event);
+ }
public EventMessage(String topic, Map properties) {
this.topic = topic;
@@ -47,9 +61,7 @@ public class EventMessage implements Serializable {
: new Hashtable(propertyNames.length);
for (int i = 0; i < propertyNames.length; i++) {
Object val = event.getProperty(propertyNames[i]);
- if (!(val instanceof Serializable || val instanceof Externalizable))
- throw new NotSerializableException("Cannot serialize property value of name="+propertyNames[i]+" and value="+val);
- ht.put(propertyNames[i], val);
+ ht.put(propertyNames[i], sh.serialize(val));
}
return ht;
}
@@ -59,6 +71,12 @@ public class EventMessage implements Serializable {
}
protected Map getProperties() {
+ final Set keySet = properties.keySet();
+ for (final Iterator itr = keySet.iterator(); itr.hasNext();) {
+ final Object key = (Object) itr.next();
+ final Object val = properties.get(key);
+ properties.put(key, sh.deserialize(val));
+ }
return properties;
}
@@ -82,5 +100,12 @@ public class EventMessage implements Serializable {
buffer.append("]");
return buffer.toString();
}
-
+
+ /**
+ * @since 1.2
+ */
+ public void setSerializationHandler(
+ SerializationHandler serializationHandler) {
+ this.sh = serializationHandler;
+ }
}
diff --git a/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/serialization/SerializationHandler.java b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/serialization/SerializationHandler.java
new file mode 100644
index 000000000..2def157d8
--- /dev/null
+++ b/server-side/bundles/org.eclipse.ecf.remoteservice.eventadmin/src/org/eclipse/ecf/remoteservice/eventadmin/serialization/SerializationHandler.java
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * Copyright (c) 2013 Markus Alexander Kuppe and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Alexander Kuppe - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.ecf.remoteservice.eventadmin.serialization;
+
+import java.io.NotSerializableException;
+
+/**
+ * @since 1.2
+ */
+public abstract class SerializationHandler {
+ public Object serialize(Object val) throws NotSerializableException {
+ return val;
+ }
+
+ public Object deserialize(Object val) {
+ return val;
+ }
+
+
+ public abstract Object getTopic();
+}

Back to the top