1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.irc;
import net.java.sip.communicator.util.*;
import org.apache.commons.lang3.*;
/**
* Some IRC-related utility methods.
*
* @author Danny van Heumen
*/
public final class Utils
{
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(Utils.class);
/**
* Index indicating the end of the foreground color code.
*/
private static final int INDEX_END_FOREGROUND_COLOR_CODE = 2;
/**
* Index indicating the end of the background color code. (additional 1 for
* comma separating foreground color code from background color code)
*/
private static final int INDEX_END_BACKGROUND_COLOR_CODE = 3;
/**
* Private constructor since we do not need to construct anything.
*/
private Utils()
{
}
/**
* Parse IRC text message and process possible control codes.
*
* TODO Support for color 99 (Transparent)
*
* @param text the message
* @return returns the processed message or null if text message was null,
* since there is nothing to modify there
*/
public static String parseIrcMessage(final String text)
{
if (text == null)
{
return null;
}
FormattedTextBuilder builder = new FormattedTextBuilder();
for (int i = 0; i < text.length(); i++)
{
char val = text.charAt(i);
switch (val)
{
case ControlChar.Bold.CODE:
if (builder.isActive(ControlChar.Bold.class))
{
builder.cancel(ControlChar.Bold.class, true);
}
else
{
builder.apply(new ControlChar.Bold());
}
break;
case ControlChar.Italics.CODE:
if (builder.isActive(ControlChar.Italics.class))
{
builder.cancel(ControlChar.Italics.class, true);
}
else
{
builder.apply(new ControlChar.Italics());
}
break;
case ControlChar.Underline.CODE:
if (builder.isActive(ControlChar.Underline.class))
{
builder.cancel(ControlChar.Underline.class, true);
}
else
{
builder.apply(new ControlChar.Underline());
}
break;
case ControlChar.ColorFormat.CODE:
// first parse foreground color code
Color foreground = parseForegroundColor(text.substring(i + 1));
if (foreground == null)
{
builder.cancel(ControlChar.ColorFormat.class, false);
}
else
{
i += INDEX_END_FOREGROUND_COLOR_CODE;
Color background =
parseBackgroundColor(text.substring(i + 1));
if (background != null)
{
i += INDEX_END_BACKGROUND_COLOR_CODE;
}
builder.apply(new ControlChar.ColorFormat(foreground,
background));
}
break;
case ControlChar.Normal.CODE:
builder.cancelAll();
break;
default:
// value is a normal character, escape html entities and append
builder.append(StringEscapeUtils.escapeHtml4("" + val));
break;
}
}
return builder.done();
}
/**
* Parse background color code starting with the separator.
*
* @param text the text starting with the background color (separator)
* @return returns the background color
*/
private static Color parseBackgroundColor(final String text)
{
try
{
if (text.charAt(0) == ',')
{
// if available, also parse background color
int color =
Integer.parseInt("" + text.charAt(1) + text.charAt(2));
color = color % Color.values().length;
return Color.values()[color];
}
return null;
}
catch (StringIndexOutOfBoundsException e)
{
// Abort parsing background color. Assume only
// foreground color available.
LOGGER.trace("Abort parsing background color because text ended. "
+ "Assuming only foreground color was available.");
return null;
}
catch (NumberFormatException e)
{
// No background color defined, ignoring ...
LOGGER.trace("No background color defined. Ignoring ...");
return null;
}
}
/**
* Parse foreground color and return corresponding Color instance.
*
* @param text the text to parse, starting with color code
* @return returns Color instance
*/
private static Color parseForegroundColor(final String text)
{
try
{
int color = Integer.parseInt("" + text.charAt(0) + text.charAt(1));
color = color % Color.values().length;
return Color.values()[color];
}
catch (StringIndexOutOfBoundsException e)
{
// Invalid control code, since text has ended.
LOGGER.trace("ArrayIndexOutOfBounds during foreground "
+ "color control code parsing.");
return null;
}
catch (NumberFormatException e)
{
LOGGER.trace("Invalid foreground color code encountered.", e);
return null;
}
}
/**
* Format message as normal HTML-formatted message.
*
* @param message original IRC message
* @return returns HTML-formatted normal message
*/
public static String styleAsMessage(final String message)
{
return message;
}
/**
* Format message as HTML-formatted notice.
*
* @param message original IRC message
* @param user user nick name
* @return returns HTML-formatted notice
*/
public static String styleAsNotice(final String message, final String user)
{
return "<i>" + user + "</i>: " + message;
}
/**
* Format message as HTML-formatted action.
*
* @param message original IRC message
* @param user user nick name
* @return returns HTML-formatted action
*/
public static String styleAsAction(final String message, final String user)
{
return "<b>*" + user + "</b> " + message;
}
}
|