View Javadoc

    1   // ========================================================================
    2   // Copyright 2003-2005 Mort Bay Consulting Pty. Ltd.
    3   // ------------------------------------------------------------------------
    4   // Licensed under the Apache License, Version 2.0 (the "License");
    5   // you may not use this file except in compliance with the License.
    6   // You may obtain a copy of the License at
    7   // http://www.apache.org/licenses/LICENSE-2.0
    8   // Unless required by applicable law or agreed to in writing, software
    9   // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  // ========================================================================
    14  package org.mortbay.jetty.webapp;
    15
    16  import java.io.File;
    17  import java.io.IOException;
    18  import java.net.MalformedURLException;
    19  import java.net.URL;
    20  import java.util.ArrayList;
    21  import java.util.EventListener;
    22  import java.util.HashMap;
    23  import java.util.Iterator;
    24  import java.util.Map;
    25
    26  import javax.servlet.UnavailableException;
    27
    28  import org.mortbay.jetty.Handler;
    29  import org.mortbay.jetty.handler.ContextHandler;
    30  import org.mortbay.jetty.security.Authenticator;
    31  import org.mortbay.jetty.security.BasicAuthenticator;
    32  import org.mortbay.jetty.security.ClientCertAuthenticator;
    33  import org.mortbay.jetty.security.Constraint;
    34  import org.mortbay.jetty.security.ConstraintMapping;
    35  import org.mortbay.jetty.security.DigestAuthenticator;
    36  import org.mortbay.jetty.security.FormAuthenticator;
    37  import org.mortbay.jetty.security.UserRealm;
    38  import org.mortbay.jetty.servlet.Dispatcher;
    39  import org.mortbay.jetty.servlet.ErrorPageErrorHandler;
    40  import org.mortbay.jetty.servlet.FilterHolder;
    41  import org.mortbay.jetty.servlet.FilterMapping;
    42  import org.mortbay.jetty.servlet.ServletHandler;
    43  import org.mortbay.jetty.servlet.ServletHolder;
    44  import org.mortbay.jetty.servlet.ServletMapping;
    45  import org.mortbay.log.Log;
    46  import org.mortbay.resource.Resource;
    47  import org.mortbay.util.LazyList;
    48  import org.mortbay.util.Loader;
    49  import org.mortbay.xml.XmlParser;
    50  /* ------------------------------------------------------------------------------- */
    51  /**
    52   * Configure by parsing default web.xml and web.xml
    53   *
    54   * @author gregw
    55   */
    56  public class WebXmlConfiguration implements Configuration
    57  {
    58      protected WebAppContext _context;
    59      protected XmlParser _xmlParser;
    60      protected Object _filters;
    61      protected Object _filterMappings;
    62      protected Object _servlets;
    63      protected Object _servletMappings;
    64      protected Object _welcomeFiles;
    65      protected Object _constraintMappings;
    66      protected Object _listeners;
    67      protected Map _errorPages;
    68      protected boolean _hasJSP;
    69      protected String _jspServletName;
    70      protected String _jspServletClass;
    71      protected boolean _defaultWelcomeFileList;
    72      protected ServletHandler _servletHandler;
    73      protected int _version;
    74
    75      public WebXmlConfiguration()
    76      {
    77          // Get parser
    78          _xmlParser=webXmlParser();
    79      }
    80
    81      public static XmlParser webXmlParser()
    82      {
    83          XmlParser xmlParser=new XmlParser();
    84          //set up cache of DTDs and schemas locally
    85          URL dtd22=WebAppContext.class.getResource("/javax/servlet/resources/web-app_2_2.dtd");
    86          URL dtd23=WebAppContext.class.getResource("/javax/servlet/resources/web-app_2_3.dtd");
    87          URL jsp20xsd=WebAppContext.class.getResource("/javax/servlet/resources/jsp_2_0.xsd");
    88          URL jsp21xsd=WebAppContext.class.getResource("/javax/servlet/resources/jsp_2_1.xsd");
    89          URL j2ee14xsd=WebAppContext.class.getResource("/javax/servlet/resources/j2ee_1_4.xsd");
    90          URL webapp24xsd=WebAppContext.class.getResource("/javax/servlet/resources/web-app_2_4.xsd");
    91          URL webapp25xsd=WebAppContext.class.getResource("/javax/servlet/resources/web-app_2_5.xsd");
    92          URL schemadtd=WebAppContext.class.getResource("/javax/servlet/resources/XMLSchema.dtd");
    93          URL xmlxsd=WebAppContext.class.getResource("/javax/servlet/resources/xml.xsd");
    94          URL webservice11xsd=WebAppContext.class.getResource("/javax/servlet/resources/j2ee_web_services_client_1_1.xsd");
    95          URL webservice12xsd=WebAppContext.class.getResource("/javax/servlet/resources/javaee_web_services_client_1_2.xsd");
    96          URL datatypesdtd=WebAppContext.class.getResource("/javax/servlet/resources/datatypes.dtd");
    97          xmlParser.redirectEntity("web-app_2_2.dtd",dtd22);
    98          xmlParser.redirectEntity("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
    99          xmlParser.redirectEntity("web.dtd",dtd23);
    100         xmlParser.redirectEntity("web-app_2_3.dtd",dtd23);
    101         xmlParser.redirectEntity("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
    102         xmlParser.redirectEntity("XMLSchema.dtd",schemadtd);
    103         xmlParser.redirectEntity("http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
    104         xmlParser.redirectEntity("-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
    105         xmlParser.redirectEntity("jsp_2_0.xsd",jsp20xsd);
    106         xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
    107         xmlParser.redirectEntity("jsp_2_1.xsd",jsp21xsd);
    108         xmlParser.redirectEntity("http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
    109         xmlParser.redirectEntity("j2ee_1_4.xsd",j2ee14xsd);
    110         xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
    111         xmlParser.redirectEntity("web-app_2_4.xsd",webapp24xsd);
    112         xmlParser.redirectEntity("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
    113         xmlParser.redirectEntity("web-app_2_5.xsd",webapp25xsd);
    114         xmlParser.redirectEntity("http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
    115         xmlParser.redirectEntity("xml.xsd",xmlxsd);
    116         xmlParser.redirectEntity("http://www.w3.org/2001/xml.xsd",xmlxsd);
    117         xmlParser.redirectEntity("datatypes.dtd",datatypesdtd);
    118         xmlParser.redirectEntity("http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
    119         xmlParser.redirectEntity("j2ee_web_services_client_1_1.xsd",webservice11xsd);
    120         xmlParser.redirectEntity("http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
    121         xmlParser.redirectEntity("javaee_web_services_client_1_2.xsd",webservice12xsd);
    122         xmlParser.redirectEntity("http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
    123
    124         return xmlParser;
    125     }
    126
    127     /* ------------------------------------------------------------------------------- */
    128     public void setWebAppContext (WebAppContext context)
    129     {
    130         _context = context;
    131     }
    132
    133     /* ------------------------------------------------------------------------------- */
    134     public WebAppContext getWebAppContext()
    135     {
    136         return _context;
    137     }
    138
    139     /* ------------------------------------------------------------------------------- */
    140     /** Configure ClassPath.
    141      */
    142     public  void configureClassLoader()
    143     throws Exception
    144     {
    145     }
    146
    147     /* ------------------------------------------------------------------------------- */
    148     public void configureDefaults() throws Exception
    149     {
    150         //cannot configure if the context is already started
    151         if (_context.isStarted())
    152         {
    153             if (Log.isDebugEnabled()){Log.debug("Cannot configure webapp after it is started");}
    154             return;
    155         }
    156         String defaultsDescriptor=getWebAppContext().getDefaultsDescriptor();
    157         if(defaultsDescriptor!=null&&defaultsDescriptor.length()>0)
    158         {
    159             Resource dftResource=Resource.newSystemResource(defaultsDescriptor);
    160             if(dftResource==null)
    161                 dftResource=Resource.newResource(defaultsDescriptor);
    162             configure(dftResource.getURL().toString());
    163             _defaultWelcomeFileList=_welcomeFiles!=null;
    164         }
    165     }
    166
    167     /* ------------------------------------------------------------------------------- */
    168     public void configureWebApp() throws Exception
    169     {
    170         //cannot configure if the context is already started
    171         if (_context.isStarted())
    172         {
    173             if (Log.isDebugEnabled())
    174                 Log.debug("Cannot configure webapp after it is started");
    175             return;
    176         }
    177
    178         URL webxml=findWebXml();
    179         if (webxml!=null)
    180             configure(webxml.toString());
    181
    182         String overrideDescriptor=getWebAppContext().getOverrideDescriptor();
    183         if(overrideDescriptor!=null&&overrideDescriptor.length()>0)
    184         {
    185             Resource orideResource=Resource.newSystemResource(overrideDescriptor);
    186             if(orideResource==null)
    187                 orideResource=Resource.newResource(overrideDescriptor);
    188             _xmlParser.setValidating(false);
    189             configure(orideResource.getURL().toString());
    190         }
    191     }
    192
    193     /* ------------------------------------------------------------------------------- */
    194     protected URL findWebXml() throws IOException, MalformedURLException
    195     {
    196         String descriptor=getWebAppContext().getDescriptor();
    197         if (descriptor!=null)
    198         {
    199             Resource web= Resource.newResource(descriptor);
    200             if (web.exists()&& !web.isDirectory())
    201                 return web.getURL();
    202         }
    203
    204         Resource web_inf=getWebAppContext().getWebInf();
    205         if(web_inf!=null && web_inf.isDirectory())
    206         {
    207             // do web.xml file
    208             Resource web=web_inf.addPath("web.xml");
    209             if(web.exists())
    210                 return web.getURL();
    211             Log.debug("No WEB-INF/web.xml in "+getWebAppContext().getWar()
    212                     +". Serving files and default/dynamic servlets only");
    213         }
    214         return null;
    215     }
    216
    217     /* ------------------------------------------------------------------------------- */
    218     public void configure(String webXml) throws Exception
    219     {
    220         XmlParser.Node config=null;
    221         config=_xmlParser.parse(webXml);
    222         initialize(config);
    223     }
    224
    225     /* ------------------------------------------------------------------------------- */
    226     public void deconfigureWebApp() throws Exception
    227     {
    228         // TODO preserve any configuration that pre-existed.
    229
    230         _servletHandler = getWebAppContext().getServletHandler();
    231
    232         _servletHandler.setFilters(null);
    233         _servletHandler.setFilterMappings(null);
    234         _servletHandler.setServlets(null);
    235         _servletHandler.setServletMappings(null);
    236
    237         getWebAppContext().setEventListeners(null);
    238         getWebAppContext().setWelcomeFiles(null);
    239         if (getWebAppContext().getSecurityHandler() != null)
    240             getWebAppContext().getSecurityHandler().setConstraintMappings(null);
    241
    242         if (getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
    243             ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).setErrorPages(null);
    244
    245         // TODO remove classpaths from classloader
    246     }
    247
    248     /* ------------------------------------------------------------ */
    249     protected void initialize(XmlParser.Node config) throws ClassNotFoundException,UnavailableException
    250     {
    251         _servletHandler = getWebAppContext().getServletHandler();
    252         // Get any existing servlets and mappings.
    253         _filters=LazyList.array2List(_servletHandler.getFilters());
    254         _filterMappings=LazyList.array2List(_servletHandler.getFilterMappings());
    255         _servlets=LazyList.array2List(_servletHandler.getServlets());
    256         _servletMappings=LazyList.array2List(_servletHandler.getServletMappings());
    257
    258         _listeners = LazyList.array2List(getWebAppContext().getEventListeners());
    259         _welcomeFiles = LazyList.array2List(getWebAppContext().getWelcomeFiles());
    260         _constraintMappings = LazyList.array2List(getWebAppContext().getSecurityHandler().getConstraintMappings());
    261
    262         _errorPages = getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler ?
    263                         ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).getErrorPages():null;
    264
    265         String version=config.getAttribute("version","DTD");
    266         if ("2.5".equals(version))
    267             _version=25;
    268         else if ("2.4".equals(version))
    269             _version=24;
    270         else if ("DTD".equals(version))
    271         {
    272             _version=23;
    273             String dtd=_xmlParser.getDTD();
    274             if (dtd!=null && dtd.indexOf("web-app_2_2")>=0)
    275                 _version=22;
    276         }
    277
    278         Iterator iter=config.iterator();
    279         XmlParser.Node node=null;
    280         while(iter.hasNext())
    281         {
    282             try
    283             {
    284                 Object o=iter.next();
    285                 if(!(o instanceof XmlParser.Node))
    286                     continue;
    287                 node=(XmlParser.Node)o;
    288                 String name=node.getTag();
    289                 initWebXmlElement(name,node);
    290             }
    291             catch(ClassNotFoundException e)
    292             {
    293                 throw e;
    294             }
    295             catch(Exception e)
    296             {
    297                 Log.warn("Configuration problem at "+node+": "+e);
    298                 Log.debug(e);
    299                 throw new UnavailableException("Configuration problem");
    300             }
    301         }
    302
    303         _servletHandler.setFilters((FilterHolder[])LazyList.toArray(_filters,FilterHolder.class));
    304         _servletHandler.setFilterMappings((FilterMapping[])LazyList.toArray(_filterMappings,FilterMapping.class));
    305         _servletHandler.setServlets((ServletHolder[])LazyList.toArray(_servlets,ServletHolder.class));
    306         _servletHandler.setServletMappings((ServletMapping[])LazyList.toArray(_servletMappings,ServletMapping.class));
    307
    308         getWebAppContext().setEventListeners((EventListener[])LazyList.toArray(_listeners,EventListener.class));
    309         getWebAppContext().setWelcomeFiles((String[])LazyList.toArray(_welcomeFiles,String.class));
    310         getWebAppContext().getSecurityHandler().setConstraintMappings((ConstraintMapping[])LazyList.toArray(_constraintMappings, ConstraintMapping.class));
    311
    312         if (_errorPages!=null && getWebAppContext().getErrorHandler() instanceof ErrorPageErrorHandler)
    313             ((ErrorPageErrorHandler)getWebAppContext().getErrorHandler()).setErrorPages(_errorPages);
    314
    315     }
    316
    317     /* ------------------------------------------------------------ */
    318     /**
    319      * Handle web.xml element. This method is called for each top level element within the web.xml
    320      * file. It may be specialized by derived WebAppHandlers to provide additional
    321      * configuration and handling.
    322      *
    323      * @param element The element name
    324      * @param node The node containing the element.
    325      */
    326     protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
    327     {
    328         if("display-name".equals(element))
    329             initDisplayName(node);
    330         else if("description".equals(element))
    331         {}
    332         else if("context-param".equals(element))
    333             initContextParam(node);
    334         else if("servlet".equals(element))
    335             initServlet(node);
    336         else if("servlet-mapping".equals(element))
    337             initServletMapping(node);
    338         else if("session-config".equals(element))
    339             initSessionConfig(node);
    340         else if("mime-mapping".equals(element))
    341             initMimeConfig(node);
    342         else if("welcome-file-list".equals(element))
    343             initWelcomeFileList(node);
    344         else if("locale-encoding-mapping-list".equals(element))
    345             initLocaleEncodingList(node);
    346         else if("error-page".equals(element))
    347             initErrorPage(node);
    348         else if("taglib".equals(element))
    349             initTagLib(node);
    350         else if("jsp-config".equals(element))
    351             initJspConfig(node);
    352         else if("resource-ref".equals(element))
    353         {
    354             if(Log.isDebugEnabled())
    355                 Log.debug("No implementation: "+node);
    356         }
    357         else if("security-constraint".equals(element))
    358             initSecurityConstraint(node);
    359         else if("login-config".equals(element))
    360             initLoginConfig(node);
    361         else if("security-role".equals(element))
    362             initSecurityRole(node);
    363         else if("filter".equals(element))
    364             initFilter(node);
    365         else if("filter-mapping".equals(element))
    366             initFilterMapping(node);
    367         else if("listener".equals(element))
    368             initListener(node);
    369         else if("distributable".equals(element))
    370             initDistributable(node);
    371         else
    372         {
    373             if(Log.isDebugEnabled())
    374             {
    375                 Log.debug("Element {} not handled in {}",element,this);
    376                 Log.debug(node.toString());
    377             }
    378         }
    379     }
    380
    381     /* ------------------------------------------------------------ */
    382     protected void initDisplayName(XmlParser.Node node)
    383     {
    384         getWebAppContext().setDisplayName(node.toString(false,true));
    385     }
    386
    387     /* ------------------------------------------------------------ */
    388     protected void initContextParam(XmlParser.Node node)
    389     {
    390         String name=node.getString("param-name",false,true);
    391         String value=node.getString("param-value",false,true);
    392         if(Log.isDebugEnabled())
    393             Log.debug("ContextParam: "+name+"="+value);
    394         getWebAppContext().getInitParams().put(name, value);
    395     }
    396
    397     /* ------------------------------------------------------------ */
    398     protected void initFilter(XmlParser.Node node)
    399     {
    400         String name=node.getString("filter-name",false,true);
    401         FilterHolder holder= _servletHandler.getFilter(name);
    402         if (holder==null)
    403         {
    404             holder=_servletHandler.newFilterHolder();
    405             holder.setName(name);
    406             _filters=LazyList.add(_filters,holder);
    407         }
    408
    409         String filter_class=node.getString("filter-class",false,true);
    410         if (filter_class!=null)
    411             holder.setClassName(filter_class);
    412
    413         Iterator iter=node.iterator("init-param");
    414         while(iter.hasNext())
    415         {
    416             XmlParser.Node paramNode=(XmlParser.Node)iter.next();
    417             String pname=paramNode.getString("param-name",false,true);
    418             String pvalue=paramNode.getString("param-value",false,true);
    419             holder.setInitParameter(pname, pvalue);
    420         }
    421
    422     }
    423
    424     /* ------------------------------------------------------------ */
    425     protected void initFilterMapping(XmlParser.Node node)
    426     {
    427         String filter_name=node.getString("filter-name",false,true);
    428
    429
    430
    431         FilterMapping mapping = new FilterMapping();
    432
    433         mapping.setFilterName(filter_name);
    434
    435         ArrayList paths = new ArrayList();
    436         Iterator iter=node.iterator("url-pattern");
    437         while(iter.hasNext())
    438         {
    439             String p=((XmlParser.Node)iter.next()).toString(false,true);
    440             p=normalizePattern(p);
    441             paths.add(p);
    442         }
    443         mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
    444
    445
    446         ArrayList names = new ArrayList();
    447         iter=node.iterator("servlet-name");
    448         while(iter.hasNext())
    449         {
    450             String n=((XmlParser.Node)iter.next()).toString(false,true);
    451             names.add(n);
    452         }
    453         mapping.setServletNames((String[])names.toArray(new String[names.size()]));
    454
    455
    456         int dispatcher=Handler.DEFAULT;
    457         iter=node.iterator("dispatcher");
    458         while(iter.hasNext())
    459         {
    460             String d=((XmlParser.Node)iter.next()).toString(false,true);
    461             dispatcher|=Dispatcher.type(d);
    462         }
    463         mapping.setDispatches(dispatcher);
    464
    465         _filterMappings=LazyList.add(_filterMappings,mapping);
    466     }
    467
    468     /* ------------------------------------------------------------ */
    469     protected String normalizePattern(String p)
    470     {
    471         if (p!=null && p.length()>0 && !p.startsWith("/") && !p.startsWith("*"))
    472             return "/"+p;
    473         return p;
    474     }
    475
    476     /* ------------------------------------------------------------ */
    477     protected void initServlet(XmlParser.Node node)
    478     {
    479         String id=node.getAttribute("id");
    480
    481         // initialize holder
    482         String servlet_name=node.getString("servlet-name",false,true);
    483         ServletHolder holder = _servletHandler.getServlet(servlet_name);
    484         if (holder==null)
    485         {
    486             holder=_servletHandler.newServletHolder();
    487             holder.setName(servlet_name);
    488             _servlets=LazyList.add(_servlets,holder);
    489         }
    490
    491         // init params
    492         Iterator iParamsIter=node.iterator("init-param");
    493         while(iParamsIter.hasNext())
    494         {
    495             XmlParser.Node paramNode=(XmlParser.Node)iParamsIter.next();
    496             String pname=paramNode.getString("param-name",false,true);
    497             String pvalue=paramNode.getString("param-value",false,true);
    498             holder.setInitParameter(pname,pvalue);
    499         }
    500
    501         String servlet_class=node.getString("servlet-class",false,true);
    502
    503         // Handle JSP
    504         if (id!=null && id.equals("jsp"))
    505         {
    506             _jspServletName=servlet_name;
    507             _jspServletClass=servlet_class;
    508             try
    509             {
    510                 Loader.loadClass(this.getClass(), servlet_class);
    511                 _hasJSP=true;
    512             }
    513             catch(ClassNotFoundException e)
    514             {
    515                 Log.info("NO JSP Support for {}, did not find {}",_context.getContextPath(),servlet_class);
    516                 _hasJSP=false;
    517                 _jspServletClass=servlet_class="org.mortbay.servlet.NoJspServlet";
    518             }
    519             if (holder.getInitParameter("scratchdir")==null)
    520             {
    521                 File tmp=getWebAppContext().getTempDirectory();
    522                 File scratch=new File(tmp,"jsp");
    523                 if (!scratch.exists())
    524                     scratch.mkdir();
    525                 holder.setInitParameter("scratchdir",scratch.getAbsolutePath());
    526
    527                 if ("?".equals(holder.getInitParameter("classpath")))
    528                 {
    529                     String classpath=getWebAppContext().getClassPath();
    530                     Log.debug("classpath="+classpath);
    531                     if (classpath!=null)
    532                         holder.setInitParameter("classpath",classpath);
    533                 }
    534             }
    535         }
    536         if (servlet_class!=null)
    537             holder.setClassName(servlet_class);
    538
    539
    540         // Handler JSP file
    541         String jsp_file=node.getString("jsp-file",false,true);
    542         if (jsp_file!=null)
    543         {
    544             holder.setForcedPath(jsp_file);
    545             holder.setClassName(_jspServletClass);
    546         }
    547
    548         // handle startup
    549         XmlParser.Node startup=node.get("load-on-startup");
    550         if(startup!=null)
    551         {
    552             String s=startup.toString(false,true).toLowerCase();
    553             if(s.startsWith("t"))
    554             {
    555                 Log.warn("Deprecated boolean load-on-startup.  Please use integer");
    556                 holder.setInitOrder(1);
    557             }
    558             else
    559             {
    560                 int order=0;
    561                 try
    562                 {
    563                     if(s!=null&&s.trim().length()>0)
    564                         order=Integer.parseInt(s);
    565                 }
    566                 catch(Exception e)
    567                 {
    568                     Log.warn("Cannot parse load-on-startup "+s+". Please use integer");
    569                     Log.ignore(e);
    570                 }
    571                 holder.setInitOrder(order);
    572             }
    573         }
    574
    575         Iterator sRefsIter=node.iterator("security-role-ref");
    576         while(sRefsIter.hasNext())
    577         {
    578             XmlParser.Node securityRef=(XmlParser.Node)sRefsIter.next();
    579             String roleName=securityRef.getString("role-name",false,true);
    580             String roleLink=securityRef.getString("role-link",false,true);
    581             if(roleName!=null&&roleName.length()>0&&roleLink!=null&&roleLink.length()>0)
    582             {
    583                 if(Log.isDebugEnabled())
    584                     Log.debug("link role "+roleName+" to "+roleLink+" for "+this);
    585                 holder.setUserRoleLink(roleName,roleLink);
    586             }
    587             else
    588             {
    589                 Log.warn("Ignored invalid security-role-ref element: "+"servlet-name="+holder.getName()+", "+securityRef);
    590             }
    591         }
    592
    593         XmlParser.Node run_as=node.get("run-as");
    594         if(run_as!=null)
    595         {
    596             String roleName=run_as.getString("role-name",false,true);
    597             if(roleName!=null)
    598                 holder.setRunAs(roleName);
    599         }
    600
    601     }
    602
    603     /* ------------------------------------------------------------ */
    604     protected void initServletMapping(XmlParser.Node node)
    605     {
    606         String servlet_name = node.getString("servlet-name",false,true);
    607         ServletMapping mapping = new ServletMapping();
    608         mapping.setServletName(servlet_name);
    609
    610         ArrayList paths = new ArrayList();
    611         Iterator iter=node.iterator("url-pattern");
    612         while(iter.hasNext())
    613         {
    614             String p=((XmlParser.Node)iter.next()).toString(false,true);
    615             p=normalizePattern(p);
    616             paths.add(p);
    617         }
    618         mapping.setPathSpecs((String[])paths.toArray(new String[paths.size()]));
    619
    620         _servletMappings=LazyList.add(_servletMappings,mapping);
    621     }
    622
    623     /* ------------------------------------------------------------ */
    624     protected void initListener(XmlParser.Node node)
    625     {
    626         String className=node.getString("listener-class",false,true);
    627         Object listener=null;
    628         try
    629         {
    630             Class listenerClass=getWebAppContext().loadClass(className);
    631             listener=newListenerInstance(listenerClass);
    632             if(!(listener instanceof EventListener))
    633             {
    634                 Log.warn("Not an EventListener: "+listener);
    635                 return;
    636             }
    637             _listeners=LazyList.add(_listeners, listener);
    638         }
    639         catch(Exception e)
    640         {
    641             Log.warn("Could not instantiate listener "+className,e);
    642             return;
    643         }
    644     }
    645
    646     /* ------------------------------------------------------------ */
    647     protected Object newListenerInstance(Class clazz)
    648         throws InstantiationException, IllegalAccessException
    649     {
    650                      return clazz.newInstance();
    651     }
    652
    653     /* ------------------------------------------------------------ */
    654     protected void initDistributable(XmlParser.Node node)
    655     {
    656         // the element has no content, so its simple presence
    657         // indicates that the webapp is distributable...
    658         WebAppContext wac=getWebAppContext();
    659         if (!wac.isDistributable())
    660             wac.setDistributable(true);
    661     }
    662
    663     /* ------------------------------------------------------------ */
    664     protected void initSessionConfig(XmlParser.Node node)
    665     {
    666         XmlParser.Node tNode=node.get("session-timeout");
    667         if(tNode!=null)
    668         {
    669             int timeout=Integer.parseInt(tNode.toString(false,true));
    670             getWebAppContext().getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout*60);
    671         }
    672     }
    673
    674     /* ------------------------------------------------------------ */
    675     protected void initMimeConfig(XmlParser.Node node)
    676     {
    677         String extension=node.getString("extension",false,true);
    678         if(extension!=null&&extension.startsWith("."))
    679             extension=extension.substring(1);
    680         String mimeType=node.getString("mime-type",false,true);
    681         getWebAppContext().getMimeTypes().addMimeMapping(extension, mimeType);
    682     }
    683
    684     /* ------------------------------------------------------------ */
    685     protected void initWelcomeFileList(XmlParser.Node node)
    686     {
    687         if (_defaultWelcomeFileList)
    688             _welcomeFiles=null; // erase welcome files from default web.xml
    689
    690         _defaultWelcomeFileList=false;
    691         Iterator iter=node.iterator("welcome-file");
    692         while(iter.hasNext())
    693         {
    694             XmlParser.Node indexNode=(XmlParser.Node)iter.next();
    695             String welcome=indexNode.toString(false,true);
    696             _welcomeFiles=LazyList.add(_welcomeFiles,welcome);
    697         }
    698     }
    699
    700     /* ------------------------------------------------------------ */
    701     protected void initLocaleEncodingList(XmlParser.Node node)
    702     {
    703         Iterator iter=node.iterator("locale-encoding-mapping");
    704         while(iter.hasNext())
    705         {
    706             XmlParser.Node mapping=(XmlParser.Node)iter.next();
    707             String locale=mapping.getString("locale",false,true);
    708             String encoding=mapping.getString("encoding",false,true);
    709             getWebAppContext().addLocaleEncoding(locale,encoding);
    710         }
    711     }
    712
    713     /* ------------------------------------------------------------ */
    714     protected void initErrorPage(XmlParser.Node node)
    715     {
    716         String error=node.getString("error-code",false,true);
    717         if(error==null||error.length()==0)
    718             error=node.getString("exception-type",false,true);
    719         String location=node.getString("location",false,true);
    720
    721         if (_errorPages==null)
    722             _errorPages=new HashMap();
    723         _errorPages.put(error,location);
    724     }
    725
    726     /* ------------------------------------------------------------ */
    727     protected void initTagLib(XmlParser.Node node)
    728     {
    729         String uri=node.getString("taglib-uri",false,true);
    730         String location=node.getString("taglib-location",false,true);
    731
    732         getWebAppContext().setResourceAlias(uri,location);
    733     }
    734
    735     /* ------------------------------------------------------------ */
    736     protected void initJspConfig(XmlParser.Node node)
    737     {
    738         for (int i=0;i<node.size();i++)
    739         {
    740             Object o=node.get(i);
    741             if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node)o).getTag()))
    742                 initTagLib((XmlParser.Node)o);
    743         }
    744
    745         // Map URLs from jsp property groups to JSP servlet.
    746         // this is more JSP stupidness creaping into the servlet spec
    747         Iterator iter=node.iterator("jsp-property-group");
    748         Object paths=null;
    749         while(iter.hasNext())
    750         {
    751             XmlParser.Node group=(XmlParser.Node)iter.next();
    752             Iterator iter2 = group.iterator("url-pattern");
    753             while (iter2.hasNext())
    754             {
    755                 String url = ((XmlParser.Node) iter2.next()).toString(false, true);
    756                 url=normalizePattern(url);
    757                 paths=LazyList.add(paths,url);
    758             }
    759         }
    760
    761         if (LazyList.size(paths)>0)
    762         {
    763             String jspName=getJSPServletName();
    764             if (jspName!=null)
    765             {
    766                 ServletMapping mapping = new ServletMapping();
    767                 mapping.setServletName(jspName);
    768                 mapping.setPathSpecs(LazyList.toStringArray(paths));
    769                 _servletMappings=LazyList.add(_servletMappings,mapping);
    770             }
    771         }
    772     }
    773
    774     /* ------------------------------------------------------------ */
    775     protected void initSecurityConstraint(XmlParser.Node node)
    776     {
    777         Constraint scBase = new Constraint();
    778
    779         try
    780         {
    781             XmlParser.Node auths = node.get("auth-constraint");
    782
    783             if (auths != null)
    784             {
    785                 scBase.setAuthenticate(true);
    786                 // auth-constraint
    787                 Iterator iter = auths.iterator("role-name");
    788                 Object roles=null;
    789                 while (iter.hasNext())
    790                 {
    791                     String role = ((XmlParser.Node) iter.next()).toString(false, true);
    792                     roles=LazyList.add(roles,role);
    793                 }
    794                 scBase.setRoles(LazyList.toStringArray(roles));
    795             }
    796
    797             XmlParser.Node data = node.get("user-data-constraint");
    798             if (data != null)
    799             {
    800                 data = data.get("transport-guarantee");
    801                 String guarantee = data.toString(false, true).toUpperCase();
    802                 if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
    803                     scBase.setDataConstraint(Constraint.DC_NONE);
    804                 else if ("INTEGRAL".equals(guarantee))
    805                     scBase.setDataConstraint(Constraint.DC_INTEGRAL);
    806                 else if ("CONFIDENTIAL".equals(guarantee))
    807                     scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
    808                 else
    809                 {
    810                     Log.warn("Unknown user-data-constraint:" + guarantee);
    811                     scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
    812                 }
    813             }
    814             Iterator iter = node.iterator("web-resource-collection");
    815             while (iter.hasNext())
    816             {
    817                 XmlParser.Node collection = (XmlParser.Node) iter.next();
    818                 String name = collection.getString("web-resource-name", false, true);
    819                 Constraint sc = (Constraint) scBase.clone();
    820                 sc.setName(name);
    821
    822
    823                 Iterator iter2 = collection.iterator("url-pattern");
    824                 while (iter2.hasNext())
    825                 {
    826                     String url = ((XmlParser.Node) iter2.next()).toString(false, true);
    827                     url=normalizePattern(url);
    828
    829                     Iterator iter3 = collection.iterator("http-method");
    830                     if (iter3.hasNext())
    831                     {
    832                         while (iter3.hasNext())
    833                         {
    834                             String method=((XmlParser.Node) iter3.next()).toString(false, true);
    835                             ConstraintMapping mapping = new ConstraintMapping();
    836                             mapping.setMethod(method);
    837                             mapping.setPathSpec(url);
    838                             mapping.setConstraint(sc);
    839                             _constraintMappings=LazyList.add(_constraintMappings,mapping);
    840                         }
    841                     }
    842                     else
    843                     {
    844                         ConstraintMapping mapping = new ConstraintMapping();
    845                         mapping.setPathSpec(url);
    846                         mapping.setConstraint(sc);
    847                         _constraintMappings=LazyList.add(_constraintMappings,mapping);
    848                     }
    849                 }
    850             }
    851         }
    852         catch (CloneNotSupportedException e)
    853         {
    854             Log.warn(e);
    855         }
    856
    857     }
    858
    859     /* ------------------------------------------------------------ */
    860     protected void initLoginConfig(XmlParser.Node node)
    861     {
    862         XmlParser.Node method=node.get("auth-method");
    863         FormAuthenticator _formAuthenticator=null;
    864         if(method!=null)
    865         {
    866             Authenticator authenticator=null;
    867             String m=method.toString(false,true);
    868             if(Constraint.__FORM_AUTH.equals(m))
    869                 authenticator=_formAuthenticator=new FormAuthenticator();
    870             else if(Constraint.__BASIC_AUTH.equals(m))
    871                 authenticator=new BasicAuthenticator();
    872             else if(Constraint.__DIGEST_AUTH.equals(m))
    873                 authenticator=new DigestAuthenticator();
    874             else if(Constraint.__CERT_AUTH.equals(m))
    875                 authenticator=new ClientCertAuthenticator();
    876             else if(Constraint.__CERT_AUTH2.equals(m))
    877                 authenticator=new ClientCertAuthenticator();
    878             else
    879                 Log.warn("UNKNOWN AUTH METHOD: "+m);
    880             getWebAppContext().getSecurityHandler().setAuthenticator(authenticator);
    881         }
    882         XmlParser.Node name=node.get("realm-name");
    883
    884         UserRealm[] realms=ContextHandler.getCurrentContext().getContextHandler().getServer().getUserRealms();
    885
    886         String realm_name=name==null?"default":name.toString(false,true);
    887
    888         UserRealm realm=getWebAppContext().getSecurityHandler().getUserRealm();
    889         for (int i=0;realm==null && realms!=null && i<realms.length; i++)
    890         {
    891             if (realms[i]!=null && realm_name.equals(realms[i].getName()))
    892                 realm=realms[i];
    893         }
    894
    895         if (realm==null)
    896         {
    897             String msg = "Unknown realm: "+realm_name;
    898             Log.warn(msg);
    899         }
    900         else
    901             getWebAppContext().getSecurityHandler().setUserRealm(realm);
    902
    903
    904         XmlParser.Node formConfig=node.get("form-login-config");
    905         if(formConfig!=null)
    906         {
    907             if(_formAuthenticator==null)
    908                 Log.warn("FORM Authentication miss-configured");
    909             else
    910             {
    911                 XmlParser.Node loginPage=formConfig.get("form-login-page");
    912                 if(loginPage!=null)
    913                     _formAuthenticator.setLoginPage(loginPage.toString(false,true));
    914                 XmlParser.Node errorPage=formConfig.get("form-error-page");
    915                 if(errorPage!=null)
    916                 {
    917                     String ep=errorPage.toString(false,true);
    918                     _formAuthenticator.setErrorPage(ep);
    919                 }
    920             }
    921         }
    922     }
    923
    924     /* ------------------------------------------------------------ */
    925     protected void initSecurityRole(XmlParser.Node node)
    926     {}
    927
    928
    929
    930
    931     /* ------------------------------------------------------------ */
    932     protected String getJSPServletName()
    933     {
    934         if (_jspServletName==null)
    935         {
    936             Map.Entry entry= _context.getServletHandler().getHolderEntry("test.jsp");
    937             if (entry!=null)
    938             {
    939                 ServletHolder holder=(ServletHolder)entry.getValue();
    940                 _jspServletName=holder.getName();
    941             }
    942         }
    943         return _jspServletName;
    944     }
    945 }