Dict.as 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*
  2. Copyright (c) 2009, Adobe Systems Incorporated
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are
  6. met:
  7. * Redistributions of source code must retain the above copyright notice,
  8. this list of conditions and the following disclaimer.
  9. * Redistributions in binary form must reproduce the above copyright
  10. notice, this list of conditions and the following disclaimer in the
  11. documentation and/or other materials provided with the distribution.
  12. * Neither the name of Adobe Systems Incorporated nor the names of its
  13. contributors may be used to endorse or promote products derived from
  14. this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  16. IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  17. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  18. PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  19. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  20. EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  21. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  22. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  23. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  24. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. package com.adobe.protocols.dict
  28. {
  29. import com.adobe.protocols.dict.events.*;
  30. import com.adobe.protocols.dict.util.*;
  31. import flash.events.Event;
  32. import flash.events.EventDispatcher;
  33. import flash.events.IOErrorEvent;
  34. import flash.events.ProgressEvent;
  35. import flash.events.SecurityErrorEvent;
  36. import flash.net.Socket;
  37. import mx.rpc.http.HTTPService;
  38. import mx.rpc.events.ResultEvent;
  39. import mx.rpc.events.FaultEvent;
  40. import flash.xml.XMLNode;
  41. import mx.utils.StringUtil;
  42. public class Dict
  43. extends EventDispatcher
  44. {
  45. // Event type names.
  46. //public static var CONNECTED:String = "connected";
  47. //public static var DISCONNECTED:String = "disconnected";
  48. public static var IO_ERROR:String = IOErrorEvent.IO_ERROR;
  49. //public static var ERROR:String = "error";
  50. //public static var SERVERS:String = "servers";
  51. //public static var DATABASES:String = "databases";
  52. //public static var MATCH_STRATEGIES:String = "matchStrategies";
  53. //public static var DEFINITION:String = "definition";
  54. //public static var DEFINITION_HEADER:String = "definitionHeader";
  55. //public static var MATCH:String = "match";
  56. //public static var NO_MATCH:String = "noMatch";
  57. public static var FIRST_MATCH:uint = 0;
  58. public static var ALL_DATABASES:uint = 1;
  59. private var socket:SocketHelper;
  60. private var dbShortList:Boolean;
  61. public function Dict()
  62. {
  63. this.socket = new SocketHelper();
  64. this.socket.addEventListener(Event.CONNECT, connected);
  65. this.socket.addEventListener(Event.CLOSE, disconnected);
  66. this.socket.addEventListener(SocketHelper.COMPLETE_RESPONSE, incomingData);
  67. this.socket.addEventListener(IOErrorEvent.IO_ERROR, ioError);
  68. this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);
  69. }
  70. public function connect(server:String, port:uint = 2628):void
  71. {
  72. if (this.socket.connected)
  73. {
  74. this.socket.close();
  75. }
  76. this.socket.connect(server, port);
  77. }
  78. public function connectThroughProxy(proxyServer:String,
  79. proxyPort:int,
  80. server:String,
  81. port:uint = 2628):void
  82. {
  83. if (this.socket.connected)
  84. {
  85. this.socket.close();
  86. }
  87. this.socket.setProxyInfo(proxyServer, proxyPort);
  88. this.socket.connect(server, port);
  89. }
  90. public function disconnect():void
  91. {
  92. this.socket.close();
  93. this.disconnected(null);
  94. }
  95. public function getServers():void
  96. {
  97. var http:HTTPService = new HTTPService();
  98. http.url = "http://luetzschena-stahmeln.de/dictd/xmllist.php";
  99. http.addEventListener(ResultEvent.RESULT, incomingServerXML);
  100. http.addEventListener(FaultEvent.FAULT, httpError);
  101. http.resultFormat = HTTPService.RESULT_FORMAT_E4X;
  102. http.send();
  103. }
  104. public function getDatabases(shortList:Boolean=true):void
  105. {
  106. this.dbShortList = shortList;
  107. this.socket.writeUTFBytes("show db\r\n");
  108. this.socket.flush();
  109. }
  110. public function getMatchStrategies():void
  111. {
  112. this.socket.writeUTFBytes("show strat\r\n");
  113. this.socket.flush();
  114. }
  115. public function match(database:String, term:String, scope:String="prefix"):void
  116. {
  117. this.socket.writeUTFBytes("match " + database + " " + scope + " \"" + term + "\"\r\n");
  118. this.socket.flush();
  119. }
  120. public function define(database:String, term:String):void
  121. {
  122. this.socket.writeUTFBytes("define " + database + " \"" + term + "\"\r\n");
  123. this.socket.flush();
  124. }
  125. public function lookup(term:String, scope:uint):void
  126. {
  127. var flag:String;
  128. if (scope == Dict.ALL_DATABASES)
  129. {
  130. flag = "*";
  131. }
  132. else if (scope == Dict.FIRST_MATCH)
  133. {
  134. flag = "!";
  135. }
  136. this.socket.writeUTFBytes("define " + flag + " \"" + term + "\"\r\n");
  137. this.socket.flush();
  138. }
  139. //// Private functions ////
  140. private function connected(event:Event):void
  141. {
  142. // Wait to dispatch an event until we get the 220 response.
  143. }
  144. private function disconnected(event:Event):void
  145. {
  146. dispatchEvent(new DisconnectedEvent(DisconnectedEvent.DISCONNECTED));
  147. }
  148. private function incomingServerXML(event:ResultEvent):void
  149. {
  150. var dictd:Namespace = new Namespace("http://www.luetzschena-stahmeln.de/dictd/");
  151. var result:XML = event.result as XML;
  152. var server:String, description:String;
  153. var servers:Array = new Array();
  154. for each (var serverNode:XML in result.dictd::server)
  155. {
  156. server = serverNode.dictd::dictdurl;
  157. description = serverNode.dictd::description;
  158. if (StringUtil.trim(server).length != 0 &&
  159. StringUtil.trim(description).length != 0)
  160. {
  161. var dServer:DictionaryServer = new DictionaryServer();
  162. dServer.server = server.replace("dict://", "");
  163. dServer.description = description;
  164. servers.push(dServer);
  165. }
  166. }
  167. var dEvent:DictionaryServerEvent = new DictionaryServerEvent(DictionaryServerEvent.SERVERS);
  168. dEvent.servers = servers;
  169. dispatchEvent(dEvent);
  170. }
  171. private function incomingData(event:CompleteResponseEvent):void
  172. {
  173. var rawResponse:String = event.response;
  174. var response:Response = this.parseRawResponse(rawResponse);
  175. var responseCode:uint = response.code;
  176. if (responseCode == 552) // no matches
  177. {
  178. throwNoMatchEvent(response);
  179. }
  180. else if (responseCode >= 400 && responseCode <= 599) // error
  181. {
  182. throwErrorEvent(response);
  183. }
  184. else if (responseCode == 220) // successful connection
  185. {
  186. dispatchEvent(new ConnectedEvent(ConnectedEvent.CONNECTED));
  187. }
  188. else if (responseCode == 110) // databases are being returned
  189. {
  190. throwDatabasesEvent(response);
  191. }
  192. else if (responseCode == 111) // matches strategies
  193. {
  194. throwMatchStrategiesEvent(response);
  195. }
  196. else if (responseCode == 152) // matches
  197. {
  198. throwMatchEvent(response);
  199. }
  200. else if (responseCode == 150)
  201. {
  202. throwDefinitionHeaderEvent(response);
  203. }
  204. else if (responseCode == 151)
  205. {
  206. throwDefinitionEvent(response);
  207. }
  208. }
  209. private function ioError(event:IOErrorEvent):void
  210. {
  211. dispatchEvent(event);
  212. }
  213. private function httpError(event:FaultEvent):void
  214. {
  215. trace("httpError!");
  216. }
  217. private function securityError(event:SecurityErrorEvent):void
  218. {
  219. trace("security error!");
  220. trace(event.text);
  221. }
  222. // Dispatch new events.
  223. private function throwDatabasesEvent(response:Response):void
  224. {
  225. var databases:Array = new Array();
  226. var responseArray:Array = response.body.split("\r\n");
  227. for each (var line:String in responseArray)
  228. {
  229. var name:String = line.substring(0, line.indexOf(" "));
  230. if (name == "--exit--")
  231. {
  232. if (this.dbShortList)
  233. {
  234. break;
  235. }
  236. continue;
  237. }
  238. var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
  239. databases.push(new Database(name, description));
  240. }
  241. var event:DatabaseEvent = new DatabaseEvent(DatabaseEvent.DATABASES);
  242. event.databases = databases;
  243. dispatchEvent(event);
  244. }
  245. private function throwMatchStrategiesEvent(response:Response):void
  246. {
  247. var strategies:Array = new Array();
  248. var responseArray:Array = response.body.split("\r\n");
  249. for each (var line:String in responseArray)
  250. {
  251. var name:String = line.substring(0, line.indexOf(" "));
  252. var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
  253. strategies.push(new MatchStrategy(name, description));
  254. }
  255. var event:MatchStrategiesEvent = new MatchStrategiesEvent(MatchStrategiesEvent.MATCH_STRATEGIES);
  256. event.strategies = strategies;
  257. dispatchEvent(event);
  258. }
  259. private function throwMatchEvent(response:Response):void
  260. {
  261. var matches:Array = new Array();
  262. var responseArray:Array = response.body.split("\r\n");
  263. for each (var line:String in responseArray)
  264. {
  265. var match:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");
  266. matches.push(match);
  267. }
  268. var event:MatchEvent = new MatchEvent(MatchEvent.MATCH);
  269. event.matches = matches;
  270. dispatchEvent(event);
  271. }
  272. private function throwErrorEvent(response:Response):void
  273. {
  274. var event:ErrorEvent = new ErrorEvent(ErrorEvent.ERROR);
  275. event.code = response.code;
  276. event.message = response.headerText;
  277. dispatchEvent(event);
  278. }
  279. private function throwNoMatchEvent(response:Response):void
  280. {
  281. dispatchEvent(new NoMatchEvent(NoMatchEvent.NO_MATCH));
  282. }
  283. private function throwDefinitionHeaderEvent(response:Response):void
  284. {
  285. var event:DefinitionHeaderEvent = new DefinitionHeaderEvent(DefinitionHeaderEvent.DEFINITION_HEADER);
  286. event.definitionCount = uint(response.headerText.substring(0, response.headerText.indexOf(" ")));
  287. dispatchEvent(event);
  288. }
  289. private function throwDefinitionEvent(response:Response):void
  290. {
  291. var event:DefinitionEvent = new DefinitionEvent(DefinitionEvent.DEFINITION);
  292. var def:Definition = new Definition();
  293. var headerText:String = response.headerText;
  294. var tokens:Array = headerText.match(/"[^"]+"/g);
  295. def.term = String(tokens[0]).replace(/"/g, "");
  296. def.database = String(tokens[1]).replace(/"/g, "");
  297. def.definition = response.body;
  298. event.definition = def;
  299. dispatchEvent(event);
  300. }
  301. private function parseRawResponse(rawResponse:String):Response
  302. {
  303. var response:Response = new Response();
  304. var fullHeader:String;
  305. if (rawResponse.indexOf("\r\n") != -1)
  306. {
  307. fullHeader = rawResponse.substring(0, rawResponse.indexOf("\r\n"));
  308. }
  309. else
  310. {
  311. fullHeader = rawResponse;
  312. }
  313. var responseCodeMatch:Array = fullHeader.match(/^\d{3}/);
  314. response.code = uint(responseCodeMatch[0]);
  315. response.headerText = fullHeader.substring(fullHeader.indexOf(" ")+1, fullHeader.length);
  316. var body:String = rawResponse.substring(rawResponse.indexOf("\r\n")+2, rawResponse.length);
  317. body = body.replace(/\r\n\.\./, "\r\n.");
  318. response.body = body;
  319. return response;
  320. }
  321. }
  322. }