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.jetty6;
018    
019    import java.util.Map;
020    import java.util.Set;
021    
022    import javax.security.auth.Subject;
023    
024    import org.apache.geronimo.gbean.GBeanInfo;
025    import org.apache.geronimo.gbean.GBeanInfoBuilder;
026    import org.apache.geronimo.gbean.GBeanLifecycle;
027    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
028    import org.apache.geronimo.management.Servlet;
029    import org.mortbay.jetty.servlet.ServletHolder;
030    
031    
032    /**
033     * This ServletHolder's sole purpose is to provide the thread's current
034     * ServletHolder for realms that are interested in the current servlet, e.g.
035     * current servlet name.
036     * <p/>
037     * It is also being our servlet gbean for now.  We could gbean-ize the superclass to avoid the thread local access.
038     *
039     * @version $Rev: 556217 $ $Date: 2007-07-13 23:39:06 -0400 (Fri, 13 Jul 2007) $
040     * @see JAASJettyRealm#isUserInRole(java.security.Principal, String)
041     */
042    public class JettyServletHolder implements Servlet, GBeanLifecycle {
043    
044    
045        private final JettyServletRegistration servletRegistration;
046        private final ServletHolder servletHolder;
047        private final String objectName;
048    
049        //todo consider interface instead of this constructor for endpoint use.
050        public JettyServletHolder() {
051            servletRegistration = null;
052            servletHolder = null;
053            objectName = null;
054        }
055    
056        public JettyServletHolder(String objectName,
057                String servletName,
058                String servletClassName,
059                String jspFile,
060                Map initParams,
061                Integer loadOnStartup,
062                Set<String> servletMappings,
063                String runAsRole,
064                JettyServletRegistration context) throws Exception {
065            servletRegistration = context;
066            Subject runAsSubject = context == null? null: context.getSubjectForRole(runAsRole);
067            servletHolder = new InternalJettyServletHolder(context == null? null: context.getLifecycleChain(), runAsSubject, servletRegistration);
068            servletHolder.setName(servletName);
069            servletHolder.setClassName(servletClassName);
070            //context will be null only for use as "default servlet info holder" in deployer.
071    
072            if (context != null) {
073                servletHolder.setInitParameters(initParams);
074                servletHolder.setForcedPath(jspFile);
075                if (loadOnStartup != null) {
076                    //This has no effect on the actual start order, the gbean references "previous" control that.
077                    servletHolder.setInitOrder(loadOnStartup);
078                }
079                //this now starts the servlet in the appropriate context
080                context.registerServletHolder(servletHolder, servletName, servletMappings, objectName);
081            }
082            this.objectName = objectName;
083        }
084    
085        public String getServletName() {
086            return servletHolder.getName();
087        }
088    
089        public String getServletClassName() {
090            return servletHolder.getClassName();
091        }
092    
093        public String getObjectName() {
094            return objectName;
095        }
096    
097        public boolean isStateManageable() {
098            return false;
099        }
100    
101        public boolean isStatisticsProvider() {
102            return false;
103        }
104    
105        public boolean isEventProvider() {
106            return false;
107        }
108    
109        public void doStart() throws Exception {
110            //start actually handled in constructor
111    //        servletHolder.start();
112        }
113    
114        public void doStop() throws Exception {
115            servletHolder.stop();
116            if (servletRegistration != null) {
117                servletRegistration.unregisterServletHolder(servletHolder, servletHolder.getName(), null, objectName);
118            }
119        }
120    
121        public void doFail() {
122            try {
123                doStop();
124            } catch (Exception e) {
125                //?? ignore
126            }
127        }
128    
129        public static final GBeanInfo GBEAN_INFO;
130    
131        static {
132            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyServletHolder.class, NameFactory.SERVLET);
133            //todo replace with interface
134    //        infoBuilder.addInterface(ServletHolder.class);
135    
136            infoBuilder.addAttribute("servletName", String.class, true);
137            infoBuilder.addAttribute("servletClass", String.class, true);
138            infoBuilder.addAttribute("jspFile", String.class, true);
139            infoBuilder.addAttribute("initParams", Map.class, true);
140            infoBuilder.addAttribute("loadOnStartup", Integer.class, true);
141            infoBuilder.addAttribute("servletMappings", Set.class, true);
142            infoBuilder.addAttribute("runAsRole", String.class, true);
143            infoBuilder.addAttribute("objectName", String.class, false);
144            infoBuilder.addInterface(Servlet.class);
145    
146            infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class, NameFactory.WEB_MODULE);
147    
148            infoBuilder.setConstructor(new String[]{"objectName",
149                    "servletName",
150                    "servletClass",
151                    "jspFile",
152                    "initParams",
153                    "loadOnStartup",
154                    "servletMappings",
155                    "runAsRole",
156                    "JettyServletRegistration"});
157    
158            GBEAN_INFO = infoBuilder.getBeanInfo();
159        }
160    
161        public static GBeanInfo getGBeanInfo() {
162            return GBEAN_INFO;
163        }
164    
165    }