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.util;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import org.eclipse.jetty.util.log.Log;
27  import org.eclipse.jetty.util.log.Logger;
28  
29  /**
30   * An ObjectFactory enhanced by {@link Decorator} instances.
31   * <p>
32   * Consistent single location for all Decorator behavior, with equal behavior in a ServletContext and also for a stand
33   * alone client.
34   * <p>
35   * Used by ServletContextHandler, WebAppContext, WebSocketServerFactory, and WebSocketClient.
36   * <p>
37   * Can be found in the ServletContext Attributes at the {@link #ATTR DecoratedObjectFactory.ATTR} key.
38   */
39  public class DecoratedObjectFactory implements Iterable<Decorator>
40  {
41      private static final Logger LOG = Log.getLogger(DecoratedObjectFactory.class);
42  
43      /**
44       * ServletContext attribute for the active DecoratedObjectFactory
45       */
46      public static final String ATTR = DecoratedObjectFactory.class.getName();
47  
48      private List<Decorator> decorators = new ArrayList<>();
49  
50      public void addDecorator(Decorator decorator)
51      {
52          LOG.debug("Adding Decorator: {}", decorator);
53          this.decorators.add(decorator);
54      }
55  
56      public void clear()
57      {
58          this.decorators.clear();
59      }
60  
61      public <T> T createInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException
62      {
63          if (LOG.isDebugEnabled())
64          {
65              LOG.debug("Creating Instance: " + clazz);
66          }
67          T o = clazz.newInstance();
68          return decorate(o);
69      }
70  
71      public <T> T decorate(T obj)
72      {
73          T f = obj;
74          // Decorate is always backwards
75          for (int i = decorators.size() - 1; i >= 0; i--)
76          {
77              f = decorators.get(i).decorate(f);
78          }
79          return f;
80      }
81  
82      public void destroy(Object obj)
83      {
84          for (Decorator decorator : this.decorators)
85          {
86              decorator.destroy(obj);
87          }
88      }
89  
90      public List<Decorator> getDecorators()
91      {
92          return Collections.unmodifiableList(decorators);
93      }
94  
95      @Override
96      public Iterator<Decorator> iterator()
97      {
98          return this.decorators.iterator();
99      }
100 
101     public void setDecorators(List<? extends Decorator> decorators)
102     {
103         this.decorators.clear();
104         if (decorators != null)
105         {
106             this.decorators.addAll(decorators);
107         }
108     }
109     
110     @Override
111     public String toString()
112     {
113         StringBuilder str = new StringBuilder();
114         str.append(this.getClass().getName()).append("[decorators=");
115         str.append(Integer.toString(decorators.size()));
116         str.append("]");
117         return str.toString();
118     }
119 }