You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by at...@apache.org on 2016/01/02 23:20:53 UTC
commons-scxml git commit: SCXML-247: dedicated
SCInstanceObjectInputStream to support proper dynamic class resolution in
GroovyContext - see https://issues.apache.org/jira/browse/SCXML-247 for
details - GroovyContext now can use the 'root' (SCInstance)Ob
Repository: commons-scxml
Updated Branches:
refs/heads/master 29402ee97 -> 5faba6798
SCXML-247: dedicated SCInstanceObjectInputStream to support proper dynamic class resolution in GroovyContext
- see https://issues.apache.org/jira/browse/SCXML-247 for details
- GroovyContext now can use the 'root' (SCInstance)ObjectInputStream for dynamic Groovy class resolving
- tested through SerializableInitialBaseScriptTest (unmodified, but again validates new implementation works too)
Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/5faba679
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/5faba679
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/5faba679
Branch: refs/heads/master
Commit: 5faba67982689543f69fd316c38f16b7ce39225b
Parents: 29402ee
Author: Ate Douma <at...@apache.org>
Authored: Sat Jan 2 23:20:46 2016 +0100
Committer: Ate Douma <at...@apache.org>
Committed: Sat Jan 2 23:20:46 2016 +0100
----------------------------------------------------------------------
.../scxml2/SCInstanceObjectInputStream.java | 96 ++++++++++++++++++++
.../scxml2/env/groovy/GroovyContext.java | 28 +++---
.../apache/commons/scxml2/SCXMLTestHelper.java | 2 +-
3 files changed, 109 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/5faba679/src/main/java/org/apache/commons/scxml2/SCInstanceObjectInputStream.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/SCInstanceObjectInputStream.java b/src/main/java/org/apache/commons/scxml2/SCInstanceObjectInputStream.java
new file mode 100644
index 0000000..3c0659c
--- /dev/null
+++ b/src/main/java/org/apache/commons/scxml2/SCInstanceObjectInputStream.java
@@ -0,0 +1,96 @@
+/*
+ * 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.commons.scxml2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+
+/**
+ * Extended ObjectInputStream to be used for de-serializing SCInstance.
+ * <p>
+ * This class allows configuring a custom {@link ClassResolver} callback to dynamically resolve a deserialization class,
+ * which is needed for SCXML languages like Groovy which need to dynamically lookup custom Groovy classes.
+ * </p>
+ */
+public class SCInstanceObjectInputStream extends ObjectInputStream {
+
+ /** ClassResolver Callback interface */
+ public interface ClassResolver {
+
+ /**
+ * Callback method invoked from {@link SCInstanceObjectInputStream#resolveClass(ObjectStreamClass)}
+ * @param osc an instance of class ObjectStreamClass
+ * @return a Class object corresponding to osc
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException;
+ }
+
+ /**
+ * current classresolver callback
+ */
+ private ClassResolver classResolver;
+
+ /**
+ * Default constructor
+ * @param in Inputstream to use
+ * @throws IOException
+ */
+ public SCInstanceObjectInputStream(final InputStream in) throws IOException {
+ super(in);
+ }
+
+ /**
+ * Set custom class resolver callback, or null when no longer needed.
+ * <p>
+ * Typically usage:
+ * <pre><code>
+ * private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
+ * ClassResolver currentClassResolver = null;
+ * try {
+ * if (in instanceof SCInstanceObjectInputStream) {
+ * currentClassResolver = ((SCInstanceObjectInputStream)in).setClassResolver(customClassResolver);
+ * }
+ * ... // read Object(s)
+ * }
+ * finally {
+ * if (in instanceof SCInstanceObjectInputStream) {
+ * ((SCInstanceObjectInputStream)in).setClassResolver(currentClassResolver);
+ * }
+ * }
+ * }
+ * </code></pre>
+ * </p>
+ * @see org.apache.commons.scxml2.env.groovy.GroovyContext#readObject(ObjectInputStream)
+ * @param classResolver custom class resolver
+ */
+ public ClassResolver setClassResolver(ClassResolver classResolver) {
+ ClassResolver old = this.classResolver;
+ this.classResolver = classResolver;
+ return old;
+ }
+
+ protected Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
+ if (classResolver != null) {
+ return classResolver.resolveClass(osc);
+ }
+ return super.resolveClass(osc);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/5faba679/src/main/java/org/apache/commons/scxml2/env/groovy/GroovyContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/env/groovy/GroovyContext.java b/src/main/java/org/apache/commons/scxml2/env/groovy/GroovyContext.java
index 9799216..d2526f6 100644
--- a/src/main/java/org/apache/commons/scxml2/env/groovy/GroovyContext.java
+++ b/src/main/java/org/apache/commons/scxml2/env/groovy/GroovyContext.java
@@ -18,18 +18,16 @@ package org.apache.commons.scxml2.env.groovy;
import groovy.lang.Closure;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.ObjectStreamClass;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.scxml2.Context;
+import org.apache.commons.scxml2.SCInstanceObjectInputStream;
import org.apache.commons.scxml2.env.SimpleContext;
/**
@@ -133,9 +131,7 @@ public class GroovyContext extends SimpleContext {
out.writeObject(this.scriptBaseClass);
out.writeObject(this.evaluator);
out.writeObject(this.binding);
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- new ObjectOutputStream(bout).writeObject(this.vars);
- out.writeObject(bout.toByteArray());
+ out.writeObject(this.vars);
}
@SuppressWarnings("unchecked")
@@ -143,17 +139,17 @@ public class GroovyContext extends SimpleContext {
this.scriptBaseClass = (String)in.readObject();
this.evaluator = (GroovyEvaluator)in.readObject();
this.binding = (GroovyContextBinding)in.readObject();
- byte[] bytes = (byte[])in.readObject();
- if (evaluator != null) {
- this.vars = (Map<String, Object>)
- new ObjectInputStream(new ByteArrayInputStream(bytes)) {
- protected Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
- return Class.forName(osc.getName(), true, evaluator.getGroovyClassLoader());
- }
- }.readObject();
+ SCInstanceObjectInputStream.ClassResolver currentResolver = null;
+ try {
+ if (evaluator != null && in instanceof SCInstanceObjectInputStream) {
+ currentResolver = ((SCInstanceObjectInputStream)in).setClassResolver(osc -> Class.forName(osc.getName(), true, evaluator.getGroovyClassLoader()));
+ }
+ this.vars = (Map<String, Object>)in.readObject();
}
- else {
- this.vars = (Map<String, Object>)new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
+ finally {
+ if (in instanceof SCInstanceObjectInputStream) {
+ ((SCInstanceObjectInputStream)in).setClassResolver(currentResolver);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/5faba679/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java b/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java
index 3330cce..983bc7c 100644
--- a/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java
+++ b/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java
@@ -254,7 +254,7 @@ public class SCXMLTestHelper {
out.writeObject(exec.detachInstance());
out.close();
ObjectInputStream in =
- new ObjectInputStream(new FileInputStream(filename));
+ new SCInstanceObjectInputStream(new FileInputStream(filename));
exec.attachInstance((SCInstance) in.readObject());
in.close();
return exec;