001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.tomcat;
018    
019    import java.util.Collection;
020    import java.util.Iterator;
021    import java.util.Map;
022    
023    import org.apache.catalina.Cluster;
024    import org.apache.catalina.Engine;
025    import org.apache.catalina.Host;
026    import org.apache.catalina.LifecycleListener;
027    import org.apache.catalina.Manager;
028    import org.apache.catalina.Realm;
029    import org.apache.catalina.Valve;
030    import org.apache.catalina.core.StandardEngine;
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.gbean.GBeanLifecycle;
036    import org.apache.geronimo.gbean.ReferenceCollection;
037    import org.apache.geronimo.gbean.ReferenceCollectionEvent;
038    import org.apache.geronimo.gbean.ReferenceCollectionListener;
039    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
040    import org.apache.geronimo.system.jmx.MBeanServerReference;
041    import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean;
042    import org.apache.tomcat.util.modeler.Registry;
043    
044    /**
045     * @version $Rev: 554952 $ $Date: 2007-07-10 10:07:16 -0400 (Tue, 10 Jul 2007) $
046     */
047    public class EngineGBean extends BaseGBean implements GBeanLifecycle, ObjectRetriever {
048    
049        private static final Log log = LogFactory.getLog(EngineGBean.class);
050    
051        private static final String NAME = "name";
052        private static final String DEFAULTHOST = "defaultHost";
053    
054        private final Engine engine;
055    
056        public EngineGBean(String className,
057                Map initParams,
058                HostGBean defaultHost,
059                Collection hosts,
060                ObjectRetriever realmGBean,
061                ValveGBean tomcatValveChain,
062                LifecycleListenerGBean listenerChain,
063                CatalinaClusterGBean clusterGBean,
064                ManagerGBean manager,
065                MBeanServerReference mbeanServerReference) throws Exception {
066            super(); // TODO: make it an attribute
067    
068            if (className == null){
069                className = "org.apache.geronimo.tomcat.TomcatEngine";
070            }
071    
072            if (initParams == null){
073                throw new IllegalArgumentException("Must have 'name' value in initParams.");
074            }
075            
076            //Be sure the defaulthost has been declared.
077            if (defaultHost == null){
078                throw new IllegalArgumentException("Must have a 'defaultHost' attribute.");
079            }
080    
081            //Be sure the name has been declared.
082            if (!initParams.containsKey(NAME)){
083                throw new IllegalArgumentException("Must have a 'name' value initParams.");
084            }
085            
086            //Deprecate the defaultHost initParam
087            if (initParams.containsKey(DEFAULTHOST)){
088                log.warn("The " + DEFAULTHOST + " initParams value is no longer used and will be ignored.");
089                initParams.remove(DEFAULTHOST);
090            }
091    
092            engine = (Engine)Class.forName(className).newInstance();
093    
094            //Set the parameters
095            setParameters(engine, initParams);
096            
097            //Set realm (must be before Hosts)
098            if (realmGBean != null){
099                engine.setRealm((Realm)realmGBean.getInternalObject());
100            }
101            
102            //Set the default Host
103            final String defaultHostName = ((Host)defaultHost.getInternalObject()).getName();
104            engine.setDefaultHost(defaultHostName);
105            addHost(defaultHost);
106    
107            if (manager != null)
108                engine.setManager((Manager)manager.getInternalObject());
109    
110            //Add the valve and listener lists
111            if (engine instanceof StandardEngine){
112                if (tomcatValveChain != null){
113                    ValveGBean valveGBean = tomcatValveChain;
114                    while(valveGBean != null){
115                        ((StandardEngine)engine).addValve((Valve)valveGBean.getInternalObject());
116                        valveGBean = valveGBean.getNextValve();
117                    }
118                }
119                
120                if (listenerChain != null){
121                    LifecycleListenerGBean listenerGBean = listenerChain;
122                    while(listenerGBean != null){
123                        ((StandardEngine)engine).addLifecycleListener((LifecycleListener)listenerGBean.getInternalObject());
124                        listenerGBean = listenerGBean.getNextListener();
125                    }
126                }
127            }
128    
129            if(mbeanServerReference != null) {
130                Registry.setServer(mbeanServerReference.getMBeanServer());
131            }
132            
133            //Add the hosts
134            if (hosts instanceof ReferenceCollection) {
135                ReferenceCollection refs = (ReferenceCollection)hosts;
136                refs.addReferenceCollectionListener(new ReferenceCollectionListener() {
137    
138                    public void memberAdded(ReferenceCollectionEvent event) {
139                        Object o = event.getMember();
140                        ObjectRetriever objectRetriever = (ObjectRetriever) o;
141                        String hostName = ((Host)objectRetriever.getInternalObject()).getName();
142                        if (!hostName.equals(defaultHostName))
143                            addHost(objectRetriever);
144                    }
145    
146                    public void memberRemoved(ReferenceCollectionEvent event) {
147                        Object o = event.getMember();
148                        ObjectRetriever objectRetriever = (ObjectRetriever) o;
149                        String hostName = ((Host)objectRetriever.getInternalObject()).getName();
150                        if (!hostName.equals(defaultHostName))
151                            removeHost(objectRetriever);
152                    }
153                });
154                Iterator iterator = refs.iterator();
155                while (iterator.hasNext()){
156                    ObjectRetriever objRetriever = (ObjectRetriever)iterator.next();
157                    String hostName = ((Host)objRetriever.getInternalObject()).getName();
158                    if (!hostName.equals(defaultHostName))
159                        addHost(objRetriever);
160                }
161            }
162    
163    
164            //Add clustering
165            if (clusterGBean != null){
166                engine.setCluster((Cluster)clusterGBean.getInternalObject());
167            }
168        }
169    
170        private void removeHost(ObjectRetriever objRetriever) {
171            Host host = (Host)objRetriever.getInternalObject();
172            engine.removeChild(host);
173        }
174    
175        private void addHost(ObjectRetriever objRetriever) {
176            Host host = (Host)objRetriever.getInternalObject();
177    
178            //If we didn't set a realm, then use the default
179            if (host.getRealm() == null) {
180                host.setRealm(engine.getRealm());
181            }
182            engine.addChild(host);
183        }
184    
185        public Object getInternalObject() {
186            return engine;
187        }
188    
189        public void doFail() {
190            log.warn("Failed");
191        }
192    
193        public void doStart() throws Exception {
194            log.debug("Started");
195        }
196    
197        public void doStop() throws Exception {
198            log.debug("Stopped");
199        }
200    
201        public static final GBeanInfo GBEAN_INFO;
202    
203        static {
204            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("TomcatEngine", EngineGBean.class);
205            infoFactory.addAttribute("className", String.class, true);
206            infoFactory.addAttribute("initParams", Map.class, true);
207            infoFactory.addReference("DefaultHost", HostGBean.class, HostGBean.J2EE_TYPE);
208            infoFactory.addReference("Hosts", ObjectRetriever.class, HostGBean.J2EE_TYPE);
209            infoFactory.addReference("RealmGBean", ObjectRetriever.class, NameFactory.GERONIMO_SERVICE);
210            infoFactory.addReference("TomcatValveChain", ValveGBean.class, ValveGBean.J2EE_TYPE);
211            infoFactory.addReference("LifecycleListenerChain", LifecycleListenerGBean.class, LifecycleListenerGBean.J2EE_TYPE);
212            infoFactory.addReference("CatalinaCluster", CatalinaClusterGBean.class, CatalinaClusterGBean.J2EE_TYPE);
213            infoFactory.addReference("Manager", ManagerGBean.class, ManagerGBean.J2EE_TYPE);
214            infoFactory.addReference("MBeanServerReference", MBeanServerReference.class);
215            infoFactory.addOperation("getInternalObject");
216            infoFactory.setConstructor(new String[] { 
217                    "className", 
218                    "initParams", 
219                    "DefaultHost",
220                    "Hosts", 
221                    "RealmGBean", 
222                    "TomcatValveChain",
223                    "LifecycleListenerChain",
224                    "CatalinaCluster",
225                    "Manager",
226                    "MBeanServerReference"});
227            GBEAN_INFO = infoFactory.getBeanInfo();
228        }
229    
230        public static GBeanInfo getGBeanInfo() {
231            return GBEAN_INFO;
232        }
233    }