001    /**
002     *
003     * Copyright 2003-2005 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  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    import org.apache.catalina.Cluster;
023    import org.apache.catalina.Engine;
024    import org.apache.catalina.Host;
025    import org.apache.catalina.Manager;
026    import org.apache.catalina.Realm;
027    import org.apache.catalina.Valve;
028    import org.apache.catalina.core.StandardEngine;
029    import org.apache.commons.logging.Log;
030    import org.apache.commons.logging.LogFactory;
031    import org.apache.geronimo.gbean.GBeanInfo;
032    import org.apache.geronimo.gbean.GBeanInfoBuilder;
033    import org.apache.geronimo.gbean.GBeanLifecycle;
034    import org.apache.geronimo.gbean.ReferenceCollection;
035    import org.apache.geronimo.gbean.ReferenceCollectionEvent;
036    import org.apache.geronimo.gbean.ReferenceCollectionListener;
037    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
038    import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean;
039    
040    /**
041     * @version $Rev: 387050 $ $Date: 2006-03-19 14:43:00 -0800 (Sun, 19 Mar 2006) $
042     */
043    public class EngineGBean extends BaseGBean implements GBeanLifecycle, ObjectRetriever {
044    
045        private static final Log log = LogFactory.getLog(EngineGBean.class);
046    
047        private static final String NAME = "name";
048        private static final String DEFAULTHOST = "defaultHost";
049    
050        private final Engine engine;
051    
052        public EngineGBean(String className,
053                Map initParams,
054                HostGBean defaultHost,
055                Collection hosts,
056                ObjectRetriever realmGBean,
057                ValveGBean tomcatValveChain,
058                CatalinaClusterGBean clusterGBean,
059                ManagerGBean manager) throws Exception {
060            super(); // TODO: make it an attribute
061    
062            if (className == null){
063                className = "org.apache.geronimo.tomcat.TomcatEngine";
064            }
065    
066            if (initParams == null){
067                throw new IllegalArgumentException("Must have 'name' value in initParams.");
068            }
069            
070            //Be sure the defaulthost has been declared.
071            if (defaultHost == null){
072                throw new IllegalArgumentException("Must have a 'defaultHost' attribute.");
073            }
074    
075            //Be sure the name has been declared.
076            if (!initParams.containsKey(NAME)){
077                throw new IllegalArgumentException("Must have a 'name' value initParams.");
078            }
079            
080            //Deprecate the defaultHost initParam
081            if (initParams.containsKey(DEFAULTHOST)){
082                log.warn("The " + DEFAULTHOST + " initParams value is no longer used and will be ignored.");
083                initParams.remove(DEFAULTHOST);
084            }
085    
086            engine = (Engine)Class.forName(className).newInstance();
087    
088            //Set the parameters
089            setParameters(engine, initParams);
090            
091            //Set realm (must be before Hosts)
092            if (realmGBean != null){
093                engine.setRealm((Realm)realmGBean.getInternalObject());
094            }
095            
096            //Set the default Host
097            final String defaultHostName = ((Host)defaultHost.getInternalObject()).getName();
098            engine.setDefaultHost(defaultHostName);
099            addHost(defaultHost);
100    
101            if (manager != null)
102                engine.setManager((Manager)manager.getInternalObject());
103    
104            //Add the valve list
105            if (engine instanceof StandardEngine){
106                if (tomcatValveChain != null){
107                    ValveGBean valveGBean = tomcatValveChain;
108                    while(valveGBean != null){
109                        ((StandardEngine)engine).addValve((Valve)valveGBean.getInternalObject());
110                        valveGBean = valveGBean.getNextValve();
111                    }
112                }
113            }
114    
115            //Add the hosts
116            if (hosts instanceof ReferenceCollection) {
117                ReferenceCollection refs = (ReferenceCollection)hosts;
118                refs.addReferenceCollectionListener(new ReferenceCollectionListener() {
119    
120                    public void memberAdded(ReferenceCollectionEvent event) {
121                        Object o = event.getMember();
122                        ObjectRetriever objectRetriever = (ObjectRetriever) o;
123                        String hostName = ((Host)objectRetriever.getInternalObject()).getName();
124                        if (!hostName.equals(defaultHostName))
125                            addHost(objectRetriever);
126                    }
127    
128                    public void memberRemoved(ReferenceCollectionEvent event) {
129                        Object o = event.getMember();
130                        ObjectRetriever objectRetriever = (ObjectRetriever) o;
131                        String hostName = ((Host)objectRetriever.getInternalObject()).getName();
132                        if (!hostName.equals(defaultHostName))
133                            removeHost(objectRetriever);
134                    }
135                });
136                Iterator iterator = refs.iterator();
137                while (iterator.hasNext()){
138                    ObjectRetriever objRetriever = (ObjectRetriever)iterator.next();
139                    String hostName = ((Host)objRetriever.getInternalObject()).getName();
140                    if (!hostName.equals(defaultHostName))
141                        addHost(objRetriever);
142                }
143            }
144    
145    
146            //Add clustering
147            if (clusterGBean != null){
148                engine.setCluster((Cluster)clusterGBean.getInternalObject());
149            }
150        }
151    
152        private void removeHost(ObjectRetriever objRetriever) {
153            Host host = (Host)objRetriever.getInternalObject();
154            engine.removeChild(host);
155        }
156    
157        private void addHost(ObjectRetriever objRetriever) {
158            Host host = (Host)objRetriever.getInternalObject();
159    
160            //If we didn't set a realm, then use the default
161            if (host.getRealm() == null) {
162                host.setRealm(engine.getRealm());
163            }
164            engine.addChild(host);
165        }
166    
167        public Object getInternalObject() {
168            return engine;
169        }
170    
171        public void doFail() {
172            log.warn("Failed");
173        }
174    
175        public void doStart() throws Exception {
176            log.debug("Started");
177        }
178    
179        public void doStop() throws Exception {
180            log.debug("Stopped");
181        }
182    
183        public static final GBeanInfo GBEAN_INFO;
184    
185        static {
186            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("TomcatEngine", EngineGBean.class);
187            infoFactory.addAttribute("className", String.class, true);
188            infoFactory.addAttribute("initParams", Map.class, true);
189            infoFactory.addReference("DefaultHost", HostGBean.class, HostGBean.J2EE_TYPE);
190            infoFactory.addReference("Hosts", ObjectRetriever.class, HostGBean.J2EE_TYPE);
191            infoFactory.addReference("RealmGBean", ObjectRetriever.class, NameFactory.GERONIMO_SERVICE);
192            infoFactory.addReference("TomcatValveChain", ValveGBean.class, ValveGBean.J2EE_TYPE);
193            infoFactory.addReference("CatalinaCluster", CatalinaClusterGBean.class, CatalinaClusterGBean.J2EE_TYPE);
194            infoFactory.addReference("Manager", ManagerGBean.class, ManagerGBean.J2EE_TYPE);
195            infoFactory.addOperation("getInternalObject");
196            infoFactory.setConstructor(new String[] { 
197                    "className", 
198                    "initParams", 
199                    "DefaultHost",
200                    "Hosts", 
201                    "RealmGBean", 
202                    "TomcatValveChain",
203                    "CatalinaCluster",
204                    "Manager"});
205            GBEAN_INFO = infoFactory.getBeanInfo();
206        }
207    
208        public static GBeanInfo getGBeanInfo() {
209            return GBEAN_INFO;
210        }
211    }