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.services.impl;
016
017import java.util.HashMap;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Locale;
021import java.util.Map;
022
023import org.apache.hivemind.ApplicationRuntimeException;
024import org.apache.hivemind.ClassResolver;
025import org.apache.hivemind.ErrorLog;
026import org.apache.hivemind.Resource;
027import org.apache.hivemind.service.ThreadLocale;
028import org.apache.hivemind.util.Defense;
029import org.apache.tapestry.IRequestCycle;
030import org.apache.tapestry.asset.AssetFactory;
031import org.apache.tapestry.coerce.ValueConverter;
032import org.apache.tapestry.describe.HTMLDescriber;
033import org.apache.tapestry.engine.IPageSource;
034import org.apache.tapestry.engine.IPropertySource;
035import org.apache.tapestry.engine.IScriptSource;
036import org.apache.tapestry.engine.ISpecificationSource;
037import org.apache.tapestry.engine.state.ApplicationStateManager;
038import org.apache.tapestry.error.ExceptionPresenter;
039import org.apache.tapestry.error.RequestExceptionReporter;
040import org.apache.tapestry.error.StaleLinkExceptionPresenter;
041import org.apache.tapestry.error.StaleSessionExceptionPresenter;
042import org.apache.tapestry.listener.ListenerInvoker;
043import org.apache.tapestry.listener.ListenerMapSource;
044import org.apache.tapestry.markup.MarkupWriterSource;
045import org.apache.tapestry.services.ClassFinder;
046import org.apache.tapestry.services.ComponentMessagesSource;
047import org.apache.tapestry.services.ComponentPropertySource;
048import org.apache.tapestry.services.CookieSource;
049import org.apache.tapestry.services.DataSqueezer;
050import org.apache.tapestry.services.Infrastructure;
051import org.apache.tapestry.services.LinkFactory;
052import org.apache.tapestry.services.ObjectPool;
053import org.apache.tapestry.services.RequestCycleFactory;
054import org.apache.tapestry.services.ResetEventHub;
055import org.apache.tapestry.services.ResponseRenderer;
056import org.apache.tapestry.services.ServiceMap;
057import org.apache.tapestry.services.TemplateSource;
058import org.apache.tapestry.spec.IApplicationSpecification;
059import org.apache.tapestry.web.WebContext;
060import org.apache.tapestry.web.WebContextResource;
061import org.apache.tapestry.web.WebRequest;
062import org.apache.tapestry.web.WebResponse;
063
064/**
065 * Allows access to selected HiveMind services.
066 * 
067 * @author Howard Lewis Ship
068 * @since 4.0
069 */
070public class InfrastructureImpl implements Infrastructure
071{
072    /**
073     * List of {@link org.apache.tapestry.services.impl.InfrastructureContribution}.
074     */
075    private List _normalContributions;
076
077    /**
078     * List of {@link org.apache.tapestry.services.impl.InfrastructureContribution}.
079     */
080    private List _overrideContributions;
081
082    private Map _properties = new HashMap();
083
084    private boolean _initialized;
085
086    private String _mode;
087
088    private ErrorLog _errorLog;
089
090    private ClassResolver _classResolver;
091
092    private ThreadLocale _threadLocale;
093
094    public void setLocale(Locale locale)
095    {
096        _threadLocale.setLocale(locale);
097    }
098
099    public String getApplicationId()
100    {
101        return (String) getProperty("applicationId");
102    }
103
104    public IPropertySource getApplicationPropertySource()
105    {
106        return (IPropertySource) getProperty("applicationPropertySource");
107    }
108
109    public IApplicationSpecification getApplicationSpecification()
110    {
111        return (IApplicationSpecification) getProperty("applicationSpecification");
112    }
113
114    public ApplicationStateManager getApplicationStateManager()
115    {
116        return (ApplicationStateManager) getProperty("applicationStateManager");
117    }
118
119    public ClassResolver getClassResolver()
120    {
121        return _classResolver;
122    }
123
124    public ComponentMessagesSource getComponentMessagesSource()
125    {
126        return (ComponentMessagesSource) getProperty("componentMessagesSource");
127    }
128
129    public ComponentPropertySource getComponentPropertySource()
130    {
131        return (ComponentPropertySource) getProperty("componentPropertySource");
132    }
133
134    public String getContextPath()
135    {
136        return getRequest().getContextPath();
137    }
138
139    public Resource getContextRoot()
140    {
141        WebContext context = (WebContext) getProperty("context");
142
143        return new WebContextResource(context, "/");
144    }
145
146    public DataSqueezer getDataSqueezer()
147    {
148        return (DataSqueezer) getProperty("dataSqueezer");
149    }
150
151    public IPropertySource getGlobalPropertySource()
152    {
153        return (IPropertySource) getProperty("globalPropertySource");
154    }
155
156    public LinkFactory getLinkFactory()
157    {
158        return (LinkFactory) getProperty("linkFactory");
159    }
160
161    public ObjectPool getObjectPool()
162    {
163        return (ObjectPool) getProperty("objectPool");
164    }
165
166    public IPageSource getPageSource()
167    {
168        return (IPageSource) getProperty("pageSource");
169    }
170
171    public WebRequest getRequest()
172    {
173        return (WebRequest) getProperty("request");
174    }
175
176    public RequestCycleFactory getRequestCycleFactory()
177    {
178        return (RequestCycleFactory) getProperty("requestCycleFactory");
179    }
180
181    public RequestExceptionReporter getRequestExceptionReporter()
182    {
183        return (RequestExceptionReporter) getProperty("requestExceptionReporter");
184    }
185
186    public ResetEventHub getResetEventHub()
187    {
188        return (ResetEventHub) getProperty("resetEventHub");
189    }
190
191    public WebResponse getResponse()
192    {
193        return (WebResponse) getProperty("response");
194    }
195
196    public ResponseRenderer getResponseRenderer()
197    {
198        return (ResponseRenderer) getProperty("responseRenderer");
199    }
200
201    public IScriptSource getScriptSource()
202    {
203        return (IScriptSource) getProperty("scriptSource");
204    }
205
206    public ServiceMap getServiceMap()
207    {
208        return (ServiceMap) getProperty("serviceMap");
209    }
210
211    public ISpecificationSource getSpecificationSource()
212    {
213        return (ISpecificationSource) getProperty("specificationSource");
214    }
215
216    public TemplateSource getTemplateSource()
217    {
218        return (TemplateSource) getProperty("templateSource");
219    }
220
221    public String getOutputEncoding()
222    {
223        return getApplicationPropertySource().getPropertyValue(
224                "org.apache.tapestry.output-encoding");
225    }
226
227    public MarkupWriterSource getMarkupWriterSource()
228    {
229        return (MarkupWriterSource) getProperty("markupWriterSource");
230    }
231
232    public HTMLDescriber getHTMLDescriber()
233    {
234        return (HTMLDescriber) getProperty("HTMLDescriber");
235    }
236
237    public ExceptionPresenter getExceptionPresenter()
238    {
239        return (ExceptionPresenter) getProperty("exceptionPresenter");
240    }
241
242    public ListenerMapSource getListenerMapSource()
243    {
244        return (ListenerMapSource) getProperty("listenerMapSource");
245    }
246
247    public StaleSessionExceptionPresenter getStaleSessionExceptionPresenter()
248    {
249        return (StaleSessionExceptionPresenter) getProperty("staleSessionExceptionPresenter");
250    }
251
252    public StaleLinkExceptionPresenter getStaleLinkExceptionPresenter()
253    {
254        return (StaleLinkExceptionPresenter) getProperty("staleLinkExceptionPresenter");
255    }
256
257    public ValueConverter getValueConverter()
258    {
259        return (ValueConverter) getProperty("valueConverter");
260    }
261
262    public ListenerInvoker getListenerInvoker()
263    {
264        return (ListenerInvoker) getProperty("listenerInvoker");
265    }
266
267    public AssetFactory getAssetFactory()
268    {
269        return (AssetFactory) getProperty("assetFactory");
270    }
271
272    public CookieSource getCookieSource()
273    {
274        return (CookieSource) getProperty("cookieSource");
275    }
276
277    public ClassFinder getClassFinder()
278    {
279        return (ClassFinder) getProperty("classFinder");
280    }
281
282    public IRequestCycle getRequestCycle()
283    {
284        return (IRequestCycle) getProperty("requestCycle");
285    }
286
287    public Object getProperty(String propertyName)
288    {
289        Defense.notNull(propertyName, "propertyName");
290
291        if (!_initialized)
292            throw new IllegalStateException(ImplMessages.infrastructureNotInitialized());
293
294        Object result = _properties.get(propertyName);
295
296        if (result == null)
297            throw new ApplicationRuntimeException(ImplMessages
298                    .missingInfrastructureProperty(propertyName));
299
300        return result;
301    }
302
303    public synchronized void initialize(String mode)
304    {
305        Defense.notNull(mode, "mode");
306
307        if (_initialized)
308            throw new IllegalStateException(ImplMessages.infrastructureAlreadyInitialized(
309                    mode,
310                    _mode));
311
312        Map normalByMode = buildMapFromContributions(_normalContributions, mode);
313        Map normal = buildMapFromContributions(_normalContributions, null);
314        Map overrideByMode = buildMapFromContributions(_overrideContributions, mode);
315        Map override = buildMapFromContributions(_overrideContributions, null);
316
317        addToProperties(overrideByMode);
318        addToProperties(override);
319        addToProperties(normalByMode);
320        addToProperties(normal);
321
322        _mode = mode;
323        _initialized = true;
324    }
325
326    private Map buildMapFromContributions(List contributions, String mode)
327    {
328        Map result = new HashMap();
329
330        Iterator i = contributions.iterator();
331        while (i.hasNext())
332        {
333            InfrastructureContribution ic = (InfrastructureContribution) i.next();
334
335            if (!ic.matchesMode(mode))
336                continue;
337
338            String propertyName = ic.getProperty();
339
340            InfrastructureContribution existing = (InfrastructureContribution) result
341                    .get(propertyName);
342
343            if (existing != null)
344            {
345                _errorLog.error(ImplMessages.duplicateInfrastructureContribution(ic, existing
346                        .getLocation()), ic.getLocation(), null);
347                continue;
348            }
349
350            result.put(propertyName, ic);
351        }
352
353        return result;
354    }
355
356    /**
357     * Adds to the master set of properties contributed objects that don't match an already existing
358     * key.
359     * 
360     * @param map
361     *            map of {@link org.apache.tapestry.services.impl.InfrastructureContribution}keyed
362     *            on property name (String).
363     */
364
365    private void addToProperties(Map map)
366    {
367        Iterator i = map.values().iterator();
368        while (i.hasNext())
369        {
370            InfrastructureContribution ic = (InfrastructureContribution) i.next();
371            String propertyName = ic.getProperty();
372
373            if (_properties.containsKey(propertyName))
374                continue;
375
376            _properties.put(propertyName, ic.getObject());
377        }
378    }
379
380    public void setClassResolver(ClassResolver classResolver)
381    {
382        _classResolver = classResolver;
383    }
384
385    public void setThreadLocale(ThreadLocale threadLocale)
386    {
387        _threadLocale = threadLocale;
388    }
389
390    public void setNormalContributions(List normalContributions)
391    {
392        _normalContributions = normalContributions;
393    }
394
395    public void setOverrideContributions(List overrideContributions)
396    {
397        _overrideContributions = overrideContributions;
398    }
399
400    public void setErrorLog(ErrorLog errorLog)
401    {
402        _errorLog = errorLog;
403    }
404}