1
2
3
4
5
6
7
8
9
10
11 package org.astrogrid.jes.jobscheduler.impl.groovy;
12
13 import org.astrogrid.jes.util.Cache;
14 import org.astrogrid.jes.util.TemporaryBuffer;
15 import org.astrogrid.workflow.beans.v1.Workflow;
16 import org.astrogrid.workflow.beans.v1.execution.Extension;
17 import org.astrogrid.workflow.beans.v1.execution.JobURN;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 import java.io.Reader;
23 import java.io.StringReader;
24 import java.io.Writer;
25 import java.lang.ref.Reference;
26 import java.lang.ref.SoftReference;
27 import java.util.Map;
28
29 /***
30 * Factory object that takes care of creating fresh and unpickling existing
31 * groovy interpreters.
32 *
33 * @see GroovyInterpreter
34 * @author Noel Winstanley nw@jb.man.ac.uk 14-May-2004
35 */
36 public class GroovyInterpreterFactory {
37 /***
38 * interface to a component that actually performs the serialization /
39 * deserialization in some way.
40 *
41 * @author Noel Winstanley nw@jb.man.ac.uk 27-Jul-2004
42 *
43 */
44 public interface Pickler {
45
46 /***
47 * serialize / pickle an intepreter (i.e. all hte state of an executing
48 * workflow) to a writer
49 *
50 * @param out
51 * @param interp
52 * @throws Exception
53 */
54 void marshallInterpreter(Writer out, GroovyInterpreter interp) throws Exception;
55
56 /***
57 * unmarshal a previously pickled interpreter.
58 *
59 * @param in
60 * @return
61 * @throws Exception
62 */
63 GroovyInterpreter unmarshallInterpreter(Reader in) throws Exception;
64
65 /***
66 * unmarshal a previously pickled rulestore (subcomponent of an
67 * intepreter).
68 *
69 * @param reader
70 * @return
71 * @throws Exception
72 */
73 Map unmarshallRuleStore(Reader reader) throws Exception;
74 }
75
76 /*** construct a new factory, passing in the pickler implementatio to use */
77 public GroovyInterpreterFactory(Pickler p, TemporaryBuffer buff) {
78 this.pickler = p;
79 this.buff = new SoftReference(buff);
80 this.interpreterCache = new Cache(CACHE_SIZE);
81 }
82
83 protected final Pickler pickler;
84
85 protected Reference buff;
86
87 protected final Cache interpreterCache;
88
89 public static final int CACHE_SIZE = 5;
90
91 /*** so our buffer can be shared amongst friends.. */
92 public synchronized TemporaryBuffer getBuffer() {
93 TemporaryBuffer b = (TemporaryBuffer) buff.get();
94 if (b == null) {
95 b = new TemporaryBuffer();
96 buff = new SoftReference(b);
97 }
98 return b;
99 }
100
101 private static final Log log = LogFactory.getLog(GroovyInterpreterFactory.class);
102
103 /***
104 * key used in workflow extension to store pickled workflow.
105 */
106 public static final String EXTENSION_KEY = "pickled.groovy.interpreter";
107
108 static final String EXTENSION_XPATH = "jobExecutionRecord/extension[key='" + EXTENSION_KEY
109 + "']";
110
111 /*** write a groovy interpreter back into the extension fragment of a workflow */
112 public void pickleTo(GroovyInterpreter interp, Workflow wf) throws PickleException {
113
114 Extension pickleJar = (Extension) wf
115 .findXPathValue(GroovyInterpreterFactory.EXTENSION_XPATH);
116 if (pickleJar == null) {
117 pickleJar = new Extension();
118 pickleJar.setKey(GroovyInterpreterFactory.EXTENSION_KEY);
119
120 wf.getJobExecutionRecord().addExtension(pickleJar);
121 }
122
123 TemporaryBuffer buff = getBuffer();
124 buff.writeMode();
125 Writer writer = buff.getWriter();
126 try {
127 pickler.marshallInterpreter(writer, interp);
128 writer.close();
129 buff.readMode();
130 pickleJar.setContent(buff.getContents());
131 } catch (Exception e) {
132 throw new PickleException("Could not pickle interpreter", e);
133 }
134
135 interpreterCache.stuff(wf.getJobExecutionRecord().getJobId(), interp);
136
137 }
138
139 /***
140 * deserialize previously created workflow interpreter.
141 */
142 public GroovyInterpreter unpickleFrom(JesInterface env) throws PickleException {
143
144 Workflow workflow = env.getWorkflow();
145 JobURN urn = workflow.getJobExecutionRecord().getJobId();
146 GroovyInterpreter gi = (GroovyInterpreter) interpreterCache.check(urn);
147 if (gi != null) {
148 return gi;
149 }
150 Extension pickleJar = (Extension) workflow
151 .findXPathValue(GroovyInterpreterFactory.EXTENSION_XPATH);
152 StringReader sr = new StringReader(pickleJar.getContent());
153 try {
154 gi = pickler.unmarshallInterpreter(sr);
155 gi.setJesInterface(env);
156 return gi;
157 } catch (Exception e) {
158 throw new PickleException("Could not unpickle interpreter", e);
159 } finally {
160 sr.close();
161 }
162
163 }
164
165 /*** create a new workflow interpreter, populated with contents of rulesDoc */
166 public GroovyInterpreter newInterpreter(String rulesDoc, JesInterface env)
167 throws PickleException {
168 StringReader sr = new StringReader(rulesDoc);
169 try {
170 Map rs = pickler.unmarshallRuleStore(sr);
171 GroovyInterpreter interp = new GroovyInterpreter(rs);
172 interp.setJesInterface(env);
173 return interp;
174 } catch (Exception e) {
175 throw new PickleException("Could not create new interpreter", e);
176 } finally {
177 sr.close();
178 }
179 }
180
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222