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