View Javadoc

1   // ========================================================================
2   // Copyright (c) 2006-2011 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  package org.eclipse.jetty.osgi.equinoxtools.console;
14  
15  import java.io.IOException;
16  import java.util.Queue;
17  import java.util.Set;
18  import java.util.concurrent.CopyOnWriteArraySet;
19  
20  import javax.servlet.ServletException;
21  import javax.servlet.http.HttpServletRequest;
22  import javax.servlet.http.HttpServletResponse;
23  
24  import org.eclipse.jetty.osgi.equinoxtools.WebEquinoxToolsActivator;
25  import org.eclipse.jetty.osgi.equinoxtools.console.WebConsoleWriterOutputStream.OnFlushListener;
26  import org.eclipse.jetty.util.log.Log;
27  import org.eclipse.jetty.util.log.Logger;
28  import org.eclipse.jetty.websocket.WebSocket;
29  import org.eclipse.jetty.websocket.WebSocketServlet;
30  import org.eclipse.osgi.framework.console.ConsoleSession;
31  
32  /**
33   * Websocket version of the Chat with equinox.
34   * Ported from jetty's example 'WebSocketChatServlet'
35   */
36  public class EquinoxConsoleWebSocketServlet extends WebSocketServlet implements OnFlushListener
37  {
38      private static final Logger LOG = Log.getLogger(EquinoxConsoleWebSocketServlet.class);
39  
40      private final Set<ChatWebSocket> _members = new CopyOnWriteArraySet<ChatWebSocket>();
41      private static final long serialVersionUID = 1L;
42      private WebConsoleSession _consoleSession;
43      private EquinoxChattingSupport _support;
44  
45      public EquinoxConsoleWebSocketServlet()
46      {
47          
48      }
49      public EquinoxConsoleWebSocketServlet(WebConsoleSession consoleSession, EquinoxChattingSupport support)
50      {
51          _consoleSession = consoleSession;
52          _support = support;
53      }
54      @Override
55      public void init() throws ServletException
56      {
57          if (_consoleSession == null)
58          {
59              _consoleSession = new WebConsoleSession();
60              WebEquinoxToolsActivator.getContext().registerService(ConsoleSession.class.getName(), _consoleSession, null);
61          }
62          if (_support == null)
63          {
64              _support = new EquinoxChattingSupport(_consoleSession);
65          }
66          super.init();
67          _consoleSession.addOnFlushListener(this);
68      }
69      
70      @Override
71      public void destroy()
72      {
73          _consoleSession.removeOnFlushListener(this);
74      }
75  
76      
77      protected void doGet(HttpServletRequest request, HttpServletResponse response) 
78          throws javax.servlet.ServletException ,IOException 
79      {
80          //getServletContext().getNamedDispatcher("default").forward(request,response);
81          response.sendRedirect(request.getContextPath() + request.getServletPath()
82                  + (request.getPathInfo() != null ? request.getPathInfo() : "") +  "/index.html");
83      };
84      
85      public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
86      {
87          return new ChatWebSocket();
88      }
89      
90      /* ------------------------------------------------------------ */
91      /* ------------------------------------------------------------ */
92      class ChatWebSocket implements WebSocket.OnTextMessage
93      {
94          Connection _connection;
95          String _username;
96          
97          public void onOpen(Connection connection)
98          {
99              // LOG.info(this+" onConnect");
100             _connection=connection;
101             _members.add(this);
102         }
103         
104         public void onMessage(byte frame, byte[] data,int offset, int length)
105         {
106             // LOG.info(this+" onMessage: "+TypeUtil.toHexString(data,offset,length));
107         }
108 
109         public void onMessage(String data)
110         {
111             LOG.info("onMessage: {}",data);
112             if (data.indexOf("disconnect")>=0)
113                 _connection.disconnect();
114             else
115             {
116                 if (!data.endsWith(":has joined!"))
117                 {
118                     if (_username != null)
119                     {
120                         if (data.startsWith(_username + ":"))
121                         {
122                             data = data.substring(_username.length()+1);
123                         }
124                         else
125                         {
126                             //we should not be here?
127                         }
128                     }
129                     _consoleSession.processCommand(data, false);
130                 }
131                 else
132                 {
133                     _username = data.substring(0, data.length()-":has joined!".length());
134                 }
135                 // LOG.info(this+" onMessage: "+data);
136                 onFlush();
137             }
138         }
139 
140         public void onClose(int code, String message)
141         {
142             // LOG.info(this+" onDisconnect");
143             _members.remove(this);
144         }
145 
146         public void onError(String message, Throwable ex)
147         {
148             
149         }
150 
151     }
152     
153     
154     /**
155      * Called right after the flush method on the output stream has been executed.
156      */
157     public void onFlush()
158     {
159         Queue<String> pendingConsoleOutputMessages = _support.processConsoleOutput(false, this);
160         for (ChatWebSocket member : _members)
161         {
162             try
163             {
164                 for (String line : pendingConsoleOutputMessages)
165                 {
166                     member._connection.sendMessage(line);
167                 }
168             }
169             catch(IOException e)
170             {
171                 LOG.warn(e);
172             }
173         }
174     }    
175 
176 }