View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.HandlerContainer;
31  import org.eclipse.jetty.server.Request;
32  import org.eclipse.jetty.server.Server;
33  import org.eclipse.jetty.util.ArrayUtil;
34  import org.eclipse.jetty.util.MultiException;
35  import org.eclipse.jetty.util.annotation.ManagedAttribute;
36  import org.eclipse.jetty.util.annotation.ManagedObject;
37  
38  /* ------------------------------------------------------------ */
39  /** 
40   * A collection of handlers.
41   * <p>
42   * The default implementations  calls all handlers in list order,
43   * regardless of the response status or exceptions. Derived implementation
44   * may alter the order or the conditions of calling the contained
45   * handlers.
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          {
87              // check for loops
88              for (Handler handler:handlers)
89                  if (handler == this || (handler instanceof HandlerContainer &&
90                      Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
91                          throw new IllegalStateException("setHandler loop");
92            
93              // Set server
94              for (Handler handler:handlers)
95                  if (handler.getServer()!=getServer())
96                      handler.setServer(getServer());
97          }
98          Handler[] old=_handlers;;
99          _handlers = handlers;
100         updateBeans(old, handlers);
101     }
102 
103     /* ------------------------------------------------------------ */
104     /**
105      * @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
106      */
107     @Override
108     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
109         throws IOException, ServletException
110     {
111         if (_handlers!=null && isStarted())
112         {
113             MultiException mex=null;
114 
115             for (int i=0;i<_handlers.length;i++)
116             {
117                 try
118                 {
119                     _handlers[i].handle(target,baseRequest, request, response);
120                 }
121                 catch(IOException e)
122                 {
123                     throw e;
124                 }
125                 catch(RuntimeException e)
126                 {
127                     throw e;
128                 }
129                 catch(Exception e)
130                 {
131                     if (mex==null)
132                         mex=new MultiException();
133                     mex.add(e);
134                 }
135             }
136             if (mex!=null)
137             {
138                 if (mex.size()==1)
139                     throw new ServletException(mex.getThrowable(0));
140                 else
141                     throw new ServletException(mex);
142             }
143 
144         }
145     }
146 
147     /* ------------------------------------------------------------ */
148     /* Add a handler.
149      * This implementation adds the passed handler to the end of the existing collection of handlers.
150      * @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
151      */
152     public void addHandler(Handler handler)
153     {
154         setHandlers(ArrayUtil.addToArray(getHandlers(), handler, Handler.class));
155     }
156 
157     /* ------------------------------------------------------------ */
158     public void removeHandler(Handler handler)
159     {
160         Handler[] handlers = getHandlers();
161 
162         if (handlers!=null && handlers.length>0 )
163             setHandlers(ArrayUtil.removeFromArray(handlers, handler));
164     }
165 
166     /* ------------------------------------------------------------ */
167     @Override
168     protected void expandChildren(List<Handler> list, Class<?> byClass)
169     {
170         if (getHandlers()!=null)
171             for (Handler h:getHandlers())
172                 expandHandler(h, list, byClass);
173     }
174 
175     /* ------------------------------------------------------------ */
176     @Override
177     public void destroy()
178     {
179         if (!isStopped())
180             throw new IllegalStateException("!STOPPED");
181         Handler[] children=getChildHandlers();
182         setHandlers(null);
183         for (Handler child: children)
184             child.destroy();
185         super.destroy();
186     }
187 
188     /* ------------------------------------------------------------ */
189     @Override
190     public String toString()
191     {
192         Handler[] handlers=getHandlers();
193         return super.toString()+(handlers==null?"[]":Arrays.asList(getHandlers()).toString());
194     }
195 }