1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml2.env.groovy;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.io.ObjectStreamClass;
25 import java.util.Iterator;
26 import java.util.Map;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.commons.scxml2.Context;
31 import org.apache.commons.scxml2.env.SimpleContext;
32
33 import groovy.lang.Closure;
34
35
36
37
38 public class GroovyContext extends SimpleContext {
39
40 private static final long serialVersionUID = 1L;
41
42 private static final Log log = LogFactory.getLog(GroovyContext.class);
43
44 private String scriptBaseClass;
45 private GroovyEvaluator evaluator;
46 private GroovyContextBinding binding;
47 private Map<String, Object> vars;
48
49 GroovyContextBinding getBinding() {
50 if (binding == null) {
51 binding = new GroovyContextBinding(this);
52 }
53 return binding;
54 }
55
56
57
58
59 public GroovyContext() {
60 super();
61 }
62
63
64
65
66
67
68 public GroovyContext(final Context parent, final Map<String, Object> initialVars, GroovyEvaluator evaluator) {
69 super(parent, initialVars);
70 this.evaluator = evaluator;
71 }
72
73
74
75
76
77
78 public GroovyContext(final Context parent, GroovyEvaluator evaluator) {
79 super(parent);
80 this.evaluator = evaluator;
81 }
82
83 protected GroovyEvaluator getGroovyEvaluator() {
84 return evaluator;
85 }
86
87 protected void setGroovyEvaluator(GroovyEvaluator evaluator) {
88 this.evaluator = evaluator;
89 }
90
91 @Override
92 public Map<String, Object> getVars() {
93 return vars;
94 }
95
96 @Override
97 protected void setVars(final Map<String, Object> vars) {
98 this.vars = vars;
99 }
100
101 protected void setScriptBaseClass(String scriptBaseClass) {
102 this.scriptBaseClass = scriptBaseClass;
103 }
104
105 protected String getScriptBaseClass() {
106 if (scriptBaseClass != null) {
107 return scriptBaseClass;
108 }
109 if (getParent() instanceof GroovyContext) {
110 return ((GroovyContext)getParent()).getScriptBaseClass();
111 }
112 return null;
113 }
114
115 private void writeObject(ObjectOutputStream out) throws IOException {
116 boolean closureErased = false;
117 if (vars != null) {
118 Iterator<Map.Entry<String, Object>> iterator = getVars().entrySet().iterator();
119 while (iterator.hasNext()) {
120 Map.Entry<String, Object> entry = iterator.next();
121 if (entry.getValue() != null && entry.getValue() instanceof Closure) {
122 iterator.remove();
123 closureErased = true;
124 }
125 }
126 if (closureErased) {
127 log.warn("Encountered and removed Groovy Closure(s) in the GroovyContext during serialization: these are not supported for (de)serialization");
128 }
129 }
130 out.writeObject(this.scriptBaseClass);
131 out.writeObject(this.evaluator);
132 out.writeObject(this.binding);
133 ByteArrayOutputStream bout = new ByteArrayOutputStream();
134 new ObjectOutputStream(bout).writeObject(this.vars);
135 out.writeObject(bout.toByteArray());
136 }
137
138 @SuppressWarnings("unchecked")
139 private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
140 this.scriptBaseClass = (String)in.readObject();
141 this.evaluator = (GroovyEvaluator)in.readObject();
142 this.binding = (GroovyContextBinding)in.readObject();
143 byte[] bytes = (byte[])in.readObject();
144 if (evaluator != null) {
145 this.vars = (Map<String, Object>)
146 new ObjectInputStream(new ByteArrayInputStream(bytes)) {
147 protected Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
148 return Class.forName(osc.getName(), true, evaluator.getGroovyClassLoader());
149 }
150 }.readObject();
151 }
152 else {
153 this.vars = (Map<String, Object>)new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
154 }
155 }
156 }