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