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
015 package org.apache.tapestry.engine;
016
017 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
018 import org.apache.hivemind.ApplicationRuntimeException;
019 import org.apache.hivemind.ClassResolver;
020 import org.apache.hivemind.Resource;
021 import org.apache.tapestry.IScript;
022 import org.apache.tapestry.Tapestry;
023 import org.apache.tapestry.coerce.ValueConverter;
024 import org.apache.tapestry.event.ReportStatusEvent;
025 import org.apache.tapestry.event.ReportStatusListener;
026 import org.apache.tapestry.event.ResetEventListener;
027 import org.apache.tapestry.script.ScriptParser;
028 import org.apache.tapestry.services.ExpressionEvaluator;
029 import org.apache.tapestry.util.xml.DocumentParseException;
030
031 import java.util.Map;
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
041 public 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 ConcurrentHashMap();
054
055 public void resetEventDidOccur()
056 {
057 _cache.clear();
058 }
059
060 public 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 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, _valueConverter);
084 try
085 {
086 return parser.parse(resource);
087 }
088 catch (DocumentParseException ex)
089 {
090 throw new ApplicationRuntimeException(Tapestry.format("DefaultScriptSource.unable-to-parse-script",
091 resource), ex);
092 }
093 }
094
095 public void setClassResolver(ClassResolver classResolver)
096 {
097 _classResolver = classResolver;
098 }
099
100 /** @since 4.0 */
101 public void setExpressionEvaluator(ExpressionEvaluator expressionEvaluator)
102 {
103 _expressionEvaluator = expressionEvaluator;
104 }
105
106 /** @since 4.0 */
107 public void setValueConverter(ValueConverter valueConverter)
108 {
109 _valueConverter = valueConverter;
110 }
111
112 public void setServiceId(String serviceId)
113 {
114 _serviceId = serviceId;
115 }
116 }