001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry.engine;
016
017import java.util.HashMap;
018import java.util.Map;
019
020import org.apache.hivemind.ApplicationRuntimeException;
021import org.apache.hivemind.ClassResolver;
022import org.apache.hivemind.Resource;
023import org.apache.tapestry.IScript;
024import org.apache.tapestry.Tapestry;
025import org.apache.tapestry.coerce.ValueConverter;
026import org.apache.tapestry.event.ReportStatusEvent;
027import org.apache.tapestry.event.ReportStatusListener;
028import org.apache.tapestry.event.ResetEventListener;
029import org.apache.tapestry.script.ScriptParser;
030import org.apache.tapestry.services.ExpressionEvaluator;
031import org.apache.tapestry.util.xml.DocumentParseException;
032
033/**
034 * Provides basic access to scripts available on the classpath. Scripts are cached in memory once
035 * parsed.
036 * 
037 * @author Howard Lewis Ship
038 * @since 1.0.2
039 */
040
041public class DefaultScriptSource implements IScriptSource, ResetEventListener, ReportStatusListener
042{
043    private String _serviceId;
044
045    private ClassResolver _classResolver;
046
047    /** @since 4.0 */
048    private ExpressionEvaluator _expressionEvaluator;
049
050    /** @since 4.0 */
051    private ValueConverter _valueConverter;
052
053    private Map _cache = new HashMap();
054
055    public synchronized void resetEventDidOccur()
056    {
057        _cache.clear();
058    }
059
060    public synchronized void reportStatus(ReportStatusEvent event)
061    {
062        event.title(_serviceId);
063        event.property("parsed script count", _cache.size());
064        event.collection("parsed scripts", _cache.keySet());
065    }
066
067    public synchronized IScript getScript(Resource resource)
068    {
069        IScript result = (IScript) _cache.get(resource);
070
071        if (result != null)
072            return result;
073
074        result = parse(resource);
075
076        _cache.put(resource, result);
077
078        return result;
079    }
080
081    private IScript parse(Resource resource)
082    {
083        ScriptParser parser = new ScriptParser(_classResolver, _expressionEvaluator,
084                _valueConverter);
085
086        try
087        {
088            return parser.parse(resource);
089        }
090        catch (DocumentParseException ex)
091        {
092            throw new ApplicationRuntimeException(Tapestry.format(
093                    "DefaultScriptSource.unable-to-parse-script",
094                    resource), ex);
095        }
096    }
097
098    public void setClassResolver(ClassResolver classResolver)
099    {
100        _classResolver = classResolver;
101    }
102
103    /** @since 4.0 */
104    public void setExpressionEvaluator(ExpressionEvaluator expressionEvaluator)
105    {
106        _expressionEvaluator = expressionEvaluator;
107    }
108
109    /** @since 4.0 */
110    public void setValueConverter(ValueConverter valueConverter)
111    {
112        _valueConverter = valueConverter;
113    }
114
115    public void setServiceId(String serviceId)
116    {
117        _serviceId = serviceId;
118    }
119}