View Javadoc

1   //========================================================================
2   //$Id: HandlerCollection.java,v 1.5 2005/11/11 22:55:39 gregwilkins Exp $
3   //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
4   //------------------------------------------------------------------------
5   //Licensed under the Apache License, Version 2.0 (the "License");
6   //you may not use this file except in compliance with the License.
7   //You may obtain a copy of the License at 
8   //http://www.apache.org/licenses/LICENSE-2.0
9   //Unless required by applicable law or agreed to in writing, software
10  //distributed under the License is distributed on an "AS IS" BASIS,
11  //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  //See the License for the specific language governing permissions and
13  //limitations under the License.
14  //========================================================================
15  
16  package org.mortbay.jetty.handler;
17  
18  import java.io.IOException;
19  
20  import javax.servlet.ServletException;
21  import javax.servlet.http.HttpServletRequest;
22  import javax.servlet.http.HttpServletResponse;
23  
24  import org.mortbay.jetty.EofException;
25  import org.mortbay.jetty.Handler;
26  import org.mortbay.jetty.Server;
27  import org.mortbay.util.LazyList;
28  import org.mortbay.util.MultiException;
29  
30  /* ------------------------------------------------------------ */
31  /** A collection of handlers.  
32   * For each request, all handler are called, regardless of 
33   * the response status or exceptions.
34   *  
35   * @author gregw
36   * @org.apache.xbean.XBean
37   */
38  public class HandlerCollection extends AbstractHandlerContainer
39  {
40      private Handler[] _handlers;
41  
42      /* ------------------------------------------------------------ */
43      public HandlerCollection()
44      {
45          super();
46      }
47  
48      /* ------------------------------------------------------------ */
49      /**
50       * @return Returns the handlers.
51       */
52      public Handler[] getHandlers()
53      {
54          return _handlers;
55      }
56      
57      /* ------------------------------------------------------------ */
58      /**
59       * 
60       * @param handlers The handlers to set.
61       */
62      public void setHandlers(Handler[] handlers)
63      {
64          Handler [] old_handlers = _handlers==null?null:(Handler[])_handlers.clone();
65          
66          if (getServer()!=null)
67              getServer().getContainer().update(this, old_handlers, handlers, "handler");
68          
69          Server server = getServer();
70          MultiException mex = new MultiException();
71          for (int i=0;handlers!=null && i<handlers.length;i++)
72          {
73              if (handlers[i].getServer()!=server)
74                  handlers[i].setServer(server);
75          }
76  
77          // quasi atomic.... so don't go doing this under load on a SMP system.
78          _handlers = handlers;
79  
80          for (int i=0;old_handlers!=null && i<old_handlers.length;i++)
81          {
82              if (old_handlers[i]!=null)
83              {
84                  try
85                  {
86                      if (old_handlers[i].isStarted())
87                          old_handlers[i].stop();
88                  }
89                  catch (Throwable e)
90                  {
91                      mex.add(e);
92                  }
93              }
94          }
95                  
96          mex.ifExceptionThrowRuntime();
97      }
98  
99      /* ------------------------------------------------------------ */
100     /* 
101      * @see org.mortbay.jetty.EventHandler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
102      */
103     public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) 
104         throws IOException, ServletException
105     {
106         if (_handlers!=null && isStarted())
107         {
108             MultiException mex=null;
109             
110             for (int i=0;i<_handlers.length;i++)
111             {
112                 try
113                 {
114                     _handlers[i].handle(target,request, response, dispatch);
115                 }
116                 catch(IOException e)
117                 {
118                     throw e;
119                 }
120                 catch(RuntimeException e)
121                 {
122                     throw e;
123                 }
124                 catch(Exception e)
125                 {
126                     if (mex==null)
127                         mex=new MultiException();
128                     mex.add(e);
129                 }
130             }
131             if (mex!=null)
132             {
133                 if (mex.size()==1)
134                     throw new ServletException(mex.getThrowable(0));
135                 else
136                     throw new ServletException(mex);
137             }
138             
139         }    
140     }
141 
142     /* ------------------------------------------------------------ */
143     /* 
144      * @see org.mortbay.jetty.handler.AbstractHandler#doStart()
145      */
146     protected void doStart() throws Exception
147     {
148         MultiException mex=new MultiException();
149         if (_handlers!=null)
150         {
151             for (int i=0;i<_handlers.length;i++)
152                 try{_handlers[i].start();}catch(Throwable e){mex.add(e);}
153         }
154         super.doStart();
155         mex.ifExceptionThrow();
156     }
157 
158     /* ------------------------------------------------------------ */
159     /* 
160      * @see org.mortbay.jetty.handler.AbstractHandler#doStop()
161      */
162     protected void doStop() throws Exception
163     {
164         MultiException mex=new MultiException();
165         try { super.doStop(); } catch(Throwable e){mex.add(e);}
166         if (_handlers!=null)
167         {
168             for (int i=_handlers.length;i-->0;)
169                 try{_handlers[i].stop();}catch(Throwable e){mex.add(e);}
170         }
171         mex.ifExceptionThrow();
172     }
173     
174     /* ------------------------------------------------------------ */
175     public void setServer(Server server)
176     {
177         Server old_server=getServer();
178         
179         super.setServer(server);
180 
181         Handler[] h=getHandlers();
182         for (int i=0;h!=null && i<h.length;i++)
183             h[i].setServer(server);
184         
185         if (server!=null && server!=old_server)
186             server.getContainer().update(this, null,_handlers, "handler");
187         
188     }
189 
190     /* ------------------------------------------------------------ */
191     /* Add a handler.
192      * This implementation adds the passed handler to the end of the existing collection of handlers. 
193      * @see org.mortbay.jetty.HandlerContainer#addHandler(org.mortbay.jetty.Handler)
194      */
195     public void addHandler(Handler handler)
196     {
197         setHandlers((Handler[])LazyList.addToArray(getHandlers(), handler, Handler.class));
198     }
199     
200     /* ------------------------------------------------------------ */
201     public void removeHandler(Handler handler)
202     {
203         Handler[] handlers = getHandlers();
204         
205         if (handlers!=null && handlers.length>0 )
206             setHandlers((Handler[])LazyList.removeFromArray(handlers, handler));
207     }
208 
209     /* ------------------------------------------------------------ */
210     protected Object expandChildren(Object list, Class byClass)
211     {
212         Handler[] handlers = getHandlers();
213         for (int i=0;handlers!=null && i<handlers.length;i++)
214             list=expandHandler(handlers[i], list, byClass);
215         return list;
216     }
217 
218 
219 }