View Javadoc

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  
19  package org.eclipse.jetty.server.handler;
20  
21  import java.io.IOException;
22  import java.util.Arrays;
23  import java.util.List;
24  
25  import javax.servlet.ServletException;
26  import javax.servlet.http.HttpServletRequest;
27  import javax.servlet.http.HttpServletResponse;
28  
29  import org.eclipse.jetty.server.Handler;
30  import org.eclipse.jetty.server.Request;
31  import org.eclipse.jetty.server.Server;
32  import org.eclipse.jetty.util.ArrayUtil;
33  import org.eclipse.jetty.util.MultiException;
34  import org.eclipse.jetty.util.annotation.ManagedAttribute;
35  import org.eclipse.jetty.util.annotation.ManagedObject;
36  
37  /* ------------------------------------------------------------ */
38  /** A collection of handlers.
39   * <p>
40   * The default implementations  calls all handlers in list order,
41   * regardless of the response status or exceptions. Derived implementation
42   * may alter the order or the conditions of calling the contained
43   * handlers.
44   * <p>
45   *
46   */
47  @ManagedObject("Handler of multiple handlers")
48  public class HandlerCollection extends AbstractHandlerContainer
49  {
50      private final boolean _mutableWhenRunning;
51      private volatile Handler[] _handlers;
52  
53      /* ------------------------------------------------------------ */
54      public HandlerCollection()
55      {
56          _mutableWhenRunning=false;
57      }
58  
59      /* ------------------------------------------------------------ */
60      public HandlerCollection(boolean mutableWhenRunning)
61      {
62          _mutableWhenRunning=mutableWhenRunning;
63      }
64  
65      /* ------------------------------------------------------------ */
66      /**
67       * @return Returns the handlers.
68       */
69      @Override
70      @ManagedAttribute(value="Wrapped handlers", readonly=true)
71      public Handler[] getHandlers()
72      {
73          return _handlers;
74      }
75  
76      /* ------------------------------------------------------------ */
77      /**
78       * @param handlers The handlers to set.
79       */
80      public void setHandlers(Handler[] handlers)
81      {
82          if (!_mutableWhenRunning && isStarted())
83              throw new IllegalStateException(STARTED);
84  
85          if (handlers!=null)
86              for (Handler handler:handlers)
87                  if (handler.getServer()!=getServer())
88                      handler.setServer(getServer());
89          Handler[] old=_handlers;;
90          _handlers = handlers;
91          updateBeans(old, handlers);
92      }
93  
94      /* ------------------------------------------------------------ */
95      /**
96       * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
97       */
98      @Override
99      public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
100         throws IOException, ServletException
101     {
102         if (_handlers!=null && isStarted())
103         {
104             MultiException mex=null;
105 
106             for (int i=0;i<_handlers.length;i++)
107             {
108                 try
109                 {
110                     _handlers[i].handle(target,baseRequest, request, response);
111                 }
112                 catch(IOException e)
113                 {
114                     throw e;
115                 }
116                 catch(RuntimeException e)
117                 {
118                     throw e;
119                 }
120                 catch(Exception e)
121                 {
122                     if (mex==null)
123                         mex=new MultiException();
124                     mex.add(e);
125                 }
126             }
127             if (mex!=null)
128             {
129                 if (mex.size()==1)
130                     throw new ServletException(mex.getThrowable(0));
131                 else
132                     throw new ServletException(mex);
133             }
134 
135         }
136     }
137 
138     /* ------------------------------------------------------------ */
139     @Override
140     public void setServer(Server server)
141     {
142         super.setServer(server);
143         Handler[] handlers=getHandlers();
144         if (handlers!=null)
145             for (Handler h : handlers)
146                 h.setServer(server);
147     }
148 
149     /* ------------------------------------------------------------ */
150     /* Add a handler.
151      * This implementation adds the passed handler to the end of the existing collection of handlers.
152      * @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
153      */
154     public void addHandler(Handler handler)
155     {
156         setHandlers(ArrayUtil.addToArray(getHandlers(), handler, Handler.class));
157     }
158 
159     /* ------------------------------------------------------------ */
160     public void removeHandler(Handler handler)
161     {
162         Handler[] handlers = getHandlers();
163 
164         if (handlers!=null && handlers.length>0 )
165             setHandlers(ArrayUtil.removeFromArray(handlers, handler));
166     }
167 
168     /* ------------------------------------------------------------ */
169     @Override
170     protected void expandChildren(List<Handler> list, Class<?> byClass)
171     {
172         if (getHandlers()!=null)
173             for (Handler h:getHandlers())
174                 expandHandler(h, list, byClass);
175     }
176 
177     /* ------------------------------------------------------------ */
178     @Override
179     public void destroy()
180     {
181         if (!isStopped())
182             throw new IllegalStateException("!STOPPED");
183         Handler[] children=getChildHandlers();
184         setHandlers(null);
185         for (Handler child: children)
186             child.destroy();
187         super.destroy();
188     }
189 
190     /* ------------------------------------------------------------ */
191     @Override
192     public String toString()
193     {
194         Handler[] handlers=getHandlers();
195         return super.toString()+(handlers==null?"[]":Arrays.asList(getHandlers()).toString());
196     }
197 }