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