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.Locale;
018    
019    import org.apache.hivemind.ApplicationRuntimeException;
020    import org.apache.hivemind.ClassResolver;
021    import org.apache.tapestry.IEngine;
022    import org.apache.tapestry.services.EngineFactory;
023    import org.apache.tapestry.spec.IApplicationSpecification;
024    
025    /**
026     * Standard implementation of {@link org.apache.tapestry.services.EngineFactory} service.
027     * This should do for most purposes, since a major focus of Tapestry 4.0 is to no longer
028     * require subclassing of {@link org.apache.tapestry.engine.BaseEngine}.
029     *
030     * @author Howard Lewis Ship
031     * @since 4.0
032     */
033    public class EngineFactoryImpl implements EngineFactory
034    {
035        private IApplicationSpecification _applicationSpecification;
036        private String _defaultEngineClassName;
037        private EngineConstructor _constructor;
038        private ClassResolver _classResolver;
039    
040        interface EngineConstructor
041        {
042            IEngine construct();
043        }
044    
045    
046            // TODO: Create a BaseEngineConstructor that is hardcoded to
047            // instantiate a BaseEngine instance, without using reflection
048            // (for efficiency). 
049    
050        static class ReflectiveEngineConstructor implements EngineConstructor
051        {
052            private Class _engineClass;
053    
054            ReflectiveEngineConstructor(Class engineClass)
055            {
056                _engineClass = engineClass;
057            }
058    
059            public IEngine construct()
060            {
061                try
062                {
063                    return (IEngine) _engineClass.newInstance();
064                }
065                catch (Exception ex)
066                {
067                    throw new ApplicationRuntimeException(
068                        ImplMessages.errorInstantiatingEngine(_engineClass, ex),
069                        ex);
070                }
071            }
072        }
073    
074        public void initializeService()
075        {
076            String engineClassName = _applicationSpecification.getEngineClassName();
077    
078                    // TODO: Check in web.xml first.
079    
080            if (engineClassName == null)
081                engineClassName = _defaultEngineClassName;
082    
083            Class engineClass = _classResolver.findClass(engineClassName);
084    
085            _constructor = new ReflectiveEngineConstructor(engineClass);
086        }
087    
088        public IEngine constructNewEngineInstance(Locale locale)
089        {
090            IEngine result = _constructor.construct();
091    
092            result.setLocale(locale);
093    
094            return result;
095        }
096    
097        public void setApplicationSpecification(IApplicationSpecification specification)
098        {
099            _applicationSpecification = specification;
100        }
101    
102        public void setClassResolver(ClassResolver resolver)
103        {
104            _classResolver = resolver;
105        }
106    
107        public void setDefaultEngineClassName(String string)
108        {
109            _defaultEngineClassName = string;
110        }
111    
112    }