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.websocket.common.events;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.eclipse.jetty.util.log.Log;
25  import org.eclipse.jetty.util.log.Logger;
26  import org.eclipse.jetty.websocket.api.InvalidWebSocketException;
27  import org.eclipse.jetty.websocket.api.WebSocketPolicy;
28  
29  /**
30   * Create EventDriver implementations.
31   */
32  public class EventDriverFactory
33  {
34      private static final Logger LOG = Log.getLogger(EventDriverFactory.class);
35      private final WebSocketPolicy policy;
36      private final List<EventDriverImpl> implementations;
37  
38      public EventDriverFactory(WebSocketPolicy policy)
39      {
40          this.policy = policy;
41          this.implementations = new ArrayList<>();
42  
43          addImplementation(new JettyListenerImpl());
44          addImplementation(new JettyAnnotatedImpl());
45      }
46  
47      public void addImplementation(EventDriverImpl impl)
48      {
49          if (implementations.contains(impl))
50          {
51              LOG.warn("Ignoring attempt to add duplicate EventDriverImpl: " + impl);
52              return;
53          }
54  
55          implementations.add(impl);
56      }
57  
58      public void clearImplementations()
59      {
60          this.implementations.clear();
61      }
62  
63      protected String getClassName(Object websocket)
64      {
65          return websocket.getClass().getName();
66      }
67  
68      public List<EventDriverImpl> getImplementations()
69      {
70          return implementations;
71      }
72  
73      public boolean removeImplementation(EventDriverImpl impl)
74      {
75          return this.implementations.remove(impl);
76      }
77  
78      @Override
79      public String toString()
80      {
81          StringBuilder msg = new StringBuilder();
82          msg.append(this.getClass().getSimpleName());
83          msg.append("[implementations=[");
84          boolean delim = false;
85          for (EventDriverImpl impl : implementations)
86          {
87              if (delim)
88              {
89                  msg.append(',');
90              }
91              msg.append(impl.toString());
92              delim = true;
93          }
94          msg.append("]");
95          return msg.toString();
96      }
97  
98      /**
99       * Wrap the given WebSocket object instance in a suitable EventDriver
100      * 
101      * @param websocket
102      *            the websocket instance to wrap. Must either implement {@link WebSocketListener} or be annotated with {@link WebSocket &#064WebSocket}
103      * @return appropriate EventDriver for this websocket instance.
104      */
105     public EventDriver wrap(Object websocket)
106     {
107         if (websocket == null)
108         {
109             throw new InvalidWebSocketException("null websocket object");
110         }
111 
112         for (EventDriverImpl impl : implementations)
113         {
114             if (impl.supports(websocket))
115             {
116                 try
117                 {
118                     return impl.create(websocket,policy.clonePolicy());
119                 }
120                 catch (Throwable e)
121                 {
122                     throw new InvalidWebSocketException("Unable to create websocket",e);
123                 }
124             }
125         }
126 
127         // Create a clear error message for the developer
128         StringBuilder err = new StringBuilder();
129         err.append(getClassName(websocket));
130         err.append(" is not a valid WebSocket object.");
131         err.append("  Object must obey one of the following rules: ");
132 
133         int len = implementations.size();
134         for (int i = 0; i < len; i++)
135         {
136             EventDriverImpl impl = implementations.get(i);
137             if (i > 0)
138             {
139                 err.append(" or ");
140             }
141             err.append("\n(").append(i + 1).append(") ");
142             err.append(impl.describeRule());
143         }
144 
145         throw new InvalidWebSocketException(err.toString());
146     }
147 }