View Javadoc

1   /*$Id: GroovyInterpreterFactory.java,v 1.7 2005/04/25 12:13:54 clq2 Exp $
2    * Created on 14-May-2004
3    *
4    * Copyright (C) AstroGrid. All rights reserved.
5    *
6    * This software is published under the terms of the AstroGrid 
7    * Software License version 1.2, a copy of which has been included 
8    * with this distribution in the LICENSE.txt file.  
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         // see if its already there first..
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         //StringWriter writer = new StringWriter();
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         // finally cache it too.
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) { // found a match in the cache - that's enough
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  * $Log: GroovyInterpreterFactory.java,v $
185  * Revision 1.7  2005/04/25 12:13:54  clq2
186  * jes-nww-776-again
187  *
188  * Revision 1.6.56.1  2005/04/12 17:08:15  nw
189  * caching to improve performance
190  * Revision 1.6 2004/11/05 16:52:42 jdt
191  * Merges from branch nww-itn07-scratchspace
192  * 
193  * Revision 1.5.18.1 2004/11/05 16:13:08 nw replaced stringWriter with
194  * TemporaryBuffer updated to work with new ruleStore
195  * 
196  * Revision 1.5 2004/09/16 21:47:56 nw made sure all streams are closed
197  * 
198  * Revision 1.4 2004/09/06 16:30:25 nw javadoc
199  * 
200  * Revision 1.3 2004/08/09 17:32:18 nw updated due to removing RuleStore
201  * 
202  * Revision 1.2 2004/07/30 15:42:34 nw merged in branch nww-itn06-bz#441 (groovy
203  * scripting)
204  * 
205  * Revision 1.1.2.2 2004/07/28 16:24:23 nw finished groovy beans. moved useful
206  * tests from old python package. removed python implemntation
207  * 
208  * Revision 1.1.2.1 2004/07/27 23:37:59 nw refactoed framework. experimented
209  * with betwixt - can't get it to work. got XStream working in 5 mins. about to
210  * remove betwixt code.
211  * 
212  * Revision 1.1.2.1 2004/07/26 15:51:19 nw first stab at a groovy scheduler.
213  * transcribed all the classes in the python prototype, and took copies of the
214  * classes in the 'scripting' package.
215  * 
216  * Revision 1.1 2004/07/09 09:30:28 nw merged in scripting workflow interpreter
217  * from branch nww-x-workflow-extensions
218  * 
219  * Revision 1.1.2.1 2004/05/21 11:25:19 nw first checkin of prototype scrpting
220  * workflow interpreter
221  *  
222  */