A script service object needs to be serialized/deserialized in one of the following cases:

  • When the object will participate in groovy closures. A groovy closure represents groovy code that is invoked after an asynchronous action execution has finished.

  • When the object represents an event used for Functional Rule Triggers. The events need to be transferred between RM backend hosts.

Object serialization can be realized through one of the following ways:
•   java.io.Serializable – when the object data is represented only by a Java object (String, double, int, etc).
•   com.prosyst.util.io.Externalizable – when the object data contains RM specific objects.
•   com.prosyst.mprm.backend.rules.spi.io.ScriptSerializable – when there is a need to use a reference to the script service.
•   com.prosyst.mprm.util.externalizable.ObjectSteramer – when a special class for serialization is needed.

The Camera Manager returns an object from type Camera in its getCamera() method. If we want to use the Camera object into a closure, the interface Camera must be serialized. If we are not going to use the Camera objects into a closures, then we can skip the object serialization.

The Camera object will be able to send messages to the real camera by using the script service context, so we will serialize it by implementing the ScriptSerializable interface. The ScriptSerializable interface has a single method public String getScriptSerializerType(), which has to return the serializer type.

package com.prosyst.mprm.demos.rules;
 
import com.prosyst.mprm.backend.rules.spi.io.ScriptSerializable;
 
// the Camera object will use a reference to the script service and will participate
// in groovy closures, that's why we use ScriptSerializable
public interface Camera extends ScriptSerializable {
  ...
}

The Camera implementation:

package com.prosyst.mprm.demos.rules.impl;
 
import com.prosyst.mprm.demos.rules.Camera;
 
public class CameraImpl implements Camera {
  ...
 
  // the obligatory constructor
  public CameraImpl() {
    
  }
 
  // must return the serializer type
  public String getScriptSerializerType() {
    return CameraSerializer.TYPE;
  }
 
}


The serializer itself has to implement com.prosyst.mprm.backend.rules.spi.io.ScriptSerializer methods:

  • void serializeObject(Object obj, DataOutputStream outputStream) throws IOException

  • Object deserializeObject(DataInputStream inputStream) throws IOException

getSerializerType() of the serialized object must return the type of the object serializer. The serialization is custom so the interface com.prosyst.mprm.backend.rules.spi.io.ScriptSerializer has to be implemented.

package com.prosyst.mprm.demos.rules.impl;
 
...
import com.prosyst.mprm.backend.rules.spi.io.ScriptSerializer;
import com.prosyst.mprm.demos.rules.Camera;
import com.prosyst.mprm.util.externalizable.StringStreamer;
 
public class CameraSerializer implements ScriptSerializer {
 
  // the serializer type that Camera getSerializerType() points to
  public static final String TYPE = "rules.demo.service.camera";
 
  // the method that will serialize the Camera object
  public void serializeObject(Object obj, DataOutputStream outputStream) throws IOException {
    if (!(obj instanceof Camera)) {
      Logger.error("Failed to serialized a Camera object! Unknown object class \'" + obj.getClass() + "\'!");
      return;
    }
 
    Camera camera = (Camera)obj;
    // writing the camera id into the stream
    StringStreamer.writeString(outputStream, camera.getId());
  }
 
  // the method that will deserialize the Camera object
  public Object deserializeObject(DataInputStream inputStream) throws IOException {
    // redaing the camera id from the stream
    String cameraId = StringStreamer.readString(inputStream);
    return new CameraImpl(cameraId);
  }
}


The serializer has to be registered as OSGi service with registration property ScriptSerializer.SERIALIZER_TYPE:

...
public class Activator implements BundleActivator {
  ...
// method to register the serializer
private void registerSerializer() {
    CameraSerializer serializer = new CameraSerializer();
    Dictionary<String, Object> props = new Hashtable<String, Object>(1);
    // setting the mandatory serializer type service registration property
    props.put(ScriptSerializer.SERIALIZER_TYPE, CameraSerializer.TYPE);
    // making the service registration
    serializerReg = bc.registerService(ScriptSerializer.class.getName(), serializer, props);
  }
  ...
}


Camera camera1 = cm.getCamera('camera1');
Closure c = {camera1.getId()};
Camera camera2 =cm.getCamera('camera2', c);