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.http.HttpStatus;
30  import org.eclipse.jetty.server.Handler;
31  import org.eclipse.jetty.server.HandlerContainer;
32  import org.eclipse.jetty.server.Request;
33  import org.eclipse.jetty.server.Server;
34  import org.eclipse.jetty.util.annotation.ManagedAttribute;
35  import org.eclipse.jetty.util.annotation.ManagedObject;
36  import org.eclipse.jetty.util.component.LifeCycle;
37  
38  /* ------------------------------------------------------------ */
39  /** A <code>HandlerWrapper</code> acts as a {@link Handler} but delegates the {@link Handler#handle handle} method and
40   * {@link LifeCycle life cycle} events to a delegate. This is primarily used to implement the <i>Decorator</i> pattern.
41   *
42   */
43  @ManagedObject("Handler wrapping another Handler")
44  public class HandlerWrapper extends AbstractHandlerContainer
45  {
46      protected Handler _handler;
47  
48      /* ------------------------------------------------------------ */
49      /**
50       *
51       */
52      public HandlerWrapper()
53      {
54      }
55  
56      /* ------------------------------------------------------------ */
57      /**
58       * @return Returns the handlers.
59       */
60      @ManagedAttribute(value="Wrapped Handler", readonly=true)
61      public Handler getHandler()
62      {
63          return _handler;
64      }
65  
66      /* ------------------------------------------------------------ */
67      /**
68       * @return Returns the handlers.
69       */
70      @Override
71      public Handler[] getHandlers()
72      {
73          if (_handler==null)
74              return new Handler[0];
75          return new Handler[] {_handler};
76      }
77  
78      /* ------------------------------------------------------------ */
79      /**
80       * @param handler Set the {@link Handler} which should be wrapped.
81       */
82      public void setHandler(Handler handler)
83      {
84          if (isStarted())
85              throw new IllegalStateException(STARTED);
86  
87          // check for loops
88          if (handler==this || (handler instanceof HandlerContainer &&
89              Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
90              throw new IllegalStateException("setHandler loop");
91          
92          if (handler!=null)
93              handler.setServer(getServer());
94          
95          Handler old=_handler;
96          _handler=handler;
97          updateBean(old,_handler,true);
98      }
99  
100     /* ------------------------------------------------------------ */
101     /** 
102      * Replace the current handler with another HandlerWrapper
103      * linked to the current handler.  
104      * <p>
105      * This is equivalent to:
106      * <pre>
107      *   wrapper.setHandler(getHandler());
108      *   setHandler(wrapper);
109      * </pre>
110      * @param wrapper the wrapper to insert
111      */
112     public void insertHandler(HandlerWrapper wrapper)
113     {
114         if (wrapper==null)
115             throw new IllegalArgumentException();
116         
117         HandlerWrapper tail = wrapper;
118         while(tail.getHandler() instanceof HandlerWrapper)
119             tail=(HandlerWrapper)tail.getHandler();
120         if (tail.getHandler()!=null)
121             throw new IllegalArgumentException("bad tail of inserted wrapper chain");
122         
123         Handler next=getHandler();
124         setHandler(wrapper);
125         tail.setHandler(next);
126     }
127 
128     /* ------------------------------------------------------------ */
129     @Override
130     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
131     {
132         Handler handler=_handler;
133         if (handler!=null)
134             handler.handle(target,baseRequest, request, response);
135     }
136 
137     /* ------------------------------------------------------------ */
138     @Override
139     protected void expandChildren(List<Handler> list, Class<?> byClass)
140     {
141         expandHandler(_handler,list,byClass);
142     }
143 
144     /* ------------------------------------------------------------ */
145     @Override
146     public void destroy()
147     {
148         if (!isStopped())
149             throw new IllegalStateException("!STOPPED");
150         Handler child=getHandler();
151         if (child!=null)
152         {
153             setHandler(null);
154             child.destroy();
155         }
156         super.destroy();
157     }
158 
159 }