View Javadoc

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