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