KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > rero > ircfw > Parsed1459


1 /**
2        .;: Parser for RFC 1459 - IRC Protocol :;.
3
4    Some of this code gets kind of ugly. Regex's all over the place.
5
6    Basically this class takes a String given by the IRC server and extracts
7    all relevant information we might care about into a Hashmap.
8
9    No extra processing is done here, just extract information from the protocol
10
11     Ugly code below. You shouldn't need to touch this though. That is why
12     it is framework code. !@#$%^
13
14  BNF Representation of Stuff from Server
15
16  <message> ::= ':' <prefix> <SPACE> <command> <params>
17                <command> <params>
18
19  <prefix> ::= <servername>
20                <nick> [ '!' <user> ] [ '@' <host> ]
21
22  <command> ::= <letter> { <letter> }
23                <number> <number> <number>
24
25  <SPACE> ::= ' ' { ' ' }
26
27  <params> ::= ':' <text>
28            ::= <middle> <params>
29
30   <middle> ::= a bunch of characters without the first one being a :, and no
31                white space
32
33 <trailing> ::= a bunch of white space
34
35 **/

36
37 package rero.ircfw;
38
39 import rero.ircfw.interfaces.FrameworkConstants;
40
41 import java.util.regex.Pattern JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import rero.util.StringParser;
44
45 public class Parsed1459 implements FrameworkConstants
46 {
47    //
48
// Yes, we are in write-only land with reg ex's. Sorry.
49
// Nick Pattern: ([\-|\[|\]|\\|\`|\^|\{|\}|\w]++)
50
// Nick Pattern: ([^!\.]+?) <-- safer
51
// User Pattern: ([\~\w]++)
52
// User Pattern: ([^\@]+?) <-- safer
53
// Host Pattern: (\w++[[\.|\:]\w++]*) hopefully works with either ipv4 or ipv6 addresses. - if my IP6 bit is bad then this
54
// will fuck up parsing royally and the client *WILL* crash.
55
// Chan Pattern: ([\#|\&]\S++)
56
//
57
protected static String JavaDoc nickPattern = "(.+?)";
58    protected static String JavaDoc userPattern = "(.+?)";
59    protected static String JavaDoc hostPattern2 = "(.+?)";
60
61    protected static String JavaDoc hostPattern = "([\\w\\-\\=]++[[\\.|\\:][\\w\\-\\=]++]*)";
62    protected static String JavaDoc channelPattern = "([\\#|\\&]\\S++)";
63
64    // ([\-|\[|\]|\\|\`|\^|\{|\}|\w|\-]++)!(([\~\w\-]++)@([\w\-]++[\.[\w\-]++]*))
65

66    protected static Pattern JavaDoc isHost = Pattern.compile(hostPattern);
67    protected static Pattern JavaDoc isNickUserHost = Pattern.compile(nickPattern+"!("+userPattern+"@"+hostPattern2+")"); // matches nick!user@host
68
protected static Pattern JavaDoc isNick = Pattern.compile(nickPattern);
69
70    protected static Pattern JavaDoc isNumeric = Pattern.compile("\\d++");
71    protected static Pattern JavaDoc isColonPresent = Pattern.compile(":(.++)");
72    protected static Pattern JavaDoc isWhiteSpace = Pattern.compile("XXX");
73
74    protected HashMap JavaDoc eventInformation;
75
76    public HashMap JavaDoc parseString (String JavaDoc data)
77    {
78       eventInformation = new HashMap JavaDoc();
79       
80       eventInformation.put($RAW$, data);
81
82       phase1(data, eventInformation);
83
84       return eventInformation;
85    }
86
87    //
88
// Phase 1 - grabs really basic info (source, command, parms)
89
// -------
90
//
91
private HashMap JavaDoc phase1 (String JavaDoc data, HashMap JavaDoc eventInformation)
92    {
93        StringParser parser;
94
95        parser = new StringParser(data, isColonPresent);
96        if (parser.matches())
97        {
98            // <message> ::= ':' <prefix> <SPACE> <command> <params>
99

100            String JavaDoc[] text = parser.getParsedString(0).split("\\s", 2);
101
102            parseSourceInformation(text[0], eventInformation);
103
104            data = text[1];
105        }
106
107        // <message> ::= <command> <params>
108
String JavaDoc text[] = data.split("\\s", 2);
109
110        if (isNumeric.matcher(text[0]).matches())
111        {
112            eventInformation.put($NUMERIC$, text[0]);
113        }
114
115        eventInformation.put($EVENT$, text[0]);
116
117        if (text.length > 1)
118        {
119           data = text[1];
120        }
121        else
122        {
123           data = "";
124        }
125
126        parseParameterInformation(data, eventInformation);
127
128        return eventInformation;
129    }
130
131    private HashMap JavaDoc parseParameterInformation (String JavaDoc data, HashMap JavaDoc eventInformation)
132    {
133        // <params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
134

135        //
136
// Generally the item after the COMMAND is a target or a set of parameters
137
// right here we are looking to see if it is the target or not.
138
//
139
StringParser parser = new StringParser(data, isColonPresent);
140        String JavaDoc text[] = data.split("\\s", 2);
141        int targetLength = 0;
142
143        if (!parser.matches())
144        {
145            text = data.split("\\s", 2);
146            eventInformation.put($TARGET$, text[0]);
147            targetLength = text[0].length() + 1;
148        }
149        else
150        {
151            if (((data.charAt(1) == '#') || (data.charAt(1) == '&')) && data.indexOf(' ') == -1)
152            {
153                // the parameter is a channel, this is put in place for broke assed ircds
154
// that don't know any better... grr.
155
data = data.substring(1, data.length());
156
157                return parseParameterInformation(data, eventInformation);
158            }
159            else
160            {
161                data = "<null> " + data;
162                targetLength = "<null>".length() + 1;
163            }
164
165            text = data.split("\\s", 2);
166            parser = new StringParser(data, isColonPresent);
167        }
168
169        StringBuffer JavaDoc parmsString = new StringBuffer JavaDoc();
170        
171        while (!parser.matches() && text.length > 1)
172        {
173            text = data.split("\\s", 2);
174
175            if (text.length > 1)
176            {
177               data = text[1];
178
179               parmsString.append(text[0]);
180               parmsString.append(" ");
181
182               parser = new StringParser(data, isColonPresent);
183            }
184        }
185
186        if (parser.matches())
187        {
188            parmsString.append(parser.getParsedString(0));
189        }
190        else if (!data.equals(":"))
191        {
192            parmsString.append(data);
193        }
194
195        eventInformation.put($DATA$, parmsString.toString());
196
197        if (targetLength < parmsString.toString().length())
198        {
199           eventInformation.put($PARMS$, parmsString.toString().substring(targetLength, parmsString.toString().length() ));
200        }
201        else
202        {
203           eventInformation.put($PARMS$, "");
204        }
205
206        return eventInformation;
207    }
208
209    private HashMap JavaDoc parseSourceInformation(String JavaDoc text, HashMap JavaDoc eventInformation)
210    {
211       StringParser parser = new StringParser(text, isNickUserHost);
212       if (parser.matches())
213       {
214           // Pattern> ([\-|\[|\]|\\|\`|\^|\{|\}|\w|\-]++)!(([\~\w\-]++)@([\w\-]++[\.[\w\-]++]*))
215
// Text> `butane!~uncle@istheman.chartermi.net
216
// Matches!
217
// 0: `butane
218
// 1: ~uncle@istheman.chartermi.net
219
// 2: ~uncle
220
// 3: istheman.chartermi.net
221

222           String JavaDoc[] data = parser.getParsedStrings();
223           eventInformation.put($NICK$, data[0]);
224           eventInformation.put($ADDRESS$, data[1]);
225           eventInformation.put($USER$, data[2]);
226           eventInformation.put($HOST$, data[3]);
227
228           eventInformation.put($SOURCE$, data[0]);
229
230           return eventInformation;
231       }
232   
233       parser = new StringParser(text, isHost);
234       if (parser.matches())
235       {
236           String JavaDoc[] data = parser.getParsedStrings();
237           eventInformation.put($SERVER$, data[0]);
238           eventInformation.put($NICK$, data[0]);
239           eventInformation.put($SOURCE$, data[0]);
240
241           return eventInformation;
242       }
243
244       parser = new StringParser(text, isNick);
245       if (parser.matches())
246       {
247           String JavaDoc[] data = parser.getParsedStrings();
248           eventInformation.put($NICK$, data[0]);
249           eventInformation.put($SOURCE$, data[0]);
250       }
251
252       return eventInformation;
253    }
254 }
255
Popular Tags