1 package com.adobe.protocols.dict
\r
3 import com.adobe.protocols.dict.events.*;
\r
4 import com.adobe.protocols.dict.util.*;
\r
6 import flash.events.Event;
\r
7 import flash.events.EventDispatcher;
\r
8 import flash.events.IOErrorEvent;
\r
9 import flash.events.ProgressEvent;
\r
10 import flash.events.SecurityErrorEvent;
\r
11 import flash.net.Socket;
\r
12 import mx.rpc.http.HTTPService;
\r
13 import mx.rpc.events.ResultEvent;
\r
14 import mx.rpc.events.FaultEvent;
\r
15 import flash.xml.XMLNode;
\r
16 import mx.utils.StringUtil;
\r
19 extends EventDispatcher
\r
21 // Event type names.
\r
22 public static var CONNECTED:String = "connected";
\r
23 public static var DISCONNECTED:String = "disconnected";
\r
24 public static var IO_ERROR:String = IOErrorEvent.IO_ERROR;
\r
25 public static var ERROR:String = "error";
\r
26 public static var SERVERS:String = "servers";
\r
27 public static var DATABASES:String = "databases";
\r
28 public static var MATCH_STRATEGIES:String = "matchStrategies";
\r
29 public static var DEFINITION:String = "definition";
\r
30 public static var DEFINITION_HEADER:String = "definitionHeader";
\r
31 public static var MATCH:String = "match";
\r
32 public static var NO_MATCH:String = "noMatch";
\r
34 public static var FIRST_MATCH:uint = 0;
\r
35 public static var ALL_DATABASES:uint = 1;
\r
37 private var socket:SocketHelper;
\r
39 private var dbShortList:Boolean;
\r
41 public function Dict()
\r
43 this.socket = new SocketHelper();
\r
44 this.socket.addEventListener(Event.CONNECT, connected);
\r
45 this.socket.addEventListener(Event.CLOSE, disconnected);
\r
46 this.socket.addEventListener(SocketHelper.COMPLETE_RESPONSE, incomingData);
\r
47 this.socket.addEventListener(IOErrorEvent.IO_ERROR, ioError);
\r
48 this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);
\r
51 public function connect(server:String, port:uint = 2628):void
\r
53 if (this.socket.connected)
\r
55 this.socket.close();
\r
57 this.socket.connect(server, port);
\r
60 public function connectThroughProxy(proxyServer:String,
\r
63 port:uint = 2628):void
\r
65 if (this.socket.connected)
\r
67 this.socket.close();
\r
69 this.socket.setProxyInfo(proxyServer, proxyPort);
\r
70 this.socket.connect(server, port);
\r
73 public function disconnect():void
\r
75 this.socket.close();
\r
76 this.disconnected(null);
\r
79 public function getServers():void
\r
81 var http:HTTPService = new HTTPService();
\r
82 http.url = "http://luetzschena-stahmeln.de/dictd/xmllist.php";
\r
83 http.addEventListener(ResultEvent.RESULT, incomingServerXML);
\r
84 http.addEventListener(FaultEvent.FAULT, httpError);
\r
85 http.resultFormat = HTTPService.RESULT_FORMAT_E4X;
\r
89 public function getDatabases(shortList:Boolean=true):void
\r
91 this.dbShortList = shortList;
\r
92 this.socket.writeUTFBytes("show db\r\n");
\r
93 this.socket.flush();
\r
96 public function getMatchStrategies():void
\r
98 this.socket.writeUTFBytes("show strat\r\n");
\r
99 this.socket.flush();
\r
102 public function match(database:String, term:String, scope:String="prefix"):void
\r
104 this.socket.writeUTFBytes("match " + database + " " + scope + " \"" + term + "\"\r\n");
\r
105 this.socket.flush();
\r
108 public function define(database:String, term:String):void
\r
110 this.socket.writeUTFBytes("define " + database + " \"" + term + "\"\r\n");
\r
111 this.socket.flush();
\r
114 public function lookup(term:String, scope:uint):void
\r
117 if (scope == Dict.ALL_DATABASES)
\r
121 else if (scope == Dict.FIRST_MATCH)
\r
125 this.socket.writeUTFBytes("define " + flag + " \"" + term + "\"\r\n");
\r
126 this.socket.flush();
\r
129 //// Private functions ////
\r
131 private function connected(event:Event):void
\r
133 // Wait to dispatch an event until we get the 220 response.
\r
136 private function disconnected(event:Event):void
\r
138 dispatchEvent(new DisconnectedEvent());
\r
141 private function incomingServerXML(event:ResultEvent):void
\r
143 var dictd:Namespace = new Namespace("http://www.luetzschena-stahmeln.de/dictd/");
\r
144 var result:XML = event.result as XML;
\r
145 var server:String, description:String;
\r
146 var servers:Array = new Array();
\r
147 for each (var serverNode:XML in result.dictd::server)
\r
149 server = serverNode.dictd::dictdurl;
\r
150 description = serverNode.dictd::description;
\r
151 if (StringUtil.trim(server).length != 0 &&
\r
152 StringUtil.trim(description).length != 0)
\r
154 var dServer:DictionaryServer = new DictionaryServer();
\r
155 dServer.server = server.replace("dict://", "");
\r
156 dServer.description = description;
\r
157 servers.push(dServer);
\r
160 var dEvent:DictionaryServerEvent = new DictionaryServerEvent();
\r
161 dEvent.servers = servers;
\r
162 dispatchEvent(dEvent);
\r
165 private function incomingData(event:CompleteResponseEvent):void
\r
167 var rawResponse:String = event.response;
\r
168 var response:Response = this.parseRawResponse(rawResponse);
\r
169 var responseCode:uint = response.code;
\r
170 if (responseCode == 552) // no matches
\r
172 throwNoMatchEvent(response);
\r
174 else if (responseCode >= 400 && responseCode <= 599) // error
\r
176 throwErrorEvent(response);
\r
178 else if (responseCode == 220) // successful connection
\r
180 dispatchEvent(new ConnectedEvent());
\r
182 else if (responseCode == 110) // databases are being returned
\r
184 throwDatabasesEvent(response);
\r
186 else if (responseCode == 111) // matches strategies
\r
188 throwMatchStrategiesEvent(response);
\r
190 else if (responseCode == 152) // matches
\r
192 throwMatchEvent(response);
\r
194 else if (responseCode == 150)
\r
196 throwDefinitionHeaderEvent(response);
\r
198 else if (responseCode == 151)
\r
200 throwDefinitionEvent(response);
\r
204 private function ioError(event:IOErrorEvent):void
\r
206 dispatchEvent(event);
\r
209 private function httpError(event:FaultEvent):void
\r
211 trace("httpError!");
\r
214 private function securityError(event:SecurityErrorEvent):void
\r
216 trace("security error!");
\r
220 // Dispatch new events.
\r
222 private function throwDatabasesEvent(response:Response):void
\r
224 var databases:Array = new Array();
\r
225 var responseArray:Array = response.body.split("\r\n");
\r
226 for each (var line:String in responseArray)
\r
228 var name:String = line.substring(0, line.indexOf(" "));
\r
229 if (name == "--exit--")
\r
231 if (this.dbShortList)
\r
237 var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
\r
238 databases.push(new Database(name, description));
\r
240 var event:DatabaseEvent = new DatabaseEvent();
\r
241 event.databases = databases;
\r
242 dispatchEvent(event);
\r
245 private function throwMatchStrategiesEvent(response:Response):void
\r
247 var strategies:Array = new Array();
\r
248 var responseArray:Array = response.body.split("\r\n");
\r
249 for each (var line:String in responseArray)
\r
251 var name:String = line.substring(0, line.indexOf(" "));
\r
252 var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
\r
253 strategies.push(new MatchStrategy(name, description));
\r
255 var event:MatchStrategiesEvent = new MatchStrategiesEvent();
\r
256 event.strategies = strategies;
\r
257 dispatchEvent(event);
\r
260 private function throwMatchEvent(response:Response):void
\r
262 var matches:Array = new Array();
\r
263 var responseArray:Array = response.body.split("\r\n");
\r
264 for each (var line:String in responseArray)
\r
266 var match:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
\r
267 matches.push(match);
\r
269 var event:MatchEvent = new MatchEvent();
\r
270 event.matches = matches;
\r
271 dispatchEvent(event);
\r
274 private function throwErrorEvent(response:Response):void
\r
276 var event:ErrorEvent = new ErrorEvent();
\r
277 event.code = response.code;
\r
278 event.message = response.headerText;
\r
279 dispatchEvent(event);
\r
282 private function throwNoMatchEvent(response:Response):void
\r
284 dispatchEvent(new NoMatchEvent());
\r
287 private function throwDefinitionHeaderEvent(response:Response):void
\r
289 var event:DefinitionHeaderEvent = new DefinitionHeaderEvent();
\r
290 event.definitionCount = uint(response.headerText.substring(0, response.headerText.indexOf(" ")));
\r
291 dispatchEvent(event);
\r
294 private function throwDefinitionEvent(response:Response):void
\r
296 var event:DefinitionEvent = new DefinitionEvent();
\r
297 var def:Definition = new Definition();
\r
298 var headerText:String = response.headerText;
\r
299 var tokens:Array = headerText.match(/"[^"]+"/g);
\r
300 def.term = String(tokens[0]).replace(/"/g, "");
\r
301 def.database = String(tokens[1]).replace(/"/g, "");
\r
302 def.definition = response.body;
\r
303 event.definition = def;
\r
304 dispatchEvent(event);
\r
307 private function parseRawResponse(rawResponse:String):Response
\r
309 var response:Response = new Response();
\r
310 var fullHeader:String;
\r
311 if (rawResponse.indexOf("\r\n") != -1)
\r
313 fullHeader = rawResponse.substring(0, rawResponse.indexOf("\r\n"));
\r
317 fullHeader = rawResponse;
\r
319 var responseCodeMatch:Array = fullHeader.match(/^\d{3}/);
\r
320 response.code = uint(responseCodeMatch[0]);
\r
321 response.headerText = fullHeader.substring(fullHeader.indexOf(" ")+1, fullHeader.length);
\r
322 var body:String = rawResponse.substring(rawResponse.indexOf("\r\n")+2, rawResponse.length);
\r
323 body = body.replace(/\r\n\.\./, "\r\n.");
\r
324 response.body = body;
\r