KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > web > PEWebContainer


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.web;
25
26 import java.io.File JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.text.MessageFormat JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.Hashtable JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.ListIterator JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38 import java.util.logging.Level JavaDoc;
39 import java.util.ResourceBundle JavaDoc;
40 import java.util.Set JavaDoc;
41 import java.util.Stack JavaDoc;
42 import java.util.Vector JavaDoc;
43 import javax.management.MBeanServer JavaDoc;
44
45 import javax.naming.NamingException JavaDoc;
46
47 import org.apache.catalina.Container;
48 import org.apache.catalina.Connector;
49 import org.apache.catalina.startup.Embedded;
50 import org.apache.catalina.Engine;
51 import org.apache.catalina.LifecycleException;
52 import org.apache.catalina.core.StandardWrapper;
53 import org.apache.catalina.core.StandardContext;
54 import org.apache.catalina.core.StandardEngine;
55 import org.apache.catalina.core.StandardHost;
56 import org.apache.coyote.tomcat5.CoyoteConnector;
57
58 import com.sun.enterprise.server.Constants;
59 import com.sun.enterprise.config.ConfigContext;
60 import com.sun.enterprise.config.ConfigBean;
61 import com.sun.enterprise.config.ConfigBeansFactory;
62 import com.sun.enterprise.config.ConfigException;
63 import com.sun.enterprise.config.serverbeans.AccessLog;
64 import com.sun.enterprise.config.serverbeans.Config;
65 import com.sun.enterprise.config.serverbeans.ConnectionPool;
66 import com.sun.enterprise.config.serverbeans.Domain;
67 import com.sun.enterprise.config.serverbeans.Applications;
68 import com.sun.enterprise.config.serverbeans.J2eeApplication;
69 import com.sun.enterprise.config.serverbeans.LogService;
70 import com.sun.enterprise.config.serverbeans.Server;
71 import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
72 import com.sun.enterprise.config.serverbeans.WebModule;
73 import com.sun.enterprise.config.serverbeans.HttpFileCache;
74 import com.sun.enterprise.config.serverbeans.HttpService;
75 import com.sun.enterprise.config.serverbeans.HttpProtocol;
76 import com.sun.enterprise.config.serverbeans.KeepAlive;
77 import com.sun.enterprise.config.serverbeans.HttpListener;
78 import com.sun.enterprise.config.serverbeans.ElementProperty;
79 import com.sun.enterprise.config.serverbeans.RequestProcessing;
80 import com.sun.enterprise.config.serverbeans.Ssl;
81 //import com.sun.enterprise.config.serverbeans.Mime;
82
import com.sun.enterprise.config.ConfigContext;
83
84 import com.sun.enterprise.instance.InstanceEnvironment;
85 import com.sun.enterprise.server.ApplicationRegistry;
86 import com.sun.enterprise.server.ServerContext;
87 import com.sun.enterprise.admin.common.InitConfFileBean;
88 import com.sun.enterprise.admin.common.PasswordConfReader;
89 import com.sun.enterprise.server.pluggable.WebContainerFeatureFactory;
90 import com.sun.enterprise.util.io.FileUtils;
91 import com.sun.enterprise.util.logging.IASLevel;
92 import com.sun.enterprise.util.StringUtils;
93 import com.sun.enterprise.web.logger.IASLogger;
94 import com.sun.enterprise.web.session.PersistenceType;
95 import com.sun.enterprise.web.session.SessionCookieConfig;
96 import com.sun.enterprise.web.connector.coyote.PECoyoteConnector;
97
98 import com.sun.enterprise.deployment.Application;
99 import com.sun.enterprise.deployment.WebBundleDescriptor;
100 import com.sun.enterprise.Switch;
101 import com.sun.appserv.server.ServerLifecycleException;
102 import com.sun.appserv.ProxyHandler;
103 import com.sun.logging.LogDomains;
104 import com.sun.web.security.RealmAdapter;
105
106 //dynamic reconfiguration
107
import com.sun.enterprise.admin.event.AdminEventListenerException;
108 import com.sun.enterprise.admin.event.AdminEventListenerRegistry;
109 import com.sun.enterprise.admin.event.http.HSHttpListenerEvent;
110 import com.sun.enterprise.admin.event.http.HSSslEvent;
111 import com.sun.enterprise.admin.event.http.HSVirtualServerEvent;
112 import com.sun.enterprise.admin.event.http.HSHttpAccessLogEvent;
113 import com.sun.enterprise.admin.event.http.HSAccessLogEvent;
114
115 // monitoring imports
116
import com.sun.enterprise.admin.monitor.stats.HTTPListenerStats;
117 import com.sun.enterprise.admin.monitor.registry.MonitoringRegistry;
118 import com.sun.enterprise.admin.monitor.registry.MonitoringRegistrationException;
119 import com.sun.enterprise.admin.monitor.registry.MonitoringLevelListener;
120
121 import com.sun.enterprise.web.reconfig.HttpListenerReconfig;
122 import com.sun.enterprise.web.reconfig.VirtualServerReconfig;
123
124 import com.sun.enterprise.web.stats.HTTPListenerStatsImpl;
125 import com.sun.enterprise.web.stats.PWCFileCacheStatsImpl;
126 import com.sun.enterprise.web.stats.PWCKeepAliveStatsImpl;
127 import com.sun.enterprise.web.stats.PWCThreadPoolStatsImpl;
128 import com.sun.enterprise.web.stats.PWCVirtualServerStatsImpl;
129 import com.sun.enterprise.web.stats.PWCConnectionQueueStatsImpl;
130 import com.sun.enterprise.web.stats.PWCRequestStatsImpl;
131
132 import com.sun.enterprise.security.CipherInfo;
133
134 /**
135  * Represents the web container for PE and EE (since 9.0)
136  */

