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.ArrayList;
22import java.util.Collections;
23import java.util.Iterator;
24import java.util.List;
25
26import org.eclipse.jetty.util.resource.Resource;
27import org.eclipse.jetty.xml.XmlParser;
28
29
30/**
31 * Fragment
32 *
33 * A web-fragment.xml descriptor.
34 */
35public class FragmentDescriptor extends WebDescriptor
36{
37    public static final String NAMELESS = "@@-NAMELESS-@@"; //prefix for nameless Fragments
38    protected static int _counter = 0;
39
40    public enum OtherType {None, Before, After};
41    protected OtherType _otherType = OtherType.None;
42
43
44    protected List<String> _befores = new ArrayList<String>();
45    protected List<String> _afters = new ArrayList<String>();
46    protected String _name;
47
48
49    public FragmentDescriptor (Resource xml)
50        throws Exception
51    {
52        super (xml);
53    }
54
55    public String getName ()
56    {
57        return _name;
58    }
59
60    @Override
61    public void parse ()
62        throws Exception
63    {
64        super.parse();
65        processName();
66    }
67
68    public void processName ()
69    {
70        XmlParser.Node root = getRoot();
71        XmlParser.Node nameNode = root.get("name");
72        _name = NAMELESS+(_counter++);
73        if (nameNode != null)
74        {
75            String tmp = nameNode.toString(false,true);
76            if (tmp!=null && tmp.length()>0)
77                _name = tmp;
78        }
79    }
80    @Override
81    public void processOrdering ()
82    {
83        //Process a fragment jar's web-fragment.xml<ordering> elements
84        XmlParser.Node root = getRoot();
85
86        XmlParser.Node ordering = root.get("ordering");
87        if (ordering == null)
88            return; //No ordering for this fragment
89
90        _isOrdered = true;
91
92        processBefores(ordering);
93        processAfters(ordering);
94    }
95
96
97    public void processBefores (XmlParser.Node ordering)
98    {
99        //Process the <before> elements, looking for an <others/> clause and all of the <name> clauses
100        XmlParser.Node before = ordering.get("before");
101        if (before == null)
102            return;
103
104        Iterator<?> iter = before.iterator();
105        XmlParser.Node node = null;
106        while (iter.hasNext())
107        {
108            Object o = iter.next();
109            if (!(o instanceof XmlParser.Node)) continue;
110            node = (XmlParser.Node) o;
111            if (node.getTag().equalsIgnoreCase("others"))
112            {
113                if (_otherType != OtherType.None)
114                    throw new IllegalStateException("Duplicate <other> clause detected in "+_xml.getURI());
115
116                _otherType = OtherType.Before;
117            }
118            else if (node.getTag().equalsIgnoreCase("name"))
119                _befores.add(node.toString(false,true));
120        }
121    }
122
123    public void processAfters (XmlParser.Node ordering)
124    {
125        //Process the <after> elements, look for an <others/> clause and all of the <name/> clauses
126        XmlParser.Node after = ordering.get("after");
127        if (after == null)
128            return;
129
130        Iterator<?> iter = after.iterator();
131        XmlParser.Node node = null;
132        while (iter.hasNext())
133        {
134            Object o = iter.next();
135            if (!(o instanceof XmlParser.Node)) continue;
136            node = (XmlParser.Node) o;
137            if (node.getTag().equalsIgnoreCase("others"))
138            {
139                if (_otherType != OtherType.None)
140                    throw new IllegalStateException("Duplicate <other> clause detected in "+_xml.getURI());
141
142                _otherType = OtherType.After;
143
144            }
145            else if (node.getTag().equalsIgnoreCase("name"))
146                _afters.add(node.toString(false,true));
147        }
148    }
149
150    public List<String> getBefores()
151    {
152        return Collections.unmodifiableList(_befores);
153    }
154
155    public List<String> getAfters()
156    {
157        return Collections.unmodifiableList(_afters);
158    }
159
160    public OtherType getOtherType ()
161    {
162        return _otherType;
163    }
164
165    public List<String> getOrdering()
166    {
167        return null; //only used for absolute-ordering in Descriptor
168    }
169}
170