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.tapestry.IEngine;
021    import org.apache.tapestry.engine.BaseEngine;
022    import org.apache.tapestry.services.EngineFactory;
023    import org.apache.tapestry.spec.IApplicationSpecification;
024    
025    import java.util.Locale;
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        /**
048         * Creates a new engine?
049         * @author Howard Lewis Ship
050         */
051        interface EngineConstructor
052        {
053            IEngine construct();
054        }
055    
056        // TODO: Create a BaseEngineConstructor that is hardcoded to
057        // instantiate a BaseEngine instance, without using reflection
058        // (for efficiency).
059    
060        /**
061         * Creates a new reflective engine constructor.
062         */
063        static class ReflectiveEngineConstructor implements EngineConstructor
064        {
065            private Class _engineClass;
066    
067            ReflectiveEngineConstructor(Class engineClass)
068            {
069                _engineClass = engineClass;
070            }
071    
072            public IEngine construct()
073            {
074                try
075                {
076                    return (IEngine) _engineClass.newInstance();
077                }
078                catch (Exception ex)
079                {
080                    throw new ApplicationRuntimeException(ImplMessages.errorInstantiatingEngine(_engineClass, ex), ex);
081                }
082            }
083        }
084    
085        public void initializeService()
086        {
087            String engineClassName = _applicationSpecification.getEngineClassName();
088    
089            // TODO: Check in web.xml first.
090    
091            if (engineClassName == null)
092                engineClassName = _defaultEngineClassName;
093    
094            Class engineClass = _classResolver.checkForClass(engineClassName);
095    
096            if (engineClass == null)
097            {
098                _errorLog.error(ImplMessages.engineClassNotFound(engineClassName), null, null);
099                engineClass = BaseEngine.class;
100            }
101    
102            _constructor = new ReflectiveEngineConstructor(engineClass);
103        }
104    
105        public IEngine constructNewEngineInstance(Locale locale)
106        {
107            IEngine result = _constructor.construct();
108    
109            result.setLocale(locale);
110    
111            return result;
112        }
113    
114        public void setApplicationSpecification(IApplicationSpecification specification)
115        {
116            _applicationSpecification = specification;
117        }
118    
119        public void setClassResolver(ClassResolver resolver)
120        {
121            _classResolver = resolver;
122        }
123    
124        public void setDefaultEngineClassName(String string)
125        {
126            _defaultEngineClassName = string;
127        }
128    
129        public void setErrorLog(ErrorLog errorLog)
130        {
131            _errorLog = errorLog;
132        }
133    
134    }