View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.struts.flow.core;
17  
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import org.apache.struts.flow.core.source.Source;
23  import org.apache.struts.flow.core.source.SourceResolver;
24  import org.mozilla.javascript.Context;
25  import org.mozilla.javascript.Script;
26  import org.mozilla.javascript.Scriptable;
27  
28  /***
29   * This is a base class for all interpreters compiling the scripts
30   *
31   * @author <a href="mailto:ovidiu@apache.org">Ovidiu Predescu</a>
32   * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
33   * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
34   * @version CVS $Id: CompilingInterpreter.java 55850 2004-10-28 13:43:12Z vgritsenko $
35   */
36  public abstract class CompilingInterpreter
37          extends AbstractInterpreter {
38  
39      /***
40       * A source resolver
41       */
42      protected SourceResolver sourceresolver;
43  
44      /***
45       * Mapping of String objects (source uri's) to ScriptSourceEntry's
46       */
47      protected Map compiledScripts = new HashMap();
48  
49      
50      public CompilingInterpreter() {
51          super();
52      }
53      
54      public void setSourceResolver(SourceResolver r) {
55          this.sourceresolver = r;
56      }
57  
58      /* (non-Javadoc)
59       * @see org.apache.avalon.framework.activity.Disposable#dispose()
60       */
61      public void dispose() {
62          if (this.compiledScripts != null) {
63              Iterator i = this.compiledScripts.values().iterator();
64              while (i.hasNext()) {
65                  ScriptSourceEntry current = (ScriptSourceEntry)i.next();
66                  this.sourceresolver.release(current.getSource());
67              }
68              this.compiledScripts = null;
69          }
70         this.sourceresolver = null;
71      }
72  
73      /***
74       * TODO - This is a little bit strange, the interpreter calls
75       * get Script on the ScriptSourceEntry which in turn
76       * calls compileScript on the interpreter. I think we
77       * need more refactoring here.
78       */
79      protected abstract Script compileScript(Context context,
80                                              Scriptable scope,
81                                              Source source) throws Exception;
82  
83      protected class ScriptSourceEntry {
84          final private Source source;
85          private Script script;
86          private long compileTime;
87  
88          public ScriptSourceEntry(Source source) {
89              this.source = source;
90          }
91  
92          public ScriptSourceEntry(Source source, Script script, long t) {
93              this.source = source;
94              this.script = script;
95              this.compileTime = t;
96          }
97  
98          public Source getSource() {
99              return source;
100         }
101 
102         public Script getScript(Context context, Scriptable scope,
103                                 boolean refresh, CompilingInterpreter interpreter)
104         throws Exception {
105             if (refresh) {
106                 source.refresh();
107             }
108             if (script == null || compileTime < source.getLastModified()) {
109                 script = interpreter.compileScript(context, scope, source);
110                 compileTime = source.getLastModified();
111             }
112             return script;
113         }
114     }
115 }