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