137 public class PEWebContainer extends WebContainer
138     implements MonitoringLevelListener {
139
140     /**
141      * Maps mime element's id to parsed contents of mime file
142      */

143     private HashMap JavaDoc mimeMap;
144
145     /**
146      * Maps http-listener id to Tomcat Connector
147      */

148     private HashMap JavaDoc<String JavaDoc,PECoyoteConnector> connectorMap;
149     
150    
151     /**
152      * Allow disabling accessLog mechanism
153      */

154     private boolean installAccessLogValve = true;
155     
156     
157    /**
158     * AccessLog buffer size for storing logs.
159     */

160    private String JavaDoc accessLogBufferSize = null;
161    
162    
163    /**
164     * AccessLog interval before the valve flush its buffer to the disk.
165     */

166    private String JavaDoc accessLogWriteInterval = null;
167    
168    
169     /**
170      * The default-redirect port.
171      */

172     protected int defaultRedirectPort = -1;
173
174    // --------------------------------------------------------- Constructor
175

176     /**
177      * This creates the embedded Catalina/Jasper container
178      * and sets the config properties on the container.
179      */

180     protected PEWebContainer(String JavaDoc id, ServerContext context) {
181
182         super(id, context);
183     }
184
185     /**
186      * Initialize Tomcat internal objects.
187      */

188     protected void init(ServerContext context){
189
190         connectorMap = new HashMap JavaDoc<String JavaDoc,PECoyoteConnector>();
191
192         Config config = null;
193         ConfigContext configContext = context.getConfigContext();
194
195         try {
196             config = ServerBeansFactory.getConfigBean(configContext);
197         } catch (ConfigException e) {
198             String JavaDoc msg = _rb.getString("vs.appsConfigError");
199                 Object JavaDoc[] params = { };
200                 msg = MessageFormat.format(msg, params);
201             _logger.log(Level.SEVERE, msg, e);
202         }
203          // Create Tomcat Engine
204
createEngine();
205
206         HttpService httpService = config.getHttpService();
207         configureNotSupported(httpService);
208
209         createConnectors(httpService);
210
211         createHosts(httpService, installAccessLogValve);
212         createJKConnector();
213         
214         registerReconfigListeners();
215        
216     }
217
218
219     /**
220      * Starts the AJP connector that will listen to call from Apache using
221      * mod_jk, mod_jk2 or mod_ajp.
222      *
223      */

224     private void createJKConnector() {
225
226         int port = 8009;
227         int defaultRedirectPort = -1;
228
229         String JavaDoc portString = System.getProperty("com.sun.enterprise.web.connector.enableJK");
230         if (portString == null) {
231             // do not create JK Connector if property is not set
232
return;
233         } else {
234             try {
235                 port = Integer.parseInt(portString);
236             } catch (NumberFormatException JavaDoc ex) {
237                 // use default port 8009
238
port = 8009;
239             }
240             PECoyoteConnector connector = (PECoyoteConnector)
241                 ((Embedded)_embedded).createConnector("0.0.0.0", port, "ajp");
242
243             String JavaDoc defaultHost = "server";
244             Container[] virtualServers =
245                     _embedded.getEngines()[0].findChildren();
246             // Find a virtual-server on which we can attach the mod_jk
247
// listener.
248
for (int i=0; i < virtualServers.length; i++){
249                 if ( !virtualServers[i].getName().equalsIgnoreCase(ADMIN_VS) ){
250                     defaultHost = virtualServers[i].getName();
251                     
252                     int[] ports = ((VirtualServer)virtualServers[i]).findPorts();
253                     int[] newPorts = new int[ports.length + 1];
254                     System.arraycopy(ports,0,newPorts,0,ports.length);
255                     newPorts[ports.length] = port;
256                     ((VirtualServer)virtualServers[i]).setPorts(newPorts);
257                     break;
258                 }
259             }
260             connector.setDefaultHost(defaultHost);
261             connector.setDomain(_serverContext.getDefaultDomainName());
262             connector.setLogger(_logger);
263             connector.setName("httpd-listener");
264         
265             _logger.log(Level.INFO, "Apache mod_jk/jk2 attached to virtual-server "
266                                 + defaultHost + " listening on port: "
267                                 + portString);
268
269             _embedded.addConnector(connector);
270         }
271     }
272
273     
274     /**
275      * Enumerates the http-listener subelements of the given http-service
276      * element, and creates a corresponding Tomcat Connector for each.
277      *
278      * @param httpService The http-service element
279      */

280     public void createConnectors(HttpService httpService) {
281         HttpListener[] httpListeners = httpService.getHttpListener();
282         
283         // Attach http-listeners to Engine
284
if (httpListeners != null){
285             for (int i=0; i< httpListeners.length; i++) {
286                 createConnector(httpListeners[i],httpService);
287             }
288         }
289         setDefaultRedirectPort(defaultRedirectPort);
290     }
291
292     
293     /**
294      * Use an http-listener subelements and creates a corresponding
295      * Tomcat Connector for each.
296      *
297      * @param httpService The http-service element
298      * @param httpListener the configuration element.
299      */

300     public PECoyoteConnector createConnector(HttpListener httpListener,
301                                              HttpService httpService){
302                                  
303         int port = 8080;
304         PECoyoteConnector connector;
305         
306         checkHostnameUniqueness(httpListener.getId(), httpService);
307
308         try {
309             port = Integer.parseInt(httpListener.getPort());
310         } catch (NumberFormatException JavaDoc nfe) {
311             String JavaDoc msg = _rb.getString("pewebcontainer.http_listener.invalid_port");
312             msg = MessageFormat.format(msg,
313                                        new Object JavaDoc[] {httpListener.getPort(),
314                                        httpListener.getId() });
315             throw new IllegalArgumentException JavaDoc(msg);
316         }
317
318         /*
319          * Create Connector. Connector is SSL-enabled if
320          * 'security-enabled' attribute in <http-listener>
321          * element is set to TRUE.
322          */

323         boolean isSecure = httpListener.isSecurityEnabled();
324         if (isSecure && defaultRedirectPort == -1) {
325             defaultRedirectPort = port;
326         }
327         String JavaDoc address = httpListener.getAddress();
328         if ("any".equals(address) || "ANY".equals(address)
329                 || "INADDR_ANY".equals(address)) {
330             address = null;
331             /*
332              * Setting 'address' to NULL will cause Tomcat to pass a
333              * NULL InetAddress argument to the java.net.ServerSocket
334              * constructor, meaning that the server socket will accept
335              * connections on any/all local addresses.
336              */

337         }
338
339         connector =
340             (PECoyoteConnector)_embedded.createConnector(address,port,
341                                                          isSecure);
342         connector.setName(httpListener.getId());
343
344         configureConnector(connector,httpListener,isSecure,httpService);
345
346         if ( _logger.isLoggable(Level.FINE)){
347             _logger.log(Level.FINE, "create.listenerport",
348                 new Object JavaDoc[] {new Integer JavaDoc(port), connector});
349         }
350
351         _embedded.addConnector(connector);
352
353         connectorMap.put(httpListener.getId(), connector);
354
355         // If we already know the redirect port, then set it now
356
// This situation will occurs when dynamic reconfiguration occurs
357
if ( defaultRedirectPort != -1 ){
358             connector.setRedirectPort(defaultRedirectPort);
359         }
360
361         return connector;
362     }
363     
364
365     /**
366      * Assigns the given redirect port to each Connector whose corresponding
367      * http-listener element in domain.xml does not specify its own
368      * redirect-port attribute.
369      *
370      * The given defaultRedirectPort corresponds to the port number of the
371      * first security-enabled http-listener in domain.xml.
372      *
373      * This method does nothing if none of the http-listener elements is
374      * security-enabled, in which case Tomcat's default redirect port (443)
375      * will be used.
376      *
377      * @param defaultRedirectPort The redirect port to be assigned to any
378      * Connector object that doesn't specify its own
379      */

380     private void setDefaultRedirectPort(int defaultRedirectPort) {
381         if (defaultRedirectPort != -1) {
382             Connector[] connectors = _embedded.getConnectors();
383             for (int i=0; i<connectors.length; i++) {
384                 if (connectors[i].getRedirectPort() == -1) {
385                     connectors[i].setRedirectPort(defaultRedirectPort);
386                 }
387             }
388         }
389     }
390
391
392     /*
393      * Creates Tomcat Engine.
394      */

395     protected void createEngine(){
396
397         String JavaDoc engineName = "com.sun.appserv";
398
399         Engine engine = _embedded.createEngine();
400         _embedded.addEngine(engine);
401
402         ((StandardEngine)engine).setName(engineName);
403         if (isTomcatUsingDefaultDomain()) {
404             ((StandardEngine)engine).setDomain(
405                         _serverContext.getDefaultDomainName());
406         } else {
407             ((StandardEngine)engine).setDomain(engineName);
408         }
409         _logger.log(Level.FINE, "Creating Engine " + engineName);
410     }
411     
412     
413     /**
414      * Enumerates the virtual-server subelements of the given http-service
415      * element, and creates a corresponding Tomcat Host for each.
416      *
417      * @param httpService The http-service element
418      */

419     public void createHost(
420                     com.sun.enterprise.config.serverbeans.VirtualServer vse,
421                     ConfigContext configContext,
422                     boolean enableMonitoring) throws ConfigException{
423                         
424          Config config = ServerBeansFactory.getConfigBean(configContext);
425          
426          VirtualServer vs = createHost(config.getHttpService(),
427                                        vse,
428                                        installAccessLogValve);
429          
430          loadDefaultWebModule(vs,
431                               ServerBeansFactory.getServerBean(configContext));
432          
433          if ( enableMonitoring ){
434              enableVirtualServerMonitoring(vs);
435          }
436     }
437     
438     
439     /**
440      * Enumerates the virtual-server subelements of the given http-service
441      * element, and creates a corresponding Tomcat Host for each.
442      *
443      * @param httpService The http-service element
444      * @param configureAccessLog Indicates whether access log needs to be
445      * added
446      */

447     protected void createHosts(HttpService httpService,
448                                boolean configureAccessLog) {
449
450         com.sun.enterprise.config.serverbeans.VirtualServer[] vses
451             = httpService.getVirtualServer();
452         for (int j = 0; j < vses.length; j++) {
453             createHost(httpService,vses[j], configureAccessLog);
454         }
455     }
456           
457     
458     /**
459      * Creates a corresponding Tomcat Host from a virtual-server config bean.
460      *
461      * Note: if you add supports for a new property, you MUST also add the
462      * logic in updateHostProperties method.
463      *
464      * @param httpService The http-service element
465      * @param vse The virtual-server configuration bean.
466      * @param configureAccessLog Indicates whether access log needs to be
467      * added
468      */

469     protected VirtualServer createHost(
470                        HttpService httpService,
471                        com.sun.enterprise.config.serverbeans.VirtualServer vse,
472                        boolean configureAccessLog){
473             
474         Engine[] engines = _embedded.getEngines();
475         String JavaDoc docroot = null;
476         MimeMap mm = null;
477         String JavaDoc vs_id = vse.getId();
478
479         ElementProperty element = vse.getElementPropertyByName("docroot");
480         if ( element != null){
481             docroot = element.getValue();
482         }
483         
484         validateDocroot(docroot,
485                         vs_id,
486                         vse.getDefaultWebModule());
487
488         VirtualServer vs = createVS(vs_id, vse, docroot,
489                                     vse.getLogFile(), mm,
490                                     httpService.getHttpProtocol());
491
492         // cache control
493
ElementProperty cacheProp = vse.getElementPropertyByName(
494                                                     "setCacheControl");
495         if ( cacheProp != null ){
496             configureCacheControl(cacheProp.getValue(), vs);
497         }
498
499         if (configureAccessLog){
500             setAccessLog(vs, vs_id, vse, httpService);
501         }
502         if (_logger.isLoggable(Level.FINEST)) {
503             _logger.log(Level.FINEST, "Created virtual server " + vs_id);
504         }
505
506         /*
507          * We must configure the Host with its associated port numbers and
508          * alias names before adding it as an engine child and thereby
509          * starting it, because a MapperListener, which is associated with
510          * an HTTP listener and receives notifications about Host
511          * registrations, relies on these Host properties in order to determine
512          * whether a new Host needs to be added to the HTTP listener's Mapper.
513          */

514         configureHost(vs, httpService);
515
516         // Add Host to Engine
517
engines[0].addChild(vs);
518
519         return vs;
520     }
521
522     
523     /**
524      * Configure cache control property of a virtual-server
525      */

526     protected void configureCacheControl(String JavaDoc cacheControl, VirtualServer vs){
527         if (cacheControl != null) {
528             List JavaDoc values = StringUtils.parseStringList(cacheControl,
529                                                       ",");
530             if (values != null && !values.isEmpty()) {
531                 String JavaDoc[] cacheControls = new String JavaDoc[values.size()];
532                 vs.setCacheControls((String JavaDoc[]) values.toArray(
533                                                     cacheControls));
534             }
535         }
536     }
537     
538     
539     /**
540      * Validate the docroot properties of a virtual-server.
541      */

542     protected boolean validateDocroot(String JavaDoc docroot, String JavaDoc vs_id,
543                                       String JavaDoc defaultWebModule){
544         
545         // docroot vs default-web-module
546
if (docroot != null ) {
547             // If the docroot is invalid and there is no default module,
548
// stop the process.
549
boolean isValid = new File JavaDoc(docroot).exists();
550             if ( !isValid && defaultWebModule == null){
551
552                 String JavaDoc msg =
553                     _rb.getString("pewebcontainer.virtual_server.invalid_docroot");
554                 msg = MessageFormat.format(msg,
555                                         new Object JavaDoc[] { vs_id , docroot});
556                 throw new IllegalArgumentException JavaDoc(msg);
557             } else if (!isValid) {
558
559                 _logger.log(Level.WARNING, "virtual-server " + vs_id
560                             + " has an invalid docroot: " + docroot );
561             }
562         } else if (defaultWebModule == null) {
563             String JavaDoc msg = _rb.getString("pewebcontainer.virtual_server.missing_docroot");
564             msg = MessageFormat.format(msg, new Object JavaDoc[] { vs_id });
565             throw new IllegalArgumentException JavaDoc(msg);
566         }
567         return true;
568     }
569     
570
571     /**
572      * Configures the given virtual server.
573      *
574      * @param vs The virtual server to be configured
575      * @param httpService The http-service element of which the given
576      * virtual server is a subelement
577      */

578     protected void configureHost(VirtualServer vs, HttpService httpService) {
579        com.sun.enterprise.config.serverbeans.VirtualServer vsBean
580                                                                  = vs.getBean();
581        
582         configureHostAlias(vs);
583
584         // Set the ports with which this virtual server is associated
585
List JavaDoc<String JavaDoc> listeners = StringUtils.parseStringList(
586                                                 vsBean.getHttpListeners(), ",");
587         if (listeners == null) {
588             return;
589         }
590         
591         HttpListener[] httpListeners = new HttpListener[listeners.size()];
592         for (int i=0; i < listeners.size(); i++){
593             httpListeners[i] = httpService.getHttpListenerById(listeners.get(i));
594         }
595                 
596         configureHostListener(vs, httpListeners);
597     }
598         
599     
600     /**
601      * Configure virtual-server alias attribute.
602      * @param vs the virtual-server.
603      */

604     protected void configureHostAlias(VirtualServer vs){
605        com.sun.enterprise.config.serverbeans.VirtualServer vsBean
606             = vs.getBean();
607
608         // Add each host name from the 'hosts' attribute as an alias
609
List JavaDoc hosts = StringUtils.parseStringList(vsBean.getHosts(), ",");
610         String JavaDoc alias;
611         for (int i=0; i < hosts.size(); i++ ){
612             alias = hosts.get(i).toString();
613             if ( !alias.equalsIgnoreCase("localhost.localdomain")){
614                 vs.addAlias( alias );
615             }
616         }
617     }
618     
619     
620     /**
621      * Configure virtual-server's http-listener
622      * @param vs the virtual-server
623      * @param httpListeners the http-listener associated with the virtual-server
624      */

625     protected void configureHostListener(VirtualServer vs,
626                                          HttpListener[] httpListeners){
627        
628        String JavaDoc listener;
629        int[] ports = new int[httpListeners.length];
630        PECoyoteConnector conn;
631        int j=0;
632        
633        for (int i=0; i < httpListeners.length; i++){
634             listener = httpListeners[i].getId();
635                                 
636             conn = connectorMap.get(listener);
637             ports[j++] = conn.getPort();
638             if (!httpListeners[i].isEnabled()){
639                 if ( ( vs.getName().equalsIgnoreCase(ADMIN_VS) ) ){
640                     throw new java.lang.IllegalArgumentException JavaDoc(
641                         "http-listener "
642                         + ADMIN_VS + " enabled property cannot be modified");
643                 }
644             }
645         }
646         vs.setPorts(ports);
647     }
648     
649     
650     /**
651      * Log any unsupported domain.xml attribute or element.
652      */

653     private final void configureNotSupported(HttpService httpService){
654
655         if (!_logger.isLoggable(Level.FINE)) {
656             return;
657         }
658         
659         if ( httpService.getHttpFileCache() != null ) {
660             if ( httpService.getHttpFileCache().getHashInitSize() != null) {
661                 _logger.log(Level.FINE,
662                            "pewebcontainer.unsupportedAttribute.hash-init-size");
663             }
664
665             HttpListener[] httpListeners = httpService.getHttpListener();
666             for ( HttpListener httpListener: httpListeners){
667                 if ( httpListener.getFamily() != null ){
668                     _logger.log(Level.FINE,
669                             "pewebcontainer.unsupportedAttribute.family");
670                 }
671
672                 if ( httpListener.getAttributeValue("blocking-enabled") != null){
673                     _logger.log(Level.FINE,
674                          "pewebcontainer.unsupportedAttribute.blocking-enabled");
675                 }
676
677                 if ( httpListener.getExternalPort() != null ){
678                     _logger.log(Level.FINE,
679                             "pewebcontainer.unsupportedAttribute.external-port");
680                 }
681             }
682         }
683         
684         if ( httpService.getHttpProtocol() != null ){
685             if ( httpService.getHttpProtocol().getVersion() != null) {
686                 _logger.log(Level.FINE,
687                             "pewebcontainer.unsupportedAttribute.version");
688             }
689
690             if ( httpService.getHttpProtocol().getAttributeValue("ssl-enabled")
691                     != null) {
692                 _logger.log(Level.FINE,
693                             "pewebcontainer.unsupportedAttribute.ssl-enabled");
694             }
695         }
696     }
697     
698     
699     
700
701     /**
702      * Create a PEWebContainer object
703      */

704     public static WebContainer createInstance(ServerContext context) {
705         // Create the web container associated with this configuration
706
webContainer = new PEWebContainer(new String JavaDoc("0"), context);
707         _logger.log(Level.FINE, "Creating new instance of PEWebContainer.");
708         
709         // Initialize the Tomcat internal's object.
710
((PEWebContainer)webContainer).init(context);
711         _logger.log(Level.FINE, "Initialization of PEWebContainer.");
712         return webContainer;
713     }
714
715
716     /**
717      * Start the web container
718      */

719     public void startInstance() throws ServerLifecycleException {
720         _logger.log(Level.INFO, "pewebcontainer.start");
721         try {
722             super.start();
723          } catch (LifecycleException le) {
724
725              // check if there is an embedded exception, if so, throw that
726
Throwable JavaDoc ex = le.getThrowable();
727              if (ex == null)
728                  ex = le;
729
730              String JavaDoc msg = _rb.getString("webcontainer.startError");
731              throw new ServerLifecycleException(msg, ex);
732         }
733
734         // the server has started up, now enable monitoring.
735
enableVirtualServerMonitoring();
736         enableHttpMonitoring();
737     }
738
739
740     /**
741      * Stop the web container
742      */

743     public void stopInstance() throws ServerLifecycleException {
744         _logger.log(Level.INFO, "pewebcontainer.stop");
745         try {
746             super.stop();
747         } catch (LifecycleException le) {
748             // check if there is an embedded exception, if so, throw that
749
Throwable JavaDoc ex = le.getThrowable();
750             if (ex == null)
751                 ex = le;
752
753             String JavaDoc msg = _rb.getString("webcontainer.stopError");
754             throw new ServerLifecycleException(msg, ex);
755         }
756     }
757
758
759     public static PEWebContainer getPEWebContainer() {
760         return (PEWebContainer)webContainer;
761     }
762  
763
764     /*
765      * Configures the given virtual server with the access log specified in
766      * the domain.xml.
767      *
768      * @param vs The virtual server instance
769      * @param vsId The virtual server id
770      * @param vsBean The virtual server bean containing info about the access
771      * log
772      */

773     protected void setAccessLog(
774                 StandardHost vs,
775                 String JavaDoc vsId,
776                 com.sun.enterprise.config.serverbeans.VirtualServer vsBean,
777                 HttpService httpService) {
778
779         AccessLog accessLogConfig = httpService.getAccessLog();
780
781         /*
782          * Determine the virtual server's access log directory, which may be
783          * specified in two places:
784          *
785          * 1. <virtual-server>
786          * <http-access-log log-directory="..."/>
787          * </virtual-server>
788          *
789          * 2. <virtual-server>
790          * <property name="accesslog" value="..."/>
791          * </virtual-server>
792          *
793          * If both have been specified, the latter takes precedence.
794          */

795         String JavaDoc accessLog = "access";
796         if ( vsBean.getElementPropertyByName("accesslog") != null) {
797             accessLog = vsBean.getElementPropertyByName("accesslog").getValue();
798         } else if (vsBean.getHttpAccessLog() != null) {
799             accessLog = vsBean.getHttpAccessLog().getLogDirectory();
800         }
801         if (accessLog == null) {
802             return;
803         }
804
805         File JavaDoc dir = new File JavaDoc(accessLog);
806         if (!dir.isAbsolute()) {
807             /*
808              * If accesslog is relative, turn it into an absolute path by
809              * prepending log-root of domain element
810              */

811             String JavaDoc logRoot = domain.getLogRoot();
812             if (logRoot != null) {
813                 dir = new File JavaDoc(logRoot, accessLog);
814             } else {
815                 dir = new File JavaDoc(instance.getInstancesRoot(), accessLog);
816             }
817         }
818             
819         if (_logger.isLoggable(Level.FINE)) {
820             _logger.log(Level.FINE,
821                         "Setting accesslog directory for virtual "
822                         + "server '" + vsId + "' to "
823                         + dir.getAbsolutePath());
824     }
825
826         WebContainerFeatureFactory fac = _serverContext.
827             getPluggableFeatureFactory().getWebContainerFeatureFactory();
828         PEAccessLogValve accessLogValve = new PEAccessLogValve();
829         accessLogValve.setDirectory(dir.getAbsolutePath());
830         accessLogValve.setPrefix(vsId + fac.getDefaultAccessLogPrefix());
831         accessLogValve.setPattern("common");
832
833         HttpProtocol httpProtocol = httpService.getHttpProtocol();
834         if (httpProtocol != null) {
835             accessLogValve.setResolveHosts(httpProtocol.isDnsLookupEnabled());
836         } else {
837             accessLogValve.setResolveHosts(false);
838         }
839
840         // access-log format
841
String JavaDoc format = null;
842         if (accessLogConfig != null) {
843             format = accessLogConfig.getFormat();
844         } else {
845         format = AccessLog.getDefaultFormat();
846         }
847         accessLogValve.setPattern(format);
848                        
849         // rotation-enabled
850
if (accessLogConfig != null) {
851             accessLogValve.setRotatable(accessLogConfig.isRotationEnabled());
852         } else {
853         accessLogValve.setRotatable(
854                 Boolean.valueOf(AccessLog.getDefaultRotationEnabled()).booleanValue());
855         }
856
857         // rotation-interval
858
int rotationInterval = 0;
859         if (accessLogConfig != null) {
860             String JavaDoc s = accessLogConfig.getRotationIntervalInMinutes();
861             rotationInterval = Integer.parseInt(s) * 60;
862         } else if (vsBean.getElementPropertyByName("accessLogWriteInterval") != null
863                     || accessLogWriteInterval != null) {
864             if (vsBean.getElementPropertyByName("accessLogWriteInterval") != null) {
865                 accessLogWriteInterval = vsBean.getElementPropertyByName(
866                     "accessLogWriteInterval").getValue();
867             }
868             if (accessLogWriteInterval != null) {
869                 rotationInterval = Integer.parseInt(accessLogWriteInterval);
870             }
871         } else {
872             rotationInterval = fac.getDefaultRotationIntervalInMinutes() * 60;
873         }
874         accessLogValve.setRotationInterval(rotationInterval);
875
876         // If the property is defined under virtual-server, override the one
877
// defined under http-service.
878
String JavaDoc acWriteInterval = accessLogWriteInterval;
879         if (vsBean.getElementPropertyByName("accessLogWriteInterval") != null){
880             acWriteInterval = vsBean.getElementPropertyByName(
881                 "accessLogWriteInterval").getValue();
882         }
883          
884         // If the property is defined under virtual-server, override the one
885
// defined under http-service.
886
String JavaDoc acBufferSize = accessLogBufferSize;
887         if ( vsBean.getElementPropertyByName("accessLogBufferSize") != null){
888             acBufferSize = vsBean.getElementPropertyByName
889                 ("accessLogBufferSize").getValue();
890         }
891
892         if (acBufferSize != null){
893             try{
894                 accessLogValve.setBufferSize(
895                     Integer.parseInt(acBufferSize));
896             } catch (NumberFormatException JavaDoc ex){
897                 _logger.log(Level.WARNING,
898                     "pewebcontainer.invalid_accessLog_bufferSize",
899                     acBufferSize);
900             }
901         }
902
903         if (acWriteInterval != null){
904             try{
905                 accessLogValve.setWriterInterval(
906                     Integer.parseInt(acWriteInterval));
907             } catch (NumberFormatException JavaDoc ex){
908                 _logger.log(Level.WARNING,
909                     "pewebcontainer.invalid_accessLog_writerInterval",
910                     acWriteInterval);
911             }
912         }
913
914         // rotation-datestamp
915
String JavaDoc rotationDateStamp = null;
916         if (accessLogConfig != null) {
917             rotationDateStamp = accessLogConfig.getRotationSuffix();
918         } else {
919             rotationDateStamp = fac.getDefaultAccessLogDateStampPattern();
920         }
921         if ("%YYYY;%MM;%DD;-%hh;h%mm;m%ss;s".equals(rotationDateStamp)) {
922             /*
923              * Modify the default rotation suffix pattern specified in the
924              * sun-domain DTD in such a way that it is accepted by
925              * java.text.SimpleDateFormat. We support only those patterns
926              * accepted by java.text.SimpleDateFormat.
927              */

928             rotationDateStamp = "yyyyMMdd-HH'h'mm'm'ss's'";
929         }
930         accessLogValve.setFileDateFormat(rotationDateStamp);
931
932         // rotation-suffix
933
accessLogValve.setSuffix(fac.getDefaultAccessLogSuffix());
934
935         accessLogValve.setAddDateStampToFirstAccessLogFile(
936             fac.getAddDateStampToFirstAccessLogFile());
937
938         vs.addValve(accessLogValve);
939     }
940
941
942     /*
943      * Configures the given connector.
944      *
945      * @param connector The connector to configure
946      * @param httpListener The http-listener that corresponds to the given
947      * connector
948      * @param isSecure true if the connector is security-enabled, false
949      * otherwise
950      * @param httpServiceProps The http-service properties
951      */

952     private void configureConnector(PECoyoteConnector connector,
953                                     HttpListener httpListener,
954                                     boolean isSecure,
955                                     HttpService httpService) {
956
957         configureConnectionPool(connector, httpService.getConnectionPool());
958
959         WebContainerFeatureFactory wcFeatureFactory = _serverContext.
960             getPluggableFeatureFactory().getWebContainerFeatureFactory();
961         String JavaDoc sslImplementationName =
962             wcFeatureFactory.getSSLImplementationName();
963         
964         if (sslImplementationName != null) {
965             connector.setProperty("sSLImplementation",sslImplementationName);
966         }
967         
968         connector.setDomain(_serverContext.getDefaultDomainName());
969         connector.setLogger(_logger);
970         
971         configureSSL(connector, httpListener);
972         configureKeepAlive(connector, httpService.getKeepAlive());
973         configureHttpProtocol(connector, httpService.getHttpProtocol());
974         configureRequestProcessing(httpService.getRequestProcessing(),connector);
975         configureFileCache(connector, httpService.getHttpFileCache());
976         
977         // default-virtual-server
978
connector.setDefaultHost(httpListener.getDefaultVirtualServer());
979
980         // xpoweredBy
981
connector.setXpoweredBy(httpListener.isXpoweredBy());
982
983         // enabled/disabled
984
connector.setIsEnabled(httpListener.isEnabled());
985         
986         // Application root
987
connector.setWebAppRootPath(getModulesRoot());
988         
989         // server-name (may contain scheme and colon-separated port number)
990
String JavaDoc serverName = httpListener.getServerName();
991         if (serverName != null && serverName.length() > 0) {
992             // Ignore scheme, which was required for webcore issued redirects
993
// in 8.x EE
994
if (serverName.startsWith("http://")) {
995                 serverName = serverName.substring("http://".length());
996             } else if (serverName.startsWith("https://")) {
997                 serverName = serverName.substring("https://".length());
998             }
999             int index = serverName.indexOf(':');
1000            if (index != -1) {
1001                connector.setProxyName(serverName.substring(0, index).trim());
1002                String JavaDoc serverPort = serverName.substring(index+1).trim();
1003                if (serverPort.length() > 0) {
1004                    try {
1005                        connector.setProxyPort(Integer.parseInt(serverPort));
1006                    } catch (NumberFormatException JavaDoc nfe) {
1007                        _logger.log(Level.SEVERE,
1008                            "pewebcontainer.invalid_proxy_port",
1009                            new Object JavaDoc[] { serverPort, httpListener.getId() });
1010            }
1011                }
1012            } else {
1013                connector.setProxyName(serverName);
1014            }
1015        }
1016
1017        // redirect-port
1018
String JavaDoc redirectPort = httpListener.getRedirectPort();
1019        if (redirectPort != null && !redirectPort.equals("")) {
1020            try {
1021                connector.setRedirectPort(Integer.parseInt(redirectPort));
1022            } catch (NumberFormatException JavaDoc nfe) {
1023                _logger.log(Level.WARNING,
1024                    "pewebcontainer.invalid_redirect_port",
1025                    new Object JavaDoc[] {
1026                        redirectPort,
1027                        httpListener.getId(),
1028                        Integer.toString(connector.getRedirectPort()) });
1029            }
1030        } else {
1031            connector.setRedirectPort(-1);
1032        }
1033
1034        // acceptor-threads
1035
String JavaDoc acceptorThreads = httpListener.getAcceptorThreads();
1036        if (acceptorThreads != null) {
1037            try {
1038                connector.setSelectorReadThreadsCount
1039                    (Integer.parseInt(acceptorThreads));
1040            } catch (NumberFormatException JavaDoc nfe) {
1041                _logger.log(Level.WARNING,
1042                    "pewebcontainer.invalid_acceptor_threads",
1043                    new Object JavaDoc[] {
1044                        acceptorThreads,
1045                        httpListener.getId(),
1046                        Integer.toString(connector.getMaxProcessors()) });
1047            }
1048        }
1049        
1050        // Configure Connector with keystore password and location
1051
if (isSecure) {
1052
1053            // Get keystore location
1054
String JavaDoc ksFile = System.getProperty("javax.net.ssl.keyStore");
1055            if (ksFile != null) {
1056                connector.setKeystoreFile(ksFile);
1057            }
1058
1059            /*
1060             * Get keystore password from password.conf file.
1061             * Notice that JSSE, the underlying SSL implementation,
1062             * currently does not support individual key entry passwords
1063             * that are different from the keystore password.
1064             */

1065            String JavaDoc ksPasswd = null;
1066            try {
1067                ksPasswd = PasswordConfReader.getKeyStorePassword();
1068            } catch (IOException JavaDoc ioe) {
1069                // Ignore
1070
}
1071
1072            // Get keystore password from system property
1073
if (ksPasswd == null) {
1074                ksPasswd = System.getProperty(
1075                    "javax.net.ssl.keyStorePassword");
1076            }
1077
1078            if (ksPasswd != null) {
1079                try {
1080                    connector.setKeystorePass(ksPasswd);
1081                } catch (Exception JavaDoc e) {
1082                    _logger.log(Level.SEVERE,
1083                        "pewebcontainer.http_listener_keystore_password_exception",
1084                        e);
1085                }
1086            }
1087        }
1088
1089        // Configure Connector with <http-listener> properties
1090
// START S1AS8 4861933
1091
ElementProperty prop = httpListener.getElementPropertyByName(
1092                                                        "chunkingDisabled");
1093        if (prop == null) {
1094            prop = httpListener.getElementPropertyByName("chunking-disabled");
1095        }
1096        if (prop != null) {
1097            connector.setChunkingDisabled(
1098                ConfigBean.toBoolean(prop.getValue()));
1099        }
1100        // END S1AS8 4861933
1101

1102        configureHttpServiceProperties(httpService,connector);
1103        // Override http-service property if defined.
1104
configureHttpListenerProperties(httpListener,connector);
1105
1106    }
1107
1108    
1109    /**
1110     * Configure http-listener properties
1111     */

1112    public void configureHttpListenerProperties(HttpListener httpListener,
1113                                                PECoyoteConnector connector){
1114        // Configure Connector with <http-service> properties
1115
ElementProperty[] httpListenerProps = httpListener.getElementProperty();
1116        if (httpListenerProps != null) {
1117            for (int i=0; i< httpListenerProps.length; i++) {
1118                String JavaDoc propName = httpListenerProps[i].getName();
1119                String JavaDoc propValue = httpListenerProps[i].getValue();
1120                if (!configureHttpListenerProperty(propName,
1121                                                   propValue,
1122                                                   connector)){
1123                    _logger.log(Level.WARNING,
1124                        "pewebcontainer.invalid_http_listener_property",
1125                        propName);
1126                }
1127            }
1128        }
1129    }
1130       
1131    
1132    /**
1133     * Configure http-listener property.
1134     * return true if the property exists and has been set.
1135     */

1136    protected boolean configureHttpListenerProperty(
1137                                            String JavaDoc propName,
1138                                            String JavaDoc propValue,
1139                                            PECoyoteConnector connector){
1140                                                        
1141        if ("bufferSize".equals(propName)) {
1142            connector.setBufferSize(Integer.parseInt(propValue));
1143            return true;
1144        } else if ("recycle-objects".equals(propName)) {
1145            connector
1146                .setRecycleObjects(ConfigBean.toBoolean(propValue));
1147            return true;
1148        } else if ("reader-threads".equals(propName)) {
1149            connector
1150                .setMaxReadWorkerThreads(Integer.parseInt(propValue));
1151            return true;
1152        } else if ("acceptor-queue-length".equals(propName)) {
1153            connector
1154                .setMinAcceptQueueLength(Integer.parseInt(propValue));
1155            return true;
1156        } else if ("reader-queue-length".equals(propName)) {
1157            connector
1158                .setMinReadQueueLength(Integer.parseInt(propValue));
1159            return true;
1160        } else if ("use-nio-direct-bytebuffer".equals(propName)) {
1161            connector
1162                .setUseDirectByteBuffer(ConfigBean.toBoolean(propValue));
1163            return true;
1164        } else if ("maxKeepAliveRequests".equals(propName)) {
1165            connector
1166                .setMaxKeepAliveRequests(Integer.parseInt(propValue));
1167            return true;
1168        } else if ("reader-selectors".equals(propName)) {
1169            connector
1170                .setSelectorReadThreadsCount(Integer.parseInt(propValue));
1171            return true;
1172        } else if ("authPassthroughEnabled".equals(propName)) {
1173            connector.setAuthPassthroughEnabled(
1174                                        ConfigBean.toBoolean(propValue));
1175            return true;
1176        } else if ("proxyHandler".equals(propName)) {
1177            setProxyHandler(connector, propValue);
1178            return true;
1179        } else if ("uriEncoding".equals(propName)) {
1180            connector.setURIEncoding(propValue);
1181            return true;
1182        } else {
1183            return false;
1184        }
1185    }
1186    
1187
1188    /**
1189     * Configure http-service properties.
1190     */

1191    public void configureHttpServiceProperties(HttpService httpService,
1192                                               PECoyoteConnector connector){
1193        // Configure Connector with <http-service> properties
1194
ElementProperty[] httpServiceProps = httpService.getElementProperty();
1195
1196        // Set default ProxyHandler impl, may be overriden by
1197
// proxyHandler property
1198
connector.setProxyHandler(new ProxyHandlerImpl());
1199
1200        if (httpServiceProps != null) {
1201            for (int i=0; i<httpServiceProps.length; i++) {
1202                String JavaDoc propName = httpServiceProps[i].getName();
1203                String JavaDoc propValue = httpServiceProps[i].getValue();
1204                               
1205                if (configureHttpListenerProperty(propName,
1206                                                  propValue,
1207                                                  connector)){
1208                    continue;
1209                }
1210                
1211                if ("connectionTimeout".equals(propName)) {
1212                    connector.setConnectionTimeout(
1213                                                Integer.parseInt(propValue));
1214                } else if ("tcpNoDelay".equals(propName)) {
1215                    connector.setTcpNoDelay(ConfigBean.toBoolean(propValue));
1216                } else if ("traceEnabled".equals(propName)) {
1217                    connector.setAllowTrace(ConfigBean.toBoolean(propValue));
1218                } else if ("accessLoggingEnabled".equals(propName)) {
1219                    installAccessLogValve = ConfigBean.toBoolean(propValue);
1220                } else if ("accessLogWriteInterval".equals(propName)) {
1221                    accessLogWriteInterval = propValue;
1222                } else if ("accessLogBufferSize".equals(propName)) {
1223                    accessLogBufferSize = propValue;
1224                } else if ("authPassthroughEnabled".equals(propName)) {
1225                    connector.setAuthPassthroughEnabled(
1226                                    ConfigBean.toBoolean(propValue));
1227                } else if ("ssl-session-timeout".equals(propName)) {
1228                    connector.setSSLSessionTimeout(propValue);
1229                } else if ("ssl3-session-timeout".equals(propName)) {
1230                    connector.setSSL3SessionTimeout(propValue);
1231                } else if ("ssl-cache-entries".equals(propName)) {
1232                    connector.setSSLSessionCacheSize(propValue);
1233                } else if ("proxyHandler".equals(propName)) {
1234                    setProxyHandler(connector, propValue);
1235                } else {
1236                    _logger.log(Level.WARNING,
1237                        "pewebcontainer.invalid_http_service_property",
1238                        httpServiceProps[i].getName());
1239                }
1240            }
1241        }
1242    }
1243
1244
1245    /*
1246     * Parses the given comma-separated string of cipher suite names,
1247     * converts each cipher suite that is enabled (i.e., not preceded by a
1248     * '-') to the corresponding JSSE cipher suite name, and returns a string
1249     * of comma-separated JSSE cipher suite names.
1250     *
1251     * @param sslCiphers String of SSL ciphers to parse
1252     *
1253     * @return String of comma-separated JSSE cipher suite names, or null if
1254     * none of the cipher suites in the given string are enabled or can be
1255     * mapped to corresponding JSSE cipher suite names
1256     */

1257    private String JavaDoc getJSSECiphers(String JavaDoc ciphers) {
1258
1259        String JavaDoc cipher = null;
1260        StringBuffer JavaDoc enabledCiphers = null;
1261        boolean first = true;
1262
1263        int index = ciphers.indexOf(',');
1264        if (index != -1) {
1265            int fromIndex = 0;
1266            while (index != -1) {
1267                cipher = ciphers.substring(fromIndex, index).trim();
1268                if (cipher.length() > 0 && !cipher.startsWith("-")) {
1269                    if (cipher.startsWith("+")) {
1270                        cipher = cipher.substring(1);
1271            }
1272                    String JavaDoc jsseCipher = getJSSECipher(cipher);
1273                    if (jsseCipher == null) {
1274                        _logger.log(Level.WARNING,
1275                            "pewebcontainer.unrecognized_cipher", cipher);
1276                    } else {
1277                        if (enabledCiphers == null) {
1278                            enabledCiphers = new StringBuffer JavaDoc();
1279                        }
1280                        if (!first) {
1281                            enabledCiphers.append(", ");
1282                        } else {
1283                            first = false;
1284                        }
1285                        enabledCiphers.append(jsseCipher);
1286                    }
1287                }
1288                fromIndex = index + 1;
1289                index = ciphers.indexOf(',', fromIndex);
1290            }
1291            cipher = ciphers.substring(fromIndex);
1292        } else {
1293            cipher = ciphers;
1294        }
1295
1296        if (cipher != null) {
1297            cipher = cipher.trim();
1298            if (cipher.length() > 0 && !cipher.startsWith("-")) {
1299                if (cipher.startsWith("+")) {
1300                    cipher = cipher.substring(1);
1301                }
1302                String JavaDoc jsseCipher = getJSSECipher(cipher);
1303                if (jsseCipher == null) {
1304                    _logger.log(Level.WARNING,
1305                                "pewebcontainer.unrecognized_cipher", cipher);
1306                } else {
1307                    if (enabledCiphers == null) {
1308                        enabledCiphers = new StringBuffer JavaDoc();
1309                    }
1310                    if (!first) {
1311                        enabledCiphers.append(", ");
1312                    } else {
1313                        first = false;
1314                    }
1315                    enabledCiphers.append(jsseCipher);
1316                }
1317            }
1318        }
1319
1320        return (enabledCiphers == null ? null : enabledCiphers.toString());
1321    }
1322
1323
1324    /*
1325     * Converts the given cipher suite name to the corresponding JSSE cipher.
1326     *
1327     * @param cipher The cipher suite name to convert
1328     *
1329     * @return The corresponding JSSE cipher suite name, or null if the given
1330     * cipher suite name can not be mapped
1331     */

1332    private String JavaDoc getJSSECipher(String JavaDoc cipher) {
1333
1334        String JavaDoc jsseCipher = null;
1335
1336        CipherInfo ci = CipherInfo.getCipherInfo(cipher);
1337        if( ci != null ) {
1338            jsseCipher = ci.getCipherName();
1339        }
1340
1341        return jsseCipher;
1342    }
1343    
1344
1345    /**
1346     * Registers various HTTP related monitoring stats.
1347     */

1348    private void enableHttpMonitoring(){
1349
1350        String JavaDoc vsId;
1351        int port;
1352        HttpService httpService;
1353        
1354        ServerContext sc = getServerContext();
1355        ConfigContext cc = sc.getConfigContext();
1356        MonitoringRegistry mReg = sc.getMonitoringRegistry();
1357        try {
1358            httpService = ServerBeansFactory.getHttpServiceBean(cc);
1359        } catch(ConfigException ce) {
1360            _logger.log(Level.WARNING,
1361                        "Unable to find HttpServiceBean in config",
1362                        ce);
1363            return;
1364        }
1365
1366        // keep-alive
1367
try {
1368            mReg.registerPWCKeepAliveStats(
1369                new PWCKeepAliveStatsImpl(sc.getDefaultDomainName()),
1370                null);
1371        } catch (MonitoringRegistrationException mre) {
1372            String JavaDoc msg = _logger.getResourceBundle().getString(
1373                                            "web.monitoringRegistrationError");
1374            msg = MessageFormat.format(msg,
1375                                       new Object JavaDoc[] { "PWCKeepAliveStats" });
1376            _logger.log(Level.WARNING, msg, mre);
1377        }
1378        
1379        // file-cache
1380
try {
1381            mReg.registerPWCFileCacheStats(
1382                new PWCFileCacheStatsImpl(sc.getDefaultDomainName()),null);
1383        } catch (MonitoringRegistrationException mre) {
1384            String JavaDoc msg = _logger.getResourceBundle().getString(
1385                                            "web.monitoringRegistrationError");
1386            msg = MessageFormat.format(msg,
1387                                       new Object JavaDoc[] { "PWCFileCacheStats" });
1388            _logger.log(Level.WARNING, msg, mre);
1389        }
1390
1391        // pwc-thread-pool
1392
try {
1393            mReg.registerPWCThreadPoolStats(
1394                new PWCThreadPoolStatsImpl(sc.getDefaultDomainName()),
1395                null);
1396        } catch (MonitoringRegistrationException mre) {
1397            String JavaDoc msg = _logger.getResourceBundle().getString(
1398                                            "web.monitoringRegistrationError");
1399            msg = MessageFormat.format(msg,
1400                                       new Object JavaDoc[] { "PWCThreadPoolStats" });
1401            _logger.log(Level.WARNING, msg, mre);
1402        }
1403
1404        // connection-queue
1405
try {
1406            mReg.registerPWCConnectionQueueStats(
1407                new PWCConnectionQueueStatsImpl(sc.getDefaultDomainName()),
1408                null);
1409        } catch (MonitoringRegistrationException mre) {
1410            String JavaDoc msg = _logger.getResourceBundle().getString(
1411                                            "web.monitoringRegistrationError");
1412            msg = MessageFormat.format(msg,
1413                                       new Object JavaDoc[] { "PWCConnectionQueueStats" });
1414            _logger.log(Level.WARNING, msg, mre);
1415        }
1416
1417        com.sun.enterprise.config.serverbeans.VirtualServer[] vs
1418                                            = httpService.getVirtualServer();
1419
1420        HttpListener currentListener;
1421        for(int i = 0; i<vs.length ; i++) {
1422            vsId = vs[i].getId();
1423            if(!vsId.equalsIgnoreCase(ADMIN_VS)) {
1424               
1425                VirtualServer virtualServer =
1426                        (VirtualServer)getEngines()[0].findChild(vsId);
1427
1428                if (virtualServer == null){
1429                    _logger.log(Level.WARNING,
1430                                "Invalid virtual-server: " + vsId);
1431                    continue;
1432                }
1433                List JavaDoc listeners = StringUtils.parseStringList(
1434                                            vs[i].getHttpListeners(), ",");
1435                if(listeners != null) {
1436                    ListIterator JavaDoc iter = listeners.listIterator();
1437                    while(iter.hasNext()) {
1438                       
1439                        currentListener = httpService.getHttpListenerById
1440                                                        (iter.next().toString());
1441
1442            if (currentListener == null)
1443                continue;
1444                        
1445                        enableHttpListenerMonitoring(virtualServer,
1446                                Integer.parseInt(currentListener.getPort()),
1447                                currentListener.getId());
1448                    }
1449                }
1450            }
1451        }
1452    }
1453 
1454    
1455    /**
1456     * Register http-listener monitoring statistics.
1457     */

1458    protected void enableHttpListenerMonitoring(VirtualServer virtualServer,
1459            int port, String JavaDoc httpListenerId){
1460            
1461        PWCRequestStatsImpl pwcRequestStatsImpl =
1462                virtualServer.getPWCRequestStatsImpl();
1463        
1464        if ( pwcRequestStatsImpl == null ){
1465            pwcRequestStatsImpl = new PWCRequestStatsImpl(
1466                    getServerContext().getDefaultDomainName());
1467            virtualServer.setPWCRequestStatsImpl(pwcRequestStatsImpl);
1468        }
1469 
1470        HTTPListenerStatsImpl httpStats;
1471        MonitoringRegistry mReg = getServerContext().getMonitoringRegistry();
1472        String JavaDoc vsId = virtualServer.getID();
1473        
1474        if (isTomcatUsingDefaultDomain()) {
1475            httpStats = new HTTPListenerStatsImpl(
1476                    getServerContext().getDefaultDomainName(),port);
1477        } else {
1478            httpStats = new HTTPListenerStatsImpl(vsId,port);
1479        }
1480
1481        try {
1482            mReg.registerHttpListenerStats(httpStats, httpListenerId, vsId, null);
1483            pwcRequestStatsImpl.addHttpListenerStats(httpStats);
1484        } catch (MonitoringRegistrationException mre) {
1485            String JavaDoc msg =
1486                _logger.getResourceBundle().getString(
1487                    "web.monitoringRegistrationError");
1488            msg = MessageFormat.format(
1489                    msg,
1490                    new Object JavaDoc[] { "HTTPListenerStats" });
1491            _logger.log(Level.WARNING, msg, mre);
1492        }
1493    }
1494    
1495
1496    /*
1497     * Ensures that the host names of all virtual servers associated with the
1498     * HTTP listener with the given listener id are unique.
1499     *
1500     * @param listenerId The id of the HTTP listener whose associated virtual
1501     * servers are checked for uniqueness of host names
1502     * @param httpService The http-service element whose virtual servers are
1503     * checked
1504     */

1505    private void checkHostnameUniqueness(String JavaDoc listenerId,
1506                                         HttpService httpService) {
1507
1508        ArrayList JavaDoc listenerVses = null;
1509
1510        com.sun.enterprise.config.serverbeans.VirtualServer[] vses
1511            = httpService.getVirtualServer();
1512        if (vses == null) {
1513            return;
1514        }
1515
1516        // Determine all the virtual servers associated with the given listener
1517
for (int i=0; i<vses.length; i++) {
1518            List JavaDoc vsListeners =
1519                StringUtils.parseStringList(vses[i].getHttpListeners(), ",");
1520            for (int j=0; vsListeners!=null && j<vsListeners.size(); j++) {
1521                if (listenerId.equals((String JavaDoc)vsListeners.get(j))) {
1522                    if (listenerVses == null) {
1523                        listenerVses = new ArrayList JavaDoc();
1524                    }
1525                    listenerVses.add(vses[i]);
1526                    break;
1527                }
1528            }
1529        }
1530        if (listenerVses == null) {
1531            return;
1532        }
1533
1534        for (int i=0; i<listenerVses.size(); i++) {
1535            com.sun.enterprise.config.serverbeans.VirtualServer vs
1536                = (com.sun.enterprise.config.serverbeans.VirtualServer) listenerVses.get(i);
1537            List JavaDoc hosts = StringUtils.parseStringList(vs.getHosts(), ",");
1538            for (int j=0; hosts!=null && j<hosts.size(); j++) {
1539                String JavaDoc host = (String JavaDoc) hosts.get(j);
1540                for (int k=0; k<listenerVses.size(); k++) {
1541                    if (k <= i) {
1542                        continue;
1543                    }
1544                    com.sun.enterprise.config.serverbeans.VirtualServer otherVs
1545                        = (com.sun.enterprise.config.serverbeans.VirtualServer)
1546                            listenerVses.get(k);
1547                    List JavaDoc otherHosts = StringUtils.parseStringList(otherVs.getHosts(), ",");
1548                    for (int l=0; otherHosts!=null && l<otherHosts.size(); l++) {
1549                        if (host.equals((String JavaDoc) otherHosts.get(l))) {
1550                            _logger.log(Level.SEVERE,
1551                                        "pewebcontainer.duplicate_host_name",
1552                                        new Object JavaDoc[] { host, vs.getId(),
1553                                                       otherVs.getId(),
1554                                                       listenerId });
1555                        }
1556                    }
1557        }
1558            }
1559        }
1560    }
1561
1562
1563    /**
1564     * is Tomcat using default domain name as its domain
1565     */

1566    protected boolean isTomcatUsingDefaultDomain() {
1567        // need to be careful and make sure tomcat jmx mapping works
1568
// since setting this to true might result in undeployment problems
1569
return true;
1570    }
1571
1572
1573    /**
1574     * Overrides the implementation of this method in the WebContainer.java
1575     * superclass by doing nothing.
1576     *
1577     * This is to prevent web modules that are bundled in EARs from being
1578     * loaded twice during startup, since they are already being loaded by
1579     * com.sun.enterprise.server.TomcatApplicationLoader.load(). See 4925655.
1580     */

1581    protected void loadAllJ2EEApplicationWebModules() {
1582        // Do nothing
1583
}
1584    
1585    public static WebContainer getInstance(){
1586        return webContainer;
1587    }
1588
1589
1590    /*
1591     * Enables monitoring of all virtual servers.
1592     */

1593    private void enableVirtualServerMonitoring() {
1594        Engine[] engines = _embedded.getEngines();
1595        for (int j = 0; j < engines.length; j++) {
1596            Container[] hostArray = engines[j].findChildren();
1597            for (int i = 0; i < hostArray.length; i++) {
1598                VirtualServer vs = (VirtualServer) hostArray[i];
1599                enableVirtualServerMonitoring(vs);
1600            }
1601        }
1602    }
1603
1604    
1605    /*
1606     * Enables monitoring of all virtual servers.
1607     */

1608    private void enableVirtualServerMonitoring(VirtualServer vs){
1609        ServerContext sc = getServerContext();
1610        ConfigContext cc = sc.getConfigContext();
1611        MonitoringRegistry monitoringRegistry = sc.getMonitoringRegistry();
1612        
1613        PWCVirtualServerStatsImpl vsStats = new PWCVirtualServerStatsImpl(vs);
1614        try {
1615            monitoringRegistry.registerPWCVirtualServerStats(vsStats,
1616                                                             vs.getID(),
1617                                                             null);
1618        } catch (Exception JavaDoc e) {
1619            _logger.log(Level.WARNING,
1620                        "Unable to register PWCVirtualServerStats for "
1621                        + vs.getID(), e);
1622        }
1623
1624        PWCRequestStatsImpl pwcRequestStatsImpl =
1625                new PWCRequestStatsImpl(sc.getDefaultDomainName());
1626        vs.setPWCRequestStatsImpl(pwcRequestStatsImpl);
1627        
1628        try {
1629            monitoringRegistry.registerPWCRequestStats(pwcRequestStatsImpl,
1630                        vs.getID(),
1631                        null);
1632        } catch (MonitoringRegistrationException mre) {
1633            String JavaDoc msg = _logger.getResourceBundle().getString(
1634                            "web.monitoringRegistrationError");
1635            msg = MessageFormat.format(
1636                            msg,
1637                            new Object JavaDoc[] { "PWCRequestStats" });
1638            _logger.log(Level.WARNING, msg, mre);
1639        }
1640    }
1641    
1642    /*
1643     * Configures the SSL properties on the given PECoyoteConnector from the
1644     * SSL config of the given HTTP listener.
1645     *
1646     * @param connector PECoyoteConnector to configure
1647     * @param httpListener HTTP listener whose SSL config to use
1648     */

1649    private void configureSSL(PECoyoteConnector connector,
1650                              HttpListener httpListener) {
1651
1652        Ssl sslConfig = httpListener.getSsl();
1653        if (sslConfig == null) {
1654            return;
1655        }
1656
1657        // client-auth
1658
if (sslConfig.isClientAuthEnabled()) {
1659            connector.setClientAuth(true);
1660        }
1661
1662        // ssl protocol variants
1663
StringBuffer JavaDoc sslProtocolsBuf = new StringBuffer JavaDoc();
1664        boolean needComma = false;
1665        if (sslConfig.isSsl2Enabled()) {
1666            sslProtocolsBuf.append("SSLv2");
1667            needComma = true;
1668        }
1669        if (sslConfig.isSsl3Enabled()) {
1670            if (needComma) {
1671                sslProtocolsBuf.append(", ");
1672            } else {
1673                needComma = true;
1674            }
1675            sslProtocolsBuf.append("SSLv3");
1676        }
1677        if (sslConfig.isTlsEnabled()) {
1678            if (needComma) {
1679                sslProtocolsBuf.append(", ");
1680            }
1681            sslProtocolsBuf.append("TLSv1");
1682        }
1683        if (sslConfig.isSsl3Enabled() || sslConfig.isTlsEnabled()) {
1684            sslProtocolsBuf.append(", SSLv2Hello");
1685        }
1686
1687        if (sslProtocolsBuf.length() == 0) {
1688            _logger.log(Level.WARNING,
1689                        "pewebcontainer.all_ssl_protocols_disabled",
1690                        httpListener.getId());
1691        } else {
1692            connector.setSslProtocols(sslProtocolsBuf.toString());
1693        }
1694
1695        // cert-nickname
1696
String JavaDoc certNickname = sslConfig.getCertNickname();
1697        if (certNickname != null && certNickname.length() > 0) {
1698            connector.setKeyAlias(sslConfig.getCertNickname());
1699        }
1700
1701        // ssl3-tls-ciphers
1702
String JavaDoc ciphers = sslConfig.getSsl3TlsCiphers();
1703        if (ciphers != null) {
1704            String JavaDoc jsseCiphers = getJSSECiphers(ciphers);
1705            if (jsseCiphers == null) {
1706                _logger.log(Level.WARNING,
1707                            "pewebcontainer.all_ciphers_disabled",
1708                            httpListener.getId());
1709            } else {
1710                connector.setCiphers(jsseCiphers);
1711            }
1712        }
1713    }
1714
1715
1716    /*
1717     * Configures the keep-alive properties on the given PECoyoteConnector
1718     * from the given keep-alive config.
1719     *
1720     * @param connector PECoyoteConnector to configure
1721     * @param keepAlive Keep-alive config to use
1722     */

1723    private void configureKeepAlive(PECoyoteConnector connector,
1724                                    KeepAlive keepAlive) {
1725
1726        // timeout-in-seconds, default is 60 as per sun-domain_1_1.dtd
1727
int timeoutInSeconds = 60;
1728
1729        // max-connections, default is 256 as per sun-domain_1_1.dtd
1730
int maxConnections = 256;
1731
1732        // thread-count, default is 1 as per sun-domain_1_1.dtd
1733
int threadCount = 1;
1734
1735        if (keepAlive != null) {
1736            // timeout-in-seconds
1737
try {
1738            timeoutInSeconds = Integer.parseInt(
1739                                keepAlive.getTimeoutInSeconds());
1740            } catch (NumberFormatException JavaDoc ex) {
1741                String JavaDoc msg = _rb.getString(
1742                    "pewebcontainer.invalidKeepAliveTimeout");
1743                msg = MessageFormat.format(
1744                    msg,
1745                    new Object JavaDoc[] { keepAlive.getTimeoutInSeconds(),
1746                                   Integer.toString(timeoutInSeconds)});
1747                _logger.log(Level.WARNING, msg, ex);
1748            }
1749
1750            // max-connections
1751
try {
1752            maxConnections = Integer.parseInt(
1753                                keepAlive.getMaxConnections());
1754            } catch (NumberFormatException JavaDoc ex) {
1755                String JavaDoc msg = _rb.getString(
1756                    "pewebcontainer.invalidKeepAliveMaxConnections");
1757                msg = MessageFormat.format(
1758                    msg,
1759                    new Object JavaDoc[] { keepAlive.getMaxConnections(),
1760                                   Integer.toString(maxConnections)});
1761                _logger.log(Level.WARNING, msg, ex);
1762            }
1763
1764            // thread-count
1765
try {
1766            threadCount = Integer.parseInt(keepAlive.getThreadCount());
1767            } catch (NumberFormatException JavaDoc ex) {
1768                String JavaDoc msg = _rb.getString(
1769                    "pewebcontainer.invalidKeepAliveThreadCount");
1770                msg = MessageFormat.format(
1771                    msg,
1772                    new Object JavaDoc[] { keepAlive.getThreadCount(),
1773                                   Integer.toString(threadCount)});
1774                _logger.log(Level.WARNING, msg, ex);
1775            }
1776        }
1777        
1778        connector.setKeepAliveTimeoutInSeconds(timeoutInSeconds);
1779        connector.setMaxKeepAliveRequests(maxConnections);
1780        connector.setKeepAliveThreadCount(threadCount);
1781    }
1782    
1783
1784    /*
1785     * Configures the given HTTP connector with connection-pool related info.
1786     */

1787    private void configureConnectionPool(PECoyoteConnector connector,
1788                                         ConnectionPool cp) {
1789        if (cp == null) {
1790            return;
1791        }
1792            
1793        try{
1794            int queueSizeInBytes =
1795                    Integer.parseInt(cp.getQueueSizeInBytes());
1796            if (queueSizeInBytes <= -1){
1797                _logger.log(
1798                    Level.WARNING,
1799                    "pewebcontainer.invalidQueueSizeInBytes",
1800                    new Object JavaDoc[]
1801                        { cp.getQueueSizeInBytes(),
1802                          Integer.toString(
1803                                  connector.getQueueSizeInBytes())});
1804            } else {
1805                connector.setQueueSizeInBytes(queueSizeInBytes);
1806            }
1807        } catch (NumberFormatException JavaDoc ex){
1808            String JavaDoc msg = _rb.getString("pewebcontainer.invalidQueueSizeInBytes");
1809            msg = MessageFormat.format(
1810                msg, new Object JavaDoc[]
1811                    { cp.getDefaultQueueSizeInBytes(),
1812                      Integer.toString(connector.getQueueSizeInBytes())});
1813            _logger.log(Level.WARNING, msg, ex);
1814        }
1815        
1816        
1817        try{
1818            int ssBackLog = Integer.parseInt(cp.getMaxPendingCount());
1819            if (ssBackLog <= 0){
1820                _logger.log(
1821                    Level.WARNING,
1822                    "pewebcontainer.invalidMaxPendingCount",
1823                    new Object JavaDoc[]
1824                        { cp.getMaxPendingCount(),
1825                          Integer.toString(connector.getSocketServerBacklog())});
1826            } else {
1827                connector.setSocketServerBacklog(ssBackLog);
1828            }
1829        } catch (NumberFormatException JavaDoc ex){
1830            String JavaDoc msg = _rb.getString("pewebcontainer.invalidMaxPendingCount");
1831            msg = MessageFormat.format(
1832                msg, new Object JavaDoc[]
1833                    { cp.getMaxPendingCount(),
1834                      Integer.toString(connector.getSocketServerBacklog())});
1835            _logger.log(Level.WARNING, msg, ex);
1836        }
1837        
1838        
1839        try{
1840            int bufferSize =
1841                        Integer.parseInt(cp.getReceiveBufferSizeInBytes());
1842            if ( bufferSize <= 0 ){
1843                _logger.log(
1844                    Level.WARNING,
1845                    "pewebcontainer.invalidBufferSize",
1846                    new Object JavaDoc[]
1847                        { cp.getReceiveBufferSizeInBytes(),
1848                          Integer.toString(connector.getBufferSize())});
1849            } else {
1850                connector.setBufferSize(bufferSize);
1851            }
1852        } catch (NumberFormatException JavaDoc ex) {
1853            String JavaDoc msg = _rb.getString("pewebcontainer.invalidBufferSize");
1854            msg = MessageFormat.format(
1855                msg, new Object JavaDoc[]
1856                    { cp.getReceiveBufferSizeInBytes(),
1857                      Integer.toString(connector.getBufferSize())});
1858            _logger.log(Level.WARNING, msg, ex);
1859        }
1860
1861        try{
1862            int maxHttpHeaderSize =
1863                          Integer.parseInt(cp.getSendBufferSizeInBytes());
1864            if ( maxHttpHeaderSize <= 0 ){
1865                _logger.log(
1866                    Level.WARNING,
1867                    "pewebcontainer.invalidMaxHttpHeaderSize",
1868                    new Object JavaDoc[]
1869                        { cp.getSendBufferSizeInBytes(),
1870                          Integer.toString(connector.getMaxHttpHeaderSize())});
1871            } else {
1872                connector.setMaxHttpHeaderSize(maxHttpHeaderSize);
1873            }
1874        } catch (NumberFormatException JavaDoc ex){
1875            String JavaDoc msg = _rb.getString(
1876                "pewebcontainer.invalidMaxHttpHeaderSize");
1877            msg = MessageFormat.format(
1878                msg, new Object JavaDoc[]
1879                    { cp.getSendBufferSizeInBytes(),
1880                      Integer.toString(connector.getMaxHttpHeaderSize())});
1881            _logger.log(Level.WARNING, msg, ex);
1882        }
1883    }
1884
1885
1886    /**
1887     * Registers listeners for dynamic reconfiguration with the
1888     * AdminEventListenerRegistry
1889     */

1890    public static void registerReconfigListeners(){
1891        AdminEventListenerRegistry.addEventListener(
1892                                    HSVirtualServerEvent.eventType,
1893                                    new VirtualServerReconfig());
1894        AdminEventListenerRegistry.addEventListener(
1895                                    HSHttpListenerEvent.eventType,
1896                                    new HttpListenerReconfig());
1897    }
1898    
1899    
1900    /**
1901     * Delete virtual-server.
1902     * @param httpService element which contains the configuration info.
1903     */

1904    public void deleteHost(HttpService httpService) throws LifecycleException{
1905    
1906        Engine[] engines = _embedded.getEngines();
1907        VirtualServer virtualServer;
1908        com.sun.enterprise.config.serverbeans.VirtualServer[] vses
1909            = httpService.getVirtualServer();
1910        // First we need to find which virtual-server was deleted. In
1911
// reconfig/VirtualServerReconfig, it is impossible to lookup
1912
// the vsBean because the element is removed from domain.xml
1913
// before handleDelete is invoked.
1914
Container[] virtualServers = engines[0].findChildren();
1915        for (int i=0;i < virtualServers.length; i++){
1916            for (int j=0; j < vses.length; j++){
1917                if ( virtualServers[i].getName().equals(vses[j].getId())){
1918                    virtualServers[i] = null;
1919                    break;
1920                }
1921            }
1922        }
1923        
1924        for (int i=0;i < virtualServers.length; i++){
1925            virtualServer = (VirtualServer)virtualServers[i];
1926            
1927            if (virtualServer != null ){
1928                if (virtualServer.getID().equals(ADMIN_VS)) {
1929                    throw new
1930                      LifecycleException("Cannot delete admin virtual-server.");
1931                }
1932
1933                Container[] webModules = virtualServer.findChildren();
1934                for (int j=0; j < webModules.length; j++){
1935                    unloadWebModule(webModules[j].getName(),
1936                                    webModules[j].getName(),
1937                                    virtualServer.getID(),null);
1938                }
1939                virtualServer.stop();
1940                engines[0].removeChild(virtualServer);
1941            }
1942        }
1943    }
1944    
1945    
1946    /**
1947     * Updates a virtual-server element.
1948     *
1949     * @param vsBean the virtual-server config bean.
1950     * @param httpService element which contains the configuration info.
1951     */

1952    public void updateHost(
1953                    com.sun.enterprise.config.serverbeans.VirtualServer vsBean,
1954                    HttpService httpService,
1955                    Server JavaDoc serverBean)
1956                    throws LifecycleException{
1957
1958        Engine[] engines = _embedded.getEngines();
1959        VirtualServer virtualServer =
1960                            (VirtualServer)engines[0].findChild(vsBean.getId());
1961
1962        _embedded.setLogFile(virtualServer,vsBean.getLogFile());
1963        configureVirtualServerState(virtualServer,vsBean);
1964        
1965        virtualServer.clearAliases();
1966        configureHostAlias(virtualServer);
1967
1968        // Set the ports with which this virtual server is associated
1969
List JavaDoc<String JavaDoc> listeners = StringUtils.parseStringList(
1970                                                vsBean.getHttpListeners(), ",");
1971        
1972        if (listeners != null) {
1973            HttpListener[] httpListeners = new HttpListener[listeners.size()];
1974            for (int i=0; i < listeners.size(); i++){
1975                httpListeners[i] =
1976                            httpService.getHttpListenerById(listeners.get(i));
1977            }
1978
1979            // Update listeners
1980
configureHostListener(virtualServer,httpListeners);
1981       
1982            Connector[] connectors = _embedded.findConnectors();
1983            // If new connector where added, make sure it is started.
1984
PECoyoteConnector connector;
1985            for (int i = 0; i < connectors.length; i++) {
1986                connector = (PECoyoteConnector)connectors[i];
1987                // Already started.
1988
if (connector.isAvailable()){
1989                    continue;
1990                }
1991
1992                connector.start();
1993                enableHttpListenerMonitoring(virtualServer,
1994                        connector.getPort(),connector.getName());
1995            }
1996        }
1997        
1998        String JavaDoc defaultWebModule = virtualServer.getDefaultWebModuleID();
1999        String JavaDoc configWebModule = vsBean.getDefaultWebModule();
2000        if ( configWebModule == null ){
2001            configWebModule = "";
2002        }
2003        
2004        if ( defaultWebModule == null
2005                || !defaultWebModule.equals(configWebModule)) {
2006            // If the defaultWebModule is null, this is a newly
2007
// created virtual-server which isn't having
2008
// any default web module set.
2009
if ( defaultWebModule != null){
2010            unloadWebModule("","", virtualServer.getID(),null);
2011            }
2012            virtualServer.setBean(vsBean);
2013            if (configWebModule != "" ) {
2014                loadDefaultWebModule(virtualServer, serverBean);
2015            } else {
2016                WebModuleConfig wmc =
2017                        virtualServer.createSystemDefaultWebModuleIfNecessary();
2018                
2019                // Create only if required.
2020
if ( wmc != null)
2021                    loadStandaloneWebModule(virtualServer,wmc);
2022            }
2023        }
2024    }
2025    
2026    
2027    /**
2028     * Update virtual-server properties.
2029     */

2030    public void updateHostProperties(
2031                    com.sun.enterprise.config.serverbeans.VirtualServer vsBean,
2032                    String JavaDoc name,
2033                    String JavaDoc value,
2034                    HttpService httpService){
2035                        
2036        Engine[] engines = _embedded.getEngines();
2037        VirtualServer vs = (VirtualServer)engines[0].findChild(vsBean.getId());
2038        
2039        if ("docroot".equals(name)) {
2040            boolean isValid = validateDocroot(value,
2041                                              vsBean.getId(),
2042                                              vsBean.getDefaultWebModule());
2043            if ( isValid ) {
2044                vs.setAppBase(value);
2045            }
2046        } else if ("setCacheControl".equals(name)){
2047            configureCacheControl(value, vs);
2048        } else if ("accesslog".equals(name)){
2049            setAccessLog(vs, vsBean.getId(), vsBean, httpService);
2050        } else if ("allowRemoteHost".equals(name)
2051                || "denyRemoteHost".equals(name)) {
2052            configureRemoteHostFilterValve(vs, vsBean,
2053                                           httpService.getHttpProtocol());
2054        } else if ("allowRemoteAddress".equals(name)
2055                || "denyRemoteAddress".equals(name)) {
2056            configureRemoteAddressFilterValve(vs, vsBean);
2057        }
2058    }
2059    
2060    
2061    /**
2062     * Update an http-listener property
2063     * @param httpListener the configuration bean.
2064     * @param propName the property name
2065     * @param propValue the property value
2066     */

2067    public void updateConnectorProperty(HttpListener httpListener,
2068                                        String JavaDoc propName,
2069                                        String JavaDoc propValue)
2070        throws LifecycleException{
2071       
2072        PECoyoteConnector connector = connectorMap.get(httpListener.getId());
2073        
2074        configureHttpListenerProperty(propName,propValue,connector);
2075    }
2076    
2077    
2078    
2079    /**
2080     * Update an http-listener
2081     * @param httpService the configuration bean.
2082     */

2083    public void updateConnector(HttpListener httpListener,
2084                                HttpService httpService) throws LifecycleException{
2085       
2086        PECoyoteConnector connector = connectorMap.get(httpListener.getId());
2087        
2088        if ( connector == null ){
2089            throw new LifecycleException("Invalid http-listener:"
2090                                                        + httpListener.getId());
2091        }
2092 
2093        int previousPort = connector.getPort();
2094        _embedded.removeConnector(connector);
2095        connectorMap.remove(httpListener.getId());
2096        
2097        connector = createConnector(httpListener, httpService);
2098        
2099        String JavaDoc virtualServerName = httpListener.getDefaultVirtualServer();
2100        VirtualServer virtualServer = (VirtualServer)
2101                     _embedded.getEngines()[0].findChild(virtualServerName);
2102        
2103        int[] ports = virtualServer.getPorts();
2104        for (int i=0; i < ports.length; i++){
2105            if (ports[i] == previousPort){
2106                ports[i] = connector.getPort();
2107            }
2108        }
2109        
2110        virtualServer.setPorts(ports);
2111        connector.start();
2112    }
2113    
2114    
2115    /**
2116     * Stop and delete the selected http-listener.
2117     * @param httpService the configuration bean.
2118     */

2119    public void deleteConnector(HttpService httpService)
2120                                                    throws LifecycleException{
2121        HttpListener[] httpListeners = httpService.getHttpListener();
2122        HttpListener httpListener;
2123        Connector[] connectors = (Connector[])_embedded.findConnectors().clone();
2124                   
2125        for (int i=0; i < connectors.length; i++){
2126            for (int j = 0; j < httpListeners.length; j++) {
2127                httpListener = (HttpListener)httpListeners[j];
2128                if ( ((PECoyoteConnector)connectors[i]).getPort()
2129                                  == Integer.parseInt(httpListener.getPort())){
2130                    connectors[i] = null;
2131                    break;
2132                }
2133            }
2134        }
2135        
2136        for (int i=0; i < connectors.length; i++){
2137            if ( connectors[i] != null ){
2138                _embedded.removeConnector((PECoyoteConnector)connectors[i]);
2139            }
2140        }
2141    }
2142    
2143   
2144    /*
2145     * Configures the given HTTP connector with the given http-protocol
2146     * config.
2147     *
2148     * @param connector HTTP connector to configure
2149     * @param httpProtocol http-protocol config to use
2150     */

2151    private void configureHttpProtocol(PECoyoteConnector connector,
2152                                       HttpProtocol httpProtocol) {
2153    
2154        if (httpProtocol == null) {
2155            return;
2156        }
2157
2158        connector.setEnableLookups(httpProtocol.isDnsLookupEnabled());
2159        connector.setForcedResponseType(httpProtocol.getForcedResponseType());
2160        connector.setDefaultResponseType(httpProtocol.getDefaultResponseType());
2161    }
2162    
2163    
2164    /**
2165     * Configure the Grizzly FileCache mechanism
2166     */

2167    private void configureFileCache(PECoyoteConnector connector,
2168                                    HttpFileCache httpFileCache){
2169        if ( httpFileCache == null ) return;
2170        
2171        connector.setFileCacheEnabled(httpFileCache.isGloballyEnabled());
2172        connector.setLargeFileCacheEnabled(
2173              Boolean.parseBoolean(httpFileCache.getFileCachingEnabled()));
2174        connector.setSecondsMaxAge(
2175                Integer.parseInt(httpFileCache.getMaxAgeInSeconds()));
2176        connector.setMaxCacheEntries(
2177                Integer.parseInt(httpFileCache.getMaxFilesCount()));
2178        connector.setMinEntrySize(
2179            Integer.parseInt(httpFileCache.getSmallFileSizeLimitInBytes()));
2180        connector.setMaxEntrySize(
2181            Integer.parseInt(httpFileCache.getMediumFileSizeLimitInBytes()));
2182        connector.setMaxLargeCacheSize(
2183            Integer.parseInt(httpFileCache.getMediumFileSpaceInBytes()));
2184        connector.setMaxSmallCacheSize(
2185            Integer.parseInt(httpFileCache.getSmallFileSpaceInBytes()));
2186    }
2187    
2188    
2189    /**
2190     * Configures all HTTP connector with the given request-processing
2191     * config.
2192     *
2193     * @param httpService http-service config to use
2194     */

2195    protected void configureRequestProcessing(HttpService httpService){
2196
2197        RequestProcessing rp = httpService.getRequestProcessing();
2198        Connector[] connectors = (Connector[])_embedded.findConnectors();
2199                    
2200        for (int i=0; i < connectors.length; i++){
2201            configureRequestProcessing(rp,(PECoyoteConnector)connectors[i]);
2202        }
2203    }
2204    
2205    
2206    /**
2207     * Configures an HTTP connector with the given request-processing
2208     * config.
2209     *
2210     * @param RequestProcessing http-service config to use
2211     * @param connector the connector used.
2212     */

2213    protected void configureRequestProcessing(RequestProcessing rp,
2214                                              PECoyoteConnector connector){
2215        if (rp == null) return;
2216
2217        try{
2218            connector.setMaxProcessors(
2219                    Integer.parseInt(rp.getThreadCount()));
2220            connector.setMinProcessors(
2221                    Integer.parseInt(rp.getInitialThreadCount()));
2222            connector.setProcessorWorkerThreadsTimeout(
2223                    Integer.parseInt(rp.getRequestTimeoutInSeconds()));
2224            connector.setProcessorWorkerThreadsIncrement(
2225                    Integer.parseInt(rp.getThreadIncrement()));
2226            connector.setMaxHttpHeaderSize(
2227                   Integer.parseInt(rp.getHeaderBufferLengthInBytes()));
2228        } catch (NumberFormatException JavaDoc ex){
2229            _logger.log(Level.WARNING, " Invalid request-processing attribute",
2230                    ex);
2231        }
2232    }
2233
2234
2235    /*
2236     * Loads and instantiates the ProxyHandler implementation
2237     * class with the specified name, and sets the instantiated
2238     * ProxyHandler on the given connector.
2239     *
2240     * @param connector The HTTP connector to configure
2241     * @param className The ProxyHandler implementation class name
2242     */

2243    private void setProxyHandler(PECoyoteConnector connector,
2244                                 String JavaDoc className) {
2245
2246        Object JavaDoc handler = null;
2247        try {
2248            Class JavaDoc handlerClass = Class.forName(className);
2249            handler = handlerClass.newInstance();
2250        } catch (Exception JavaDoc e) {
2251            String JavaDoc msg = _rb.getString(
2252                "pewebcontainer.proxyHandlerClassLoadError");
2253            msg = MessageFormat.format(msg, new Object JavaDoc[] { className });
2254            _logger.log(Level.SEVERE, msg, e);
2255        }
2256        if (handler != null) {
2257            if (!(handler instanceof ProxyHandler)) {
2258                _logger.log(
2259                    Level.SEVERE,
2260                    "pewebcontainer.proxyHandlerClassInvalid",
2261                    className);
2262            } else {
2263                connector.setProxyHandler((ProxyHandler) handler);
2264            }
2265        }
2266    }
2267}
2268
2269
Popular Tags