001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.flow;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: import org.apache.avalon.framework.service.ServiceException;
024: import org.apache.avalon.framework.service.ServiceManager;
025: import org.apache.excalibur.source.Source;
026: import org.apache.excalibur.source.SourceResolver;
027: import org.mozilla.javascript.Context;
028: import org.mozilla.javascript.Script;
029: import org.mozilla.javascript.Scriptable;
030:
031: /**
032: * This is a base class for all interpreters compiling the scripts
033: *
034: * @author <a href="mailto:ovidiu@apache.org">Ovidiu Predescu</a>
035: * @author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
036: * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
037: * @version CVS $Id: CompilingInterpreter.java 494773 2007-01-10 09:24:02Z cziegeler $
038: */
039: public abstract class CompilingInterpreter extends AbstractInterpreter {
040:
041: /**
042: * A source resolver
043: */
044: protected SourceResolver sourceresolver;
045:
046: /**
047: * Mapping of String objects (source uri's) to ScriptSourceEntry's
048: */
049: protected Map compiledScripts = new HashMap();
050:
051: /**
052: * Composable
053: */
054: public void service(ServiceManager manager) throws ServiceException {
055: super .service(manager);
056: this .sourceresolver = (SourceResolver) this .manager
057: .lookup(SourceResolver.ROLE);
058: }
059:
060: /* (non-Javadoc)
061: * @see org.apache.avalon.framework.activity.Disposable#dispose()
062: */
063: public void dispose() {
064: if (this .compiledScripts != null) {
065: Iterator i = this .compiledScripts.values().iterator();
066: while (i.hasNext()) {
067: ScriptSourceEntry current = (ScriptSourceEntry) i
068: .next();
069: this .sourceresolver.release(current.getSource());
070: }
071: this .compiledScripts = null;
072: }
073: if (this .manager != null) {
074: this .manager.release(this .sourceresolver);
075: this .sourceresolver = null;
076: }
077: super .dispose();
078: }
079:
080: /**
081: * TODO - This is a little bit strange, the interpreter calls
082: * get Script on the ScriptSourceEntry which in turn
083: * calls compileScript on the interpreter. I think we
084: * need more refactoring here.
085: */
086: protected abstract Script compileScript(Context context,
087: Scriptable scope, Source source) throws Exception;
088:
089: // This class cannot be static
090: protected class ScriptSourceEntry {
091: final private Source source;
092: private Script script;
093: private long compileTime;
094:
095: public ScriptSourceEntry(Source source) {
096: this .source = source;
097: }
098:
099: public ScriptSourceEntry(Source source, Script script, long t) {
100: this .source = source;
101: this .script = script;
102: this .compileTime = t;
103: }
104:
105: public Source getSource() {
106: return source;
107: }
108:
109: public long getCompileTime() {
110: return compileTime;
111: }
112:
113: public Script getScript(Context context, Scriptable scope,
114: boolean refresh, CompilingInterpreter interpreter)
115: throws Exception {
116: if (refresh) {
117: source.refresh();
118: }
119: if (script == null
120: || (refresh && compileTime < source
121: .getLastModified())) {
122: script = interpreter.compileScript(context, scope,
123: source);
124: compileTime = source.getLastModified();
125: }
126: return script;
127: }
128: }
129: }
|