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.util.LinkedList;
22  import java.util.Queue;
23  
24  import org.eclipse.jetty.osgi.equinoxtools.console.WebConsoleWriterOutputStream.OnFlushListener;
25  
26  /**
27   * Processing of the messages to be received and sent to the chat servlets.
28   * Made to be extended for filtering of the messages and commands.
29   */
30  public class EquinoxChattingSupport
31  {
32      
33      private WebConsoleSession _consoleSession;
34      
35      public EquinoxChattingSupport(WebConsoleSession consoleSession)
36      {
37          _consoleSession = consoleSession;
38      }
39      
40      /**
41       * Split the output into multiple lines.
42       * Format them for the json messages sent to the chat.
43       * Empties the console output from what is already displayed in the chat.
44       * @return The lines to add to the message queue of each client.
45       */
46      protected Queue<String> processConsoleOutput(boolean escape, OnFlushListener onflush)
47      {
48          Queue<String> result = new LinkedList<String>();
49          String toDisplay = _consoleSession.getOutputAsWriter().getBuffer().toString();
50          //the last listener to be called is in charge of clearing the console.
51          boolean clearConsole = _consoleSession.getOnFlushListeners().indexOf(onflush) == _consoleSession.getOnFlushListeners().size();
52          if (clearConsole)
53          {
54              _consoleSession.clearOutput();
55          }
56          boolean lastLineIsComplete = toDisplay.endsWith("\n") || toDisplay.endsWith("\r");
57          String[] lines = toDisplay.split("\n");
58          String lastLine = lastLineIsComplete ? null : lines[lines.length-1];
59          if (clearConsole)
60          {
61              _consoleSession.getOutputAsWriter().append(lastLine);
62          }
63          for (int lnNb = 0; lnNb < (lastLineIsComplete ? lines.length : lines.length-1); lnNb++) 
64          {
65              String line = lines[lnNb];
66              while (line.trim().startsWith("null"))
67              {//hum..
68                  line = line.trim().substring("null".length()).trim();
69              }
70              if (line.startsWith("osgi>"))
71              {
72                  result.add("osgi>");
73                  result.add(escape ? jsonEscapeString(line.substring("osgi>".length())) : line.substring("osgi>".length()));
74              }
75              else
76              {
77                  result.add("&#10;");
78                  result.add(escape ? jsonEscapeString(line) : line);
79              }
80          }
81          return result;
82      }
83      
84      /**
85       * http://www.ietf.org/rfc/rfc4627.txt
86       * @param str
87       * @return The same string escaped according to the JSON RFC.
88       */
89      public static String jsonEscapeString(String str)
90      {
91          StringBuilder sb = new StringBuilder();
92          char[] asChars = str.toCharArray();
93          for (char ch : asChars)
94          {
95              switch (ch)
96              {
97                  //the reserved characters
98                  case '"':
99                      sb.append("\\\"");
100                     break;
101                 case '\\':
102                     sb.append("\\\\");
103                     break;
104                 case '\b':
105                     sb.append("\\b");
106                     break;
107                 case '\f':
108                     sb.append("\\f");
109                     break;
110                 case '\n':
111                     sb.append("\\n");
112                     break;
113                 case '\r':
114                     sb.append("\\r");
115                     break;
116                 case '\t':
117                     sb.append("\\t");
118                     break;
119                 case '/':
120                     sb.append("\\/");
121                     break;
122                 default:
123                     //The non reserved characters
124                     if (ch >= '\u0000' && ch <= '\u001F')
125                     {
126                         //escape as a unicode number when out of range.
127                         String ss = Integer.toHexString(ch);
128                         sb.append("\\u");
129                         for (int i = 0; i < 4 - ss.length(); i++)
130                         {
131                             //padding
132                             sb.append('0');
133                         }
134                         sb.append(ss.toUpperCase());
135                     }
136                     else
137                     {
138                         sb.append(ch);
139                     }
140             }
141         }
142         return sb.toString();
143     }
144     
145     public void broadcast(OnFlushListener source)
146     {
147         for (OnFlushListener onflush : _consoleSession.getOnFlushListeners())
148         {
149             if (onflush != source)
150             {
151                 onflush.onFlush();
152             }
153         }
154     }
155 
156 }