Improvements to JaCObs Jackson serializer/deserializer
  - deserialization of channel proxies is now using public Jackson APIs only.
  - Channel garbage collection implemented.
  - HashSets replaced by LinkedHashSets in order to make the serialized form 
more deterministic.


Project: http://git-wip-us.apache.org/repos/asf/ode-jacob/repo
Commit: http://git-wip-us.apache.org/repos/asf/ode-jacob/commit/9c05eb2c
Tree: http://git-wip-us.apache.org/repos/asf/ode-jacob/tree/9c05eb2c
Diff: http://git-wip-us.apache.org/repos/asf/ode-jacob/diff/9c05eb2c

Branch: refs/heads/master
Commit: 9c05eb2c37abdb33365bb44cdd259b56df553ceb
Parents: 8736076
Author: Tammo van Lessen <[email protected]>
Authored: Fri May 3 01:36:23 2013 +0200
Committer: Tammo van Lessen <[email protected]>
Committed: Fri May 3 01:39:00 2013 +0200

----------------------------------------------------------------------
 .../org/apache/ode/jacob/CompositeProcess.java     |    4 +-
 .../java/org/apache/ode/jacob/ReceiveProcess.java  |    4 +-
 .../jacob/soup/jackson/ChannelProxySerializer.java |   14 ++-
 .../jackson/ContinuationValueInstantiator.java     |   52 -------
 .../soup/jackson/JacksonExecutionQueueImpl.java    |   81 +++++++++-
 .../JacobJacksonAnnotationIntrospector.java        |    2 +-
 .../soup/jackson/JacobTypeResolverBuilder.java     |   34 +---
 .../ode/jacob/soup/jackson/NullJsonGenerator.java  |  118 +++++++++++++++
 .../apache/ode/jacob/vpu/ExecutionQueueImpl.java   |   30 +++-
 .../ode/jacob/examples/helloworld/HelloWorld.java  |   18 ++-
 10 files changed, 254 insertions(+), 103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/CompositeProcess.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/ode/jacob/CompositeProcess.java 
