1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.tomcat.util.descriptor.web;
18
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Locale;
23
24 import javax.servlet.DispatcherType;
25
26 import org.apache.tomcat.util.buf.UDecoder;
27
28 /**
29  * Representation of a filter mapping for a web application, as represented
30  * in a <code>&lt;filter-mapping&gt;</code> element in the deployment
31  * descriptor.  Each filter mapping must contain a filter name plus either
32  * a URL pattern or a servlet name.
33  *
34  * @author Craig R. McClanahan
35  */

36 public class FilterMap extends XmlEncodingBase implements Serializable {
37
38
39     // ------------------------------------------------------------- Properties
40
41
42     private static final long serialVersionUID = 1L;
43
44     /**
45      * The name of this filter to be executed when this mapping matches
46      * a particular request.
47      */

48
49     public static final int ERROR = 1;
50     public static final int FORWARD = 2;
51     public static final int INCLUDE = 4;
52     public static final int REQUEST = 8;
53     public static final int ASYNC = 16;
54
55     // represents nothing having been set. This will be seen
56     // as equal to a REQUEST
57     private static final int NOT_SET = 0;
58
59     private int dispatcherMapping = NOT_SET;
60
61     private String filterName = null;
62
63     public String getFilterName() {
64         return this.filterName;
65     }
66
67     public void setFilterName(String filterName) {
68         this.filterName = filterName;
69     }
70
71
72     /**
73      * The servlet name this mapping matches.
74      */

75     private String[] servletNames = new String[0];
76
77     public String[] getServletNames() {
78         if (matchAllServletNames) {
79             return new String[] {};
80         } else {
81             return this.servletNames;
82         }
83     }
84
85     public void addServletName(String servletName) {
86         if ("*".equals(servletName)) {
87             this.matchAllServletNames = true;
88         } else {
89             String[] results = new String[servletNames.length + 1];
90             System.arraycopy(servletNames, 0, results, 0, servletNames.length);
91             results[servletNames.length] = servletName;
92             servletNames = results;
93         }
94     }
95
96
97     /**
98      * The flag that indicates this mapping will match all url-patterns
99      */

100     private boolean matchAllUrlPatterns = false;
101
102     public boolean getMatchAllUrlPatterns() {
103         return matchAllUrlPatterns;
104     }
105
106
107     /**
108      * The flag that indicates this mapping will match all servlet-names
109      */

110     private boolean matchAllServletNames = false;
111
112     public boolean getMatchAllServletNames() {
113         return matchAllServletNames;
114     }
115
116
117     /**
118      * The URL pattern this mapping matches.
119      */

120     private String[] urlPatterns = new String[0];
121
122     public String[] getURLPatterns() {
123         if (matchAllUrlPatterns) {
124             return new String[] {};
125         } else {
126             return this.urlPatterns;
127         }
128     }
129
130     public void addURLPattern(String urlPattern) {
131         addURLPatternDecoded(UDecoder.URLDecode(urlPattern, getCharset()));
132     }
133     public void addURLPatternDecoded(String urlPattern) {
134         if ("*".equals(urlPattern)) {
135             this.matchAllUrlPatterns = true;
136         } else {
137             String[] results = new String[urlPatterns.length + 1];
138             System.arraycopy(urlPatterns, 0, results, 0, urlPatterns.length);
139             results[urlPatterns.length] = UDecoder.URLDecode(urlPattern);
140             urlPatterns = results;
141         }
142     }
143
144     /**
145      * This method will be used to set the current state of the FilterMap
146      * representing the state of when filters should be applied.
147      * @param dispatcherString the dispatcher type which should
148      *  match this filter
149      */

150     public void setDispatcher(String dispatcherString) {
151         String dispatcher = dispatcherString.toUpperCase(Locale.ENGLISH);
152
153         if (dispatcher.equals(DispatcherType.FORWARD.name())) {
154             // apply FORWARD to the global dispatcherMapping.
155             dispatcherMapping |= FORWARD;
156         } else if (dispatcher.equals(DispatcherType.INCLUDE.name())) {
157             // apply INCLUDE to the global dispatcherMapping.
158             dispatcherMapping |= INCLUDE;
159         } else if (dispatcher.equals(DispatcherType.REQUEST.name())) {
160             // apply REQUEST to the global dispatcherMapping.
161             dispatcherMapping |= REQUEST;
162         }  else if (dispatcher.equals(DispatcherType.ERROR.name())) {
163             // apply ERROR to the global dispatcherMapping.
164             dispatcherMapping |= ERROR;
165         }  else if (dispatcher.equals(DispatcherType.ASYNC.name())) {
166             // apply ERROR to the global dispatcherMapping.
167             dispatcherMapping |= ASYNC;
168         }
169     }
170
171     public int getDispatcherMapping() {
172         // per the SRV.6.2.5 absence of any dispatcher elements is
173         // equivalent to a REQUEST value
174         if (dispatcherMapping == NOT_SET) return REQUEST;
175
176         return dispatcherMapping;
177     }
178
179     public String[] getDispatcherNames() {
180         List<String> result = new ArrayList<>();
181         if ((dispatcherMapping & FORWARD) != 0) {
182             result.add(DispatcherType.FORWARD.name());
183         }
184         if ((dispatcherMapping & INCLUDE) != 0) {
185             result.add(DispatcherType.INCLUDE.name());
186         }
187         if ((dispatcherMapping & REQUEST) != 0) {
188             result.add(DispatcherType.REQUEST.name());
189         }
190         if ((dispatcherMapping & ERROR) != 0) {
191             result.add(DispatcherType.ERROR.name());
192         }
193         if ((dispatcherMapping & ASYNC) != 0) {
194             result.add(DispatcherType.ASYNC.name());
195         }
196         return result.toArray(new String[result.size()]);
197     }
198
199     // --------------------------------------------------------- Public Methods
200
201
202     /**
203      * Render a String representation of this object.
204      */

205     @Override
206     public String toString() {
207         StringBuilder sb = new StringBuilder("FilterMap[");
208         sb.append("filterName=");
209         sb.append(this.filterName);
210         for (int i = 0; i < servletNames.length; i++) {
211             sb.append(", servletName=");
212             sb.append(servletNames[i]);
213         }
214         for (int i = 0; i < urlPatterns.length; i++) {
215             sb.append(", urlPattern=");
216             sb.append(urlPatterns[i]);
217         }
218         sb.append("]");
219         return sb.toString();
220     }
221
222
223 }
224