View Javadoc

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