1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.webapp;
20
21import java.util.HashMap;
22import java.util.Map;
23
24import org.eclipse.jetty.util.log.Log;
25import org.eclipse.jetty.util.log.Logger;
26import org.eclipse.jetty.util.resource.Resource;
27import org.eclipse.jetty.xml.XmlConfiguration;
28
29
30/**
31 *
32 * JettyWebConfiguration.
33 *
34 * Looks for Xmlconfiguration files in WEB-INF.  Searches in order for the first of jetty6-web.xml, jetty-web.xml or web-jetty.xml
35 *
36 *
37 *
38 */
39public class JettyWebXmlConfiguration extends AbstractConfiguration
40{
41    private static final Logger LOG = Log.getLogger(JettyWebXmlConfiguration.class);
42
43    /** The value of this property points to the WEB-INF directory of
44     * the web-app currently installed.
45     * it is passed as a property to the jetty-web.xml file */
46    public static final String PROPERTY_THIS_WEB_INF_URL = "this.web-inf.url";
47
48
49    public static final String XML_CONFIGURATION = "org.eclipse.jetty.webapp.JettyWebXmlConfiguration";
50    public static final String JETTY_WEB_XML = "jetty-web.xml";
51
52    /**
53     * Configure
54     * Apply web-jetty.xml configuration
55     * @see Configuration#configure(WebAppContext)
56     */
57    @Override
58    public void configure (WebAppContext context) throws Exception
59    {
60        //cannot configure if the _context is already started
61        if (context.isStarted())
62        {
63            LOG.debug("Cannot configure webapp after it is started");
64            return;
65        }
66
67        LOG.debug("Configuring web-jetty.xml");
68
69        Resource web_inf = context.getWebInf();
70        // handle any WEB-INF descriptors
71        if(web_inf!=null&&web_inf.isDirectory())
72        {
73            // do jetty.xml file
74            Resource jetty=web_inf.addPath("jetty8-web.xml");
75            if(!jetty.exists())
76                jetty=web_inf.addPath(JETTY_WEB_XML);
77            if(!jetty.exists())
78                jetty=web_inf.addPath("web-jetty.xml");
79
80            if(jetty.exists())
81            {
82                // No server classes while configuring
83                String[] old_server_classes = context.getServerClasses();
84                try
85                {
86                    context.setServerClasses(null);
87                    if(LOG.isDebugEnabled())
88                        LOG.debug("Configure: "+jetty);
89
90                    XmlConfiguration jetty_config = (XmlConfiguration)context.getAttribute(XML_CONFIGURATION);
91
92                    if (jetty_config==null)
93                    {
94                        jetty_config=new XmlConfiguration(jetty.getURL());
95                    }
96                    else
97                    {
98                        context.removeAttribute(XML_CONFIGURATION);
99                    }
100                    setupXmlConfiguration(context,jetty_config, web_inf);
101                    try
102                    {
103                        jetty_config.configure(context);
104                    }
105                    catch (ClassNotFoundException e)
106                    {
107                        LOG.warn("Unable to process jetty-web.xml", e);
108                    }
109                }
110                finally
111                {
112                    if (context.getServerClasses()==null)
113                        context.setServerClasses(old_server_classes);
114                }
115            }
116        }
117    }
118
119    /**
120     * Configures some well-known properties before the XmlConfiguration reads
121     * the configuration.
122     * @param jetty_config The configuration object.
123     */
124    private void setupXmlConfiguration(WebAppContext context, XmlConfiguration jetty_config, Resource web_inf)
125    {
126        setupXmlConfiguration(jetty_config,web_inf);
127    }
128
129    /**
130     * Configures some well-known properties before the XmlConfiguration reads
131     * the configuration.
132     * @param jetty_config The configuration object.
133     */
134    private void setupXmlConfiguration(XmlConfiguration jetty_config, Resource web_inf)
135    {
136    	Map<String,String> props = jetty_config.getProperties();
137    	if (props == null)
138    	{
139    		props = new HashMap<String, String>();
140    		jetty_config.setProperties(props);
141    	}
142
143    	// TODO - should this be an id rather than a property?
144    	props.put(PROPERTY_THIS_WEB_INF_URL, String.valueOf(web_inf.getURL()));
145    }
146}
147