1   //========================================================================
2   //Copyright 2004-2008 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  
15  package org.mortbay.jetty.handler.rewrite;
16  
17  import java.io.IOException;
18  
19  import javax.servlet.http.HttpServletRequest;
20  import javax.servlet.http.HttpServletResponse;
21  
22  import org.mortbay.jetty.HttpConnection;
23  import org.mortbay.jetty.Request;
24  import org.mortbay.jetty.servlet.PathMap;
25  import org.mortbay.log.Log;
26  import org.mortbay.util.LazyList;
27  
28  /**
29   * Base container to group rules. Can be extended so that the contained rules
30   * will only be applied under certain conditions
31   * 
32   * @author Athena Yao
33   */
34  
35  public class RuleContainer extends Rule
36  {
37      protected Rule[] _rules;
38      protected boolean _handled;
39      
40      protected String _originalPathAttribute;
41      protected boolean _rewriteRequestURI=true;
42      protected boolean _rewritePathInfo=true;
43      
44      protected LegacyRule _legacy;
45  
46      /* ------------------------------------------------------------ */
47      private LegacyRule getLegacyRule()
48      {
49          if (_legacy==null)
50          {
51              _legacy= new LegacyRule();
52              addRule(_legacy);
53          }
54          return _legacy;
55      }
56      
57  
58      /* ------------------------------------------------------------ */
59      /**
60       * To enable configuration from jetty.xml on rewriteRequestURI, rewritePathInfo and
61       * originalPathAttribute
62       * 
63       * @param legacyRule old style rewrite rule
64       */
65      public void setLegacyRule(LegacyRule legacyRule)
66      {
67          _legacy = legacyRule;
68      }
69  
70      /* ------------------------------------------------------------ */
71      /**
72       * Returns the list of rules.
73       * @return an array of {@link Rule}.
74       */
75      public Rule[] getRules()
76      {
77          return _rules;
78      }
79  
80      /* ------------------------------------------------------------ */
81      /**
82       * Assigns the rules to process.
83       * @param rules an array of {@link Rule}. 
84       */
85      public void setRules(Rule[] rules)
86      {
87          if (_legacy==null)
88              _rules = rules;
89          else
90          {
91              _rules=null;
92              addRule(_legacy);
93              if (rules!=null)
94                  for (Rule rule:rules)
95                      addRule(rule);
96          }
97      }
98  
99      /* ------------------------------------------------------------ */
100     /**
101      * Add a Rule
102      * @param rule The rule to add to the end of the rules array
103      */
104     public void addRule(Rule rule)
105     {
106         _rules = (Rule[])LazyList.addToArray(_rules,rule,Rule.class);
107     }
108    
109 
110     /* ------------------------------------------------------------ */
111     /**
112      * @return the rewriteRequestURI If true, this handler will rewrite the value
113      * returned by {@link HttpServletRequest#getRequestURI()}.
114      */
115     public boolean isRewriteRequestURI()
116     {
117         return _rewriteRequestURI;
118     }
119 
120     /* ------------------------------------------------------------ */
121     /**
122      * @param rewriteRequestURI true if this handler will rewrite the value
123      * returned by {@link HttpServletRequest#getRequestURI()}.
124      */
125     public void setRewriteRequestURI(boolean rewriteRequestURI)
126     {
127         _rewriteRequestURI=rewriteRequestURI;
128     }
129 
130     /* ------------------------------------------------------------ */
131     /**
132      * @return true if this handler will rewrite the value
133      * returned by {@link HttpServletRequest#getPathInfo()}.
134      */
135     public boolean isRewritePathInfo()
136     {
137         return _rewritePathInfo;
138     }
139 
140     /* ------------------------------------------------------------ */
141     /**
142      * @param rewritePathInfo true if this handler will rewrite the value
143      * returned by {@link HttpServletRequest#getPathInfo()}.
144      */
145     public void setRewritePathInfo(boolean rewritePathInfo)
146     {
147         _rewritePathInfo=rewritePathInfo;
148     }
149 
150     /* ------------------------------------------------------------ */
151     /**
152      * @return the originalPathAttribte. If non null, this string will be used
153      * as the attribute name to store the original request path.
154      */
155     public String getOriginalPathAttribute()
156     {
157         return _originalPathAttribute;
158     }
159 
160     /* ------------------------------------------------------------ */
161     /**
162      * @param originalPathAttribte If non null, this string will be used
163      * as the attribute name to store the original request path.
164      */
165     public void setOriginalPathAttribute(String originalPathAttribte)
166     {
167         _originalPathAttribute=originalPathAttribte;
168     }
169 
170 
171     /* ------------------------------------------------------------ */
172     /**
173      * @deprecated 
174      */
175     public PathMap getRewrite()
176     {
177         return getLegacyRule().getRewrite();
178     }
179 
180     /* ------------------------------------------------------------ */
181     /**
182      * @deprecated
183      */
184     public void setRewrite(PathMap rewrite)
185     {
186         getLegacyRule().setRewrite(rewrite);
187     }
188 
189     /* ------------------------------------------------------------ */
190     /**
191      * @deprecated
192      */
193     public void addRewriteRule(String pattern, String prefix)
194     {
195         getLegacyRule().addRewriteRule(pattern,prefix);
196     }
197 
198     
199     /**
200      * @return handled true if one of the rules within the rule container is handling the request 
201      */
202     public boolean isHandled()
203     {
204         return _handled;
205     }
206     
207     /*------------------------------------------------------------ */
208     /**
209      * @param handled true if one of the rules within the rule container is handling the request
210      */
211     public void setHandled(boolean handled)
212     {
213         _handled=handled;
214     }
215     
216 
217     /**
218      * Process the contained rules
219      * @param target target field to pass on to the contained rules
220      * @param request request object to pass on to the contained rules
221      * @param response response object to pass on to the contained rules
222      */
223     @Override
224     public String matchAndApply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
225     {
226         return apply(target, request, response);
227     }
228 
229     /**
230      * Process the contained rules (called by matchAndApply) 
231      * @param target target field to pass on to the contained rules
232      * @param request request object to pass on to the contained rules
233      * @param response response object to pass on to the contained rules
234      */
235     protected String apply(String target, HttpServletRequest request, HttpServletResponse response) throws IOException
236     {
237         _handled=false;
238         
239         boolean original_set=_originalPathAttribute==null;
240                 
241         for (Rule rule : _rules)
242         {
243             String applied=rule.matchAndApply(target,request, response);
244             if (applied!=null)
245             {       
246                 Log.debug("applied {}",rule);
247                 if (!target.equals(applied))
248                 { 
249                     Log.debug("rewrote {} to {}",target,applied);
250                     if (!original_set)
251                     {
252                         original_set=true;
253                         request.setAttribute(_originalPathAttribute, target);
254                     }     
255                     
256                     if (_rewriteRequestURI)
257                         ((Request)request).setRequestURI(applied);
258 
259                     if (_rewritePathInfo)
260                         ((Request)request).setPathInfo(applied);
261 
262                     target=applied;
263                 }
264                 
265                 if (rule.isHandling())
266                 {
267                     Log.debug("handling {}",rule);
268                     _handled=true;
269                     (request instanceof Request?(Request)request:HttpConnection.getCurrentConnection().getRequest()).setHandled(true);
270                 }
271 
272                 if (rule.isTerminating())
273                 {
274                     Log.debug("terminating {}",rule);
275                     break;
276                 }
277             }
278         }
279 
280         return target;
281     }
282 }