b/src/main/java/org/apache/ode/jacob/CompositeProcess.java
index c1e5843..785fed0 100644
--- a/src/main/java/org/apache/ode/jacob/CompositeProcess.java
+++ b/src/main/java/org/apache/ode/jacob/CompositeProcess.java
@@ -20,13 +20,13 @@ package org.apache.ode.jacob;
 
 import java.lang.reflect.Method;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 
 @SuppressWarnings("serial")
 public final class CompositeProcess extends ChannelListener {
-    private Set<ChannelListener> processes = new HashSet<ChannelListener>();
+    private Set<ChannelListener> processes = new 
LinkedHashSet<ChannelListener>();
 
     public CompositeProcess() {
     }

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/ode/jacob/ReceiveProcess.java 
b/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
index eccfd09..70f9191 100644
--- a/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
+++ b/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
@@ -20,7 +20,7 @@ package org.apache.ode.jacob;
 
 import java.lang.reflect.Method;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 
@@ -53,7 +53,7 @@ public abstract class ReceiveProcess extends ChannelListener {
 
     public Set<Method> getImplementedMethods() {
         if (_implementedMethods == null) {
-            Set<Method> implementedMethods = new HashSet<Method>();
+            Set<Method> implementedMethods = new LinkedHashSet<Method>();
             ClassUtil.getImplementedMethods(implementedMethods, 
receiver.getClass());
             _implementedMethods = 
Collections.unmodifiableSet(implementedMethods);
         }

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java 
b/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
index 0817461..a3cee06 100644
--- 
a/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
+++ 
b/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
@@ -19,6 +19,8 @@
 package org.apache.ode.jacob.soup.jackson;
 
 import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 import org.apache.ode.jacob.Channel;
 import org.apache.ode.jacob.ChannelProxy;
@@ -34,6 +36,8 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 
 public class ChannelProxySerializer extends StdSerializer<ChannelProxy>{
 
+    private final Set<Integer> serializedChannels = new 
LinkedHashSet<Integer>();
+    
     protected ChannelProxySerializer() {
         super(ChannelProxy.class);
     }
@@ -61,8 +65,16 @@ public class ChannelProxySerializer extends 
StdSerializer<ChannelProxy>{
             SerializerProvider provider) throws JsonGenerationException, 
IOException {
         CommChannel commChannel = (CommChannel) 
ChannelFactory.getBackend((Channel)value);
         ClassNameIdResolver idResolver = new 
ClassNameIdResolver(provider.constructType(commChannel.getType()), 
provider.getTypeFactory());
+        Integer cid = (Integer)commChannel.getId();
         jgen.writeStringField("channelType", idResolver.idFromBaseType());
-        jgen.writeNumberField("channelId", (Integer)commChannel.getId());
+        jgen.writeNumberField("channelId", cid);
+
+        // save channel id for garbage collection
+        serializedChannels.add(cid);
+    }
+
+    public Set<Integer> getSerializedChannels() {
+        return serializedChannels;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
 
b/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
deleted file mode 100644
index d770ad1..0000000
--- 
a/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ode.jacob.soup.jackson;
-
-import java.lang.reflect.Method;
-
-import org.apache.ode.jacob.JacobObject;
-import org.apache.ode.jacob.soup.Continuation;
-
-import com.fasterxml.jackson.databind.DeserializationConfig;
-import com.fasterxml.jackson.databind.deser.CreatorProperty;
-import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
-import com.fasterxml.jackson.databind.deser.ValueInstantiator;
-
-public class ContinuationValueInstantiator extends ValueInstantiator {
-
-    @Override
-    public String getValueTypeDesc() {
-        return Continuation.class.getName();
-    }
-
-    @Override
-    public boolean canCreateFromObjectWith() {
-        return true;
-    }
-
-    @Override
-    public SettableBeanProperty[] getFromObjectArguments(
-            DeserializationConfig config) {
-        return  new CreatorProperty[] {
-                new CreatorProperty("_closure", 
config.constructType(JacobObject.class), null, null, null, 0, null),
-                new CreatorProperty("_method", 
config.constructType(Method.class), null, null, null, 1, null),
-                new CreatorProperty("_args", 
config.constructType(Object[].class), null, null, null, 2, null)};
-
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
index e0892df..fb08f10 100644
--- 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
+++ 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
@@ -19,14 +19,19 @@
 package org.apache.ode.jacob.soup.jackson;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 import org.apache.ode.jacob.Channel;
 import org.apache.ode.jacob.ChannelProxy;
 import org.apache.ode.jacob.soup.Continuation;
 import org.apache.ode.jacob.vpu.ExecutionQueueImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
@@ -35,11 +40,16 @@ import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.DeserializationConfig;
 import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
 import com.fasterxml.jackson.databind.MapperFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
 import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -51,20 +61,40 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
  */
 public class JacksonExecutionQueueImpl extends ExecutionQueueImpl {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(JacksonExecutionQueueImpl.class);
+    
        public JacksonExecutionQueueImpl() {
                super(null);
        }
        
     public static void configureMapper(ObjectMapper om) {
         
-        SimpleModule sm = new SimpleModule("jacobmodule");
-        sm.addSerializer(ChannelProxy.class, new ChannelProxySerializer());
+        SimpleModule sm = new SimpleModule("jacob", Version.unknownVersion());
+        
+        final ChannelProxySerializer cps = new ChannelProxySerializer();
+        
+        sm.addSerializer(ChannelProxy.class, cps);
         sm.addSerializer(Continuation.class, new ContinuationSerializer());
-        sm.addSerializer(JacksonExecutionQueueImpl.class, new 
ExecutionQueueImplSerializer());
+        sm.addSerializer(JacksonExecutionQueueImpl.class, new 
ExecutionQueueImplSerializer(cps));
         sm.addDeserializer(JacksonExecutionQueueImpl.class, new 
ExecutionQueueImplDeserializer());
         sm.addDeserializer(Continuation.class, new ContinuationDeserializer());
         sm.addDeserializer(Channel.class, new ChannelProxyDeserializer());
         
+        sm.setDeserializerModifier(new BeanDeserializerModifier() {
+
+            public JsonDeserializer<?> modifyDeserializer(
+                    DeserializationConfig config, BeanDescription beanDesc,
+                    JsonDeserializer<?> deserializer) {
+                
+                // use channel proxy deserializer for channels.
+                if (Channel.class.isAssignableFrom(beanDesc.getBeanClass()) && 
beanDesc.getBeanClass().isInterface()) {
+                    return new ChannelProxyDeserializer();
+                }
+
+                return super.modifyDeserializer(config, beanDesc, 
deserializer);
+            }
+        });
+        
         om.registerModule(sm);
         om.disable(MapperFeature.AUTO_DETECT_CREATORS);
         om.disable(MapperFeature.AUTO_DETECT_GETTERS);
@@ -82,8 +112,11 @@ public class JacksonExecutionQueueImpl extends 
ExecutionQueueImpl {
        
     public static class ExecutionQueueImplSerializer extends 
StdSerializer<JacksonExecutionQueueImpl> {
 
-        public ExecutionQueueImplSerializer() {
+        private ChannelProxySerializer channelProxySerializer;
+
+        public ExecutionQueueImplSerializer(ChannelProxySerializer cps) {
             super(JacksonExecutionQueueImpl.class);
+            this.channelProxySerializer = cps;
         }
         
         @Override
@@ -108,11 +141,44 @@ public class JacksonExecutionQueueImpl extends 
ExecutionQueueImpl {
         private void serializeContents(JacksonExecutionQueueImpl value, 
JsonGenerator jgen,
                 SerializerProvider provider) throws JsonGenerationException, 
IOException {
 
-               jgen.writeNumberField("objIdCounter", value._objIdCounter);
+            channelProxySerializer.getSerializedChannels().clear();
+            
+               // write metadata
+            jgen.writeNumberField("objIdCounter", value._objIdCounter);
             jgen.writeNumberField("currentCycle", value._currentCycle);
             
+            // write continuations
             jgen.writeObjectField("continuations", 
value._reactions.toArray(new Continuation[] {}));
+            
+            
+            // channel garbage collection
+            //   - traverse whole object graph and record referenced channel 
proxies.
+            //     - first, regularily serialize continuations.
+            //     - second, serialize channels to a null serializer in order 
to record channel references
+            //       without writing them to the stream.
+            //   - remove unused channels.
+            //   - serialize remaining channels.
+
+            // write channels to null serializer
+            JsonGenerator nullgen = new NullJsonGenerator(null, 0, 
jgen.getCodec());
+            nullgen.writeObjectField("channels", 
value._channels.values().toArray(new ChannelFrame[] {}));
+
+            // remove unreferenced channels (and keep those which have been 
exported using export()).
+            Set<Integer> referencedChannels = 
channelProxySerializer.getSerializedChannels();
+            for (Iterator<ChannelFrame> i = 
value._channels.values().iterator(); i.hasNext();) {
+                ChannelFrame cframe = i.next();
+                if (referencedChannels.contains(cframe.getId()) || 
cframe.getRefCount() > 0) {
+                    // skip
+                } else {
+                    LOG.debug("GC Channel: {}", cframe);
+                    i.remove();
+                }
+            }
+
+            // write channels
             jgen.writeObjectField("channels", 
value._channels.values().toArray(new ChannelFrame[] {}));
+            
+            // write global data
             jgen.writeObjectField("global", value._gdata);
         }
     }
@@ -152,13 +218,12 @@ public class JacksonExecutionQueueImpl extends 
ExecutionQueueImpl {
                     for (ChannelFrame f : frames) {
                         soup._channels.put(f.getId(), f);
                     }
+                } else if ("global".equals(fieldname)) {
+                    soup._gdata = jp.readValueAs(Serializable.class);
                 }
 
             }
 
-            // Garbage collection
-            // TODO
-
             return soup;
         }
 

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
index 0cb3a73..ba8b7b1 100644
--- 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
+++ 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
@@ -15,5 +15,5 @@ public class JacobJacksonAnnotationIntrospector extends
     public ObjectIdInfo findObjectIdInfo(Annotated ann) {
         return new ObjectIdInfo("@id", Object.class, 
ObjectIdGenerators.IntSequenceGenerator.class);
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
index b477fcd..8a14a71 100644
--- 
a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
+++ 
b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
@@ -40,7 +40,6 @@ import 
com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver;
 import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
 import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
 import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.fasterxml.jackson.databind.util.ClassUtil;
 
 public class JacobTypeResolverBuilder extends StdTypeResolverBuilder {
 
@@ -65,7 +64,15 @@ public class JacobTypeResolverBuilder extends 
StdTypeResolverBuilder {
         
         return useForType(baseType) ? super.buildTypeSerializer(config, 
baseType, subtypes) : null;
     }
+
     
+    @Override
+    public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
+            JavaType baseType, Collection<NamedType> subtypes) {
+        
+        return (useForType(baseType)) ? super.buildTypeDeserializer(config, 
baseType, subtypes) : null;
+    }
+
     private boolean useForType(JavaType t) {
         if (JacobObject.class.isAssignableFrom(t.getRawClass())) {
             return true;
@@ -82,18 +89,6 @@ public class JacobTypeResolverBuilder extends 
StdTypeResolverBuilder {
         return false;
     }
 
-    @Override
-    public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
-            JavaType baseType, Collection<NamedType> subtypes) {
-        
-        if (useForType(baseType)) {
-            // set Channel as the default impl.
-            defaultImpl(Channel.class);
-            return super.buildTypeDeserializer(config, baseType, subtypes);
-        }
-        
-        return null;
-    }
 
     public static class ChannelAwareTypeIdResolver extends TypeIdResolverBase {
 
@@ -119,18 +114,7 @@ public class JacobTypeResolverBuilder extends 
StdTypeResolverBuilder {
         }
 
         public JavaType typeFromId(String id) {
-            try {
-                Class<?> cls =  ClassUtil.findClass(id);
-                if (Channel.class.isAssignableFrom(cls) && cls.isInterface()) {
-                    // return null to force Jackson to use default 
deserializer (which is the ChannelProxyDeserializer)
-                    return null;
-                }
-                return _typeFactory.constructSpecializedType(_baseType, cls);
-            } catch (ClassNotFoundException e) {
-                throw new IllegalArgumentException("Invalid type id '"+id+"' 
(for id type 'Id.class'): no such class found");
-            } catch (Exception e) {
-                throw new IllegalArgumentException("Invalid type id '"+id+"' 
(for id type 'Id.class'): "+e.getMessage(), e);
-            }
+            return delegate.typeFromId(id);
         }
 
         public Id getMechanism() {

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java 
b/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java
new file mode 100644
index 0000000..08cd96a
--- /dev/null
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java
@@ -0,0 +1,118 @@
+package org.apache.ode.jacob.soup.jackson;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import com.fasterxml.jackson.core.Base64Variant;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.core.io.IOContext;
+import com.fasterxml.jackson.core.json.JsonGeneratorImpl;
+
+/**
+ * No-op Json generator.
+ * 
+ * @author vanto
+ *
+ */
+public class NullJsonGenerator extends JsonGeneratorImpl {
+
+    public NullJsonGenerator(IOContext ctxt, int features, ObjectCodec codec) {
+        super(ctxt, features, codec);
+    }
+
+    public void flush() throws IOException {
+    }
+
+    protected void _releaseBuffers() {
+    }
+
+    protected void _verifyValueWrite(String typeMsg) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeStartArray() throws IOException, JsonGenerationException {
+    }
+
+    public void writeEndArray() throws IOException, JsonGenerationException {
+    }
+
+    public void writeStartObject() throws IOException, JsonGenerationException 
{
+    }
+
+    public void writeEndObject() throws IOException, JsonGenerationException {
+    }
+
+    public void writeFieldName(String name) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeString(String text) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeString(char[] text, int offset, int len)
+            throws IOException, JsonGenerationException {
+    }
+
+    public void writeRawUTF8String(byte[] text, int offset, int length)
+            throws IOException, JsonGenerationException {
+    }
+
+    public void writeUTF8String(byte[] text, int offset, int length)
+            throws IOException, JsonGenerationException {
+    }
+
+    public void writeRaw(String text) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeRaw(String text, int offset, int len) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeRaw(char[] text, int offset, int len) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeRaw(char c) throws IOException, JsonGenerationException {
+    }
+
+    public void writeBinary(Base64Variant b64variant, byte[] data, int offset,
+            int len) throws IOException, JsonGenerationException {
+    }
+
+    public void writeNumber(int v) throws IOException, JsonGenerationException 
{
+    }
+
+    public void writeNumber(long v) throws IOException, 
JsonGenerationException {
+    }
+
+    public void writeNumber(BigInteger v) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeNumber(double d) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeNumber(float f) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeNumber(BigDecimal dec) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeNumber(String encodedValue) throws IOException,
+            JsonGenerationException, UnsupportedOperationException {
+    }
+
+    public void writeBoolean(boolean state) throws IOException,
+            JsonGenerationException {
+    }
+
+    public void writeNull() throws IOException, JsonGenerationException {
+    }
+}

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java 
b/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
index fff2ae1..a6c0837 100644
--- a/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
+++ b/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
@@ -30,9 +30,10 @@ import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
@@ -80,9 +81,9 @@ public class ExecutionQueueImpl implements ExecutionQueue {
      * forward progress; this scenario would occur if a maximum processign
      * time-per-instance policy were in effect.
      */
-    protected Set<Continuation> _reactions = new HashSet<Continuation>();
+    protected Set<Continuation> _reactions = new LinkedHashSet<Continuation>();
 
-    protected Map<Integer, ChannelFrame> _channels = new HashMap<Integer, 
ChannelFrame>();
+    protected Map<Integer, ChannelFrame> _channels = new 
LinkedHashMap<Integer, ChannelFrame>();
 
     /**
      * The "expected" cycle counter, use to detect database serialization
@@ -96,7 +97,7 @@ public class ExecutionQueueImpl implements ExecutionQueue {
 
     protected Serializable _gdata;
 
-    private Map<Object, LinkedList<IndexedObject>> _index = new 
HashMap<Object, LinkedList<IndexedObject>>();
+    private Map<Object, LinkedList<IndexedObject>> _index = new 
LinkedHashMap<Object, LinkedList<IndexedObject>>();
 
     public ExecutionQueueImpl(ClassLoader classLoader) {
         _classLoader = classLoader;
@@ -454,9 +455,9 @@ public class ExecutionQueueImpl implements ExecutionQueue {
 
         boolean replicatedRecv;
 
-        Set<ObjectFrame> objFrames = new HashSet<ObjectFrame>();
+        Set<ObjectFrame> objFrames = new LinkedHashSet<ObjectFrame>();
 
-        Set<MessageFrame> msgFrames = new HashSet<MessageFrame>();
+        Set<MessageFrame> msgFrames = new LinkedHashSet<MessageFrame>();
 
         public String description;
 
@@ -473,6 +474,18 @@ public class ExecutionQueueImpl implements ExecutionQueue {
         public Integer getId() {
             return Integer.valueOf(id);
         }
+        
+        public int getRefCount() {
+            return refCount;
+        }
+        
+        public Set<ObjectFrame> getObjFrames() {
+            return objFrames;
+        }
+
+        public Set<MessageFrame> getMsgFrames() {
+            return msgFrames;
+        }
 
         public void readExternal(ObjectInput in) throws IOException, 
ClassNotFoundException {
             type = (Class<?>)in.readObject();
@@ -535,7 +548,7 @@ public class ExecutionQueueImpl implements ExecutionQueue {
     @SuppressWarnings("serial")
     protected static class CommGroupFrame implements Serializable {
         boolean replicated;
-        public Set<CommFrame> commFrames = new HashSet<CommFrame>();
+        public Set<CommFrame> commFrames = new LinkedHashSet<CommFrame>();
 
         // default constructor for deserialization
         public CommGroupFrame() {}
@@ -593,14 +606,13 @@ public class ExecutionQueueImpl implements ExecutionQueue 
{
         }
     }
 
-    private static class MessageFrame extends CommFrame implements 
Externalizable {
+    protected static class MessageFrame extends CommFrame implements 
Externalizable {
         private static final long serialVersionUID = -1112437852498126297L;
 
         String method;
         Object[] args;
 
         // Used for deserialization
-        @SuppressWarnings("unused")
         public MessageFrame() {
         }
 

http://git-wip-us.apache.org/repos/asf/ode-jacob/blob/9c05eb2c/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java 
b/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
index 524d350..053d049 100644
--- a/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
+++ b/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
@@ -30,6 +30,8 @@ import org.apache.ode.jacob.vpu.JacobVPU;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.smile.SmileFactory;
+import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
 
 /**
  * Simple Hello World example to showcase different
@@ -254,13 +256,23 @@ public class HelloWorld extends JacobRunnable {
     public static void main(String args[]) throws Exception {
         // enable logging
         //BasicConfigurator.configure();
-        long start = System.currentTimeMillis();
-        ObjectMapper mapper = new ObjectMapper(); 
+        
+        SmileFactory sf = null; 
+        // // enable smile:
+        // sf = new SmileFactory();
+        // sf.enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES);
+        // sf.enable(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT);
+        
+        ObjectMapper mapper = new ObjectMapper(sf); 
+        
+        
         JacksonExecutionQueueImpl.configureMapper(mapper);
 
         JacobVPU vpu = new JacobVPU();
         JacksonExecutionQueueImpl queue = new JacksonExecutionQueueImpl();
         vpu.setContext(queue);
+
+        long start = System.currentTimeMillis();
         vpu.inject(new HelloWorld());
         while (vpu.execute()) {
             queue = loadAndRestoreQueue(mapper, 
(JacksonExecutionQueueImpl)vpu.getContext());
@@ -268,8 +280,8 @@ public class HelloWorld extends JacobRunnable {
             System.out.println(vpu.isComplete() ? "<0>" : ".");
             //vpu.dumpState();
         }
-        vpu.dumpState();
         System.out.println("Runtime in ms: " + (System.currentTimeMillis() - 
start));
+        vpu.dumpState();
     }
 
     public static JacksonExecutionQueueImpl loadAndRestoreQueue(ObjectMapper 
mapper, JacksonExecutionQueueImpl in) throws Exception {

Reply via email to