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.net.URL;
22import java.util.ArrayList;
23import java.util.Iterator;
24import java.util.List;
25
26import javax.servlet.Servlet;
27
28import org.eclipse.jetty.util.Loader;
29import org.eclipse.jetty.util.log.Log;
30import org.eclipse.jetty.util.log.Logger;
31import org.eclipse.jetty.util.resource.Resource;
32import org.eclipse.jetty.xml.XmlParser;
33
34
35
36/**
37 * Descriptor
38 *
39 * A web descriptor (web.xml/web-defaults.xml/web-overrides.xml).
40 */
41public class WebDescriptor extends Descriptor
42{
43    private static final Logger LOG = Log.getLogger(WebDescriptor.class);
44
45    protected static XmlParser _parserSingleton;
46    protected MetaDataComplete _metaDataComplete;
47    protected int _majorVersion = 3; //default to container version
48    protected int _minorVersion = 0;
49    protected ArrayList<String> _classNames = new ArrayList<String>();
50    protected boolean _distributable;
51
52    protected boolean _isOrdered = false;
53    protected List<String> _ordering = new ArrayList<String>();
54
55    @Override
56    public void ensureParser()
57    throws ClassNotFoundException
58    {
59        if (_parserSingleton == null)
60        {
61            _parserSingleton = newParser();
62        }
63        _parser = _parserSingleton;
64    }
65
66
67    public XmlParser newParser()
68    throws ClassNotFoundException
69    {
70        XmlParser xmlParser=new XmlParser();
71        //set up cache of DTDs and schemas locally
72        URL dtd22=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_2.dtd",true);
73        URL dtd23=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_3.dtd",true);
74        URL j2ee14xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_1_4.xsd",true);
75        URL webapp24xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_4.xsd",true);
76        URL webapp25xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_2_5.xsd",true);
77        URL webapp30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-app_3_0.xsd",true);
78        URL webcommon30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-common_3_0.xsd",true);
79        URL webfragment30xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/web-fragment_3_0.xsd",true);
80        URL schemadtd=Loader.getResource(Servlet.class,"javax/servlet/resources/XMLSchema.dtd",true);
81        URL xmlxsd=Loader.getResource(Servlet.class,"javax/servlet/resources/xml.xsd",true);
82        URL webservice11xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/j2ee_web_services_client_1_1.xsd",true);
83        URL webservice12xsd=Loader.getResource(Servlet.class,"javax/servlet/resources/javaee_web_services_client_1_2.xsd",true);
84        URL datatypesdtd=Loader.getResource(Servlet.class,"javax/servlet/resources/datatypes.dtd",true);
85
86        URL jsp20xsd = null;
87        URL jsp21xsd = null;
88
89        try
90        {
91            Class<?> jsp_page = Loader.loadClass(WebXmlConfiguration.class, "javax.servlet.jsp.JspPage");
92            jsp20xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_0.xsd");
93            jsp21xsd = jsp_page.getResource("/javax/servlet/resources/jsp_2_1.xsd");
94        }
95        catch (Exception e)
96        {
97            LOG.ignore(e);
98        }
99        finally
100        {
101            if (jsp20xsd == null) jsp20xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_0.xsd", true);
102            if (jsp21xsd == null) jsp21xsd = Loader.getResource(Servlet.class, "javax/servlet/resources/jsp_2_1.xsd", true);
103        }
104
105        redirect(xmlParser,"web-app_2_2.dtd",dtd22);
106        redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",dtd22);
107        redirect(xmlParser,"web.dtd",dtd23);
108        redirect(xmlParser,"web-app_2_3.dtd",dtd23);
109        redirect(xmlParser,"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",dtd23);
110        redirect(xmlParser,"XMLSchema.dtd",schemadtd);
111        redirect(xmlParser,"http://www.w3.org/2001/XMLSchema.dtd",schemadtd);
112        redirect(xmlParser,"-//W3C//DTD XMLSCHEMA 200102//EN",schemadtd);
113        redirect(xmlParser,"jsp_2_0.xsd",jsp20xsd);
114        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/jsp_2_0.xsd",jsp20xsd);
115        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/jsp_2_1.xsd",jsp21xsd);
116        redirect(xmlParser,"j2ee_1_4.xsd",j2ee14xsd);
117        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd",j2ee14xsd);
118        redirect(xmlParser,"web-app_2_4.xsd",webapp24xsd);
119        redirect(xmlParser,"http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd",webapp24xsd);
120        redirect(xmlParser,"web-app_2_5.xsd",webapp25xsd);
121        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd",webapp25xsd);
122        redirect(xmlParser,"web-app_3_0.xsd",webapp30xsd);
123        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd",webapp30xsd);
124        redirect(xmlParser,"web-common_3_0.xsd",webcommon30xsd);
125        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-common_3_0.xsd",webcommon30xsd);
126        redirect(xmlParser,"web-fragment_3_0.xsd",webfragment30xsd);
127        redirect(xmlParser,"http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd",webfragment30xsd);
128        redirect(xmlParser,"xml.xsd",xmlxsd);
129        redirect(xmlParser,"http://www.w3.org/2001/xml.xsd",xmlxsd);
130        redirect(xmlParser,"datatypes.dtd",datatypesdtd);
131        redirect(xmlParser,"http://www.w3.org/2001/datatypes.dtd",datatypesdtd);
132        redirect(xmlParser,"j2ee_web_services_client_1_1.xsd",webservice11xsd);
133        redirect(xmlParser,"http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd",webservice11xsd);
134        redirect(xmlParser,"javaee_web_services_client_1_2.xsd",webservice12xsd);
135        redirect(xmlParser,"http://www.ibm.com/webservices/xsd/javaee_web_services_client_1_2.xsd",webservice12xsd);
136        return xmlParser;
137    }
138
139
140    public WebDescriptor (Resource xml)
141    {
142        super(xml);
143    }
144
145    public void parse ()
146    throws Exception
147    {
148        super.parse();
149        processVersion();
150        processOrdering();
151    }
152
153    public MetaDataComplete getMetaDataComplete()
154    {
155        return _metaDataComplete;
156    }
157
158
159
160    public int getMajorVersion ()
161    {
162        return _majorVersion;
163    }
164
165    public int getMinorVersion()
166    {
167        return _minorVersion;
168    }
169
170
171    public void processVersion ()
172    {
173        String version = _root.getAttribute("version", "DTD");
174        if ("DTD".equals(version))
175        {
176            _majorVersion = 2;
177            _minorVersion = 3;
178            String dtd = _parser.getDTD();
179            if (dtd != null && dtd.indexOf("web-app_2_2") >= 0)
180            {
181                _majorVersion = 2;
182                _minorVersion = 2;
183            }
184        }
185        else
186        {
187           int dot = version.indexOf(".");
188           if (dot > 0)
189           {
190               _majorVersion = Integer.parseInt(version.substring(0,dot));
191               _minorVersion = Integer.parseInt(version.substring(dot+1));
192           }
193        }
194
195        if (_majorVersion < 2 && _minorVersion < 5)
196            _metaDataComplete = MetaDataComplete.True; // does not apply before 2.5
197        else
198        {
199            String s = (String)_root.getAttribute("metadata-complete");
200            if (s == null)
201                _metaDataComplete = MetaDataComplete.NotSet;
202            else
203                _metaDataComplete = Boolean.valueOf(s).booleanValue()?MetaDataComplete.True:MetaDataComplete.False;
204        }
205
206        if (LOG.isDebugEnabled())
207            LOG.debug(_xml.toString()+": Calculated metadatacomplete = " + _metaDataComplete + " with version=" + version);
208    }
209
210    public void processOrdering ()
211    {
212        //Process the web.xml's optional <absolute-ordering> element
213        XmlParser.Node ordering = _root.get("absolute-ordering");
214        if (ordering == null)
215           return;
216
217        _isOrdered = true;
218        //If an absolute-ordering was already set, then ignore it in favor of this new one
219       // _processor.setOrdering(new AbsoluteOrdering());
220
221        Iterator<Object> iter = ordering.iterator();
222        XmlParser.Node node = null;
223        while (iter.hasNext())
224        {
225            Object o = iter.next();
226            if (!(o instanceof XmlParser.Node)) continue;
227            node = (XmlParser.Node) o;
228
229            if (node.getTag().equalsIgnoreCase("others"))
230                //((AbsoluteOrdering)_processor.getOrdering()).addOthers();
231                _ordering.add("others");
232            else if (node.getTag().equalsIgnoreCase("name"))
233                //((AbsoluteOrdering)_processor.getOrdering()).add(node.toString(false,true));
234                _ordering.add(node.toString(false,true));
235        }
236    }
237
238    public void addClassName (String className)
239    {
240        if (!_classNames.contains(className))
241            _classNames.add(className);
242    }
243
244    public ArrayList<String> getClassNames ()
245    {
246        return _classNames;
247    }
248
249    public void setDistributable (boolean distributable)
250    {
251        _distributable = distributable;
252    }
253
254    public boolean isDistributable()
255    {
256        return _distributable;
257    }
258
259    public void setValidating (boolean validating)
260    {
261       _validating = validating;
262    }
263
264
265    public boolean isOrdered()
266    {
267        return _isOrdered;
268    }
269
270    public List<String> getOrdering()
271    {
272        return _ordering;
273    }
274
275
276}
277