--- /dev/null
+package com.adobe.protocols.dict\r
+{\r
+ import com.adobe.protocols.dict.events.*;\r
+ import com.adobe.protocols.dict.util.*;\r
+ \r
+ import flash.events.Event;\r
+ import flash.events.EventDispatcher;\r
+ import flash.events.IOErrorEvent;\r
+ import flash.events.ProgressEvent;\r
+ import flash.events.SecurityErrorEvent;\r
+ import flash.net.Socket;\r
+ import mx.rpc.http.HTTPService;\r
+ import mx.rpc.events.ResultEvent;\r
+ import mx.rpc.events.FaultEvent;\r
+ import flash.xml.XMLNode;\r
+ import mx.utils.StringUtil;\r
+\r
+ public class Dict\r
+ extends EventDispatcher\r
+ {\r
+ // Event type names.\r
+ public static var CONNECTED:String = "connected";\r
+ public static var DISCONNECTED:String = "disconnected";\r
+ public static var IO_ERROR:String = IOErrorEvent.IO_ERROR;\r
+ public static var ERROR:String = "error";\r
+ public static var SERVERS:String = "servers";\r
+ public static var DATABASES:String = "databases";\r
+ public static var MATCH_STRATEGIES:String = "matchStrategies";\r
+ public static var DEFINITION:String = "definition";\r
+ public static var DEFINITION_HEADER:String = "definitionHeader";\r
+ public static var MATCH:String = "match";\r
+ public static var NO_MATCH:String = "noMatch";\r
+\r
+ public static var FIRST_MATCH:uint = 0;\r
+ public static var ALL_DATABASES:uint = 1;\r
+\r
+ private var socket:SocketHelper;\r
+ \r
+ private var dbShortList:Boolean;\r
+\r
+ public function Dict()\r
+ {\r
+ this.socket = new SocketHelper();\r
+ this.socket.addEventListener(Event.CONNECT, connected);\r
+ this.socket.addEventListener(Event.CLOSE, disconnected);\r
+ this.socket.addEventListener(SocketHelper.COMPLETE_RESPONSE, incomingData);\r
+ this.socket.addEventListener(IOErrorEvent.IO_ERROR, ioError);\r
+ this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityError);\r
+ }\r
+\r
+ public function connect(server:String, port:uint = 2628):void\r
+ {\r
+ if (this.socket.connected)\r
+ {\r
+ this.socket.close();\r
+ }\r
+ this.socket.connect(server, port);\r
+ }\r
+\r
+ public function connectThroughProxy(proxyServer:String,\r
+ proxyPort:int,\r
+ server:String,\r
+ port:uint = 2628):void\r
+ {\r
+ if (this.socket.connected)\r
+ {\r
+ this.socket.close();\r
+ }\r
+ this.socket.setProxyInfo(proxyServer, proxyPort);\r
+ this.socket.connect(server, port);\r
+ }\r
+\r
+ public function disconnect():void\r
+ {\r
+ this.socket.close();\r
+ this.disconnected(null);\r
+ }\r
+\r
+ public function getServers():void\r
+ {\r
+ var http:HTTPService = new HTTPService();\r
+ http.url = "http://luetzschena-stahmeln.de/dictd/xmllist.php";\r
+ http.addEventListener(ResultEvent.RESULT, incomingServerXML);\r
+ http.addEventListener(FaultEvent.FAULT, httpError);\r
+ http.resultFormat = HTTPService.RESULT_FORMAT_E4X;\r
+ http.send();\r
+ }\r
+\r
+ public function getDatabases(shortList:Boolean=true):void\r
+ {\r
+ this.dbShortList = shortList;\r
+ this.socket.writeUTFBytes("show db\r\n");\r
+ this.socket.flush();\r
+ }\r
+\r
+ public function getMatchStrategies():void\r
+ {\r
+ this.socket.writeUTFBytes("show strat\r\n");\r
+ this.socket.flush();\r
+ }\r
+\r
+ public function match(database:String, term:String, scope:String="prefix"):void\r
+ {\r
+ this.socket.writeUTFBytes("match " + database + " " + scope + " \"" + term + "\"\r\n");\r
+ this.socket.flush();\r
+ }\r
+\r
+ public function define(database:String, term:String):void\r
+ {\r
+ this.socket.writeUTFBytes("define " + database + " \"" + term + "\"\r\n");\r
+ this.socket.flush();\r
+ }\r
+\r
+ public function lookup(term:String, scope:uint):void\r
+ {\r
+ var flag:String;\r
+ if (scope == Dict.ALL_DATABASES)\r
+ {\r
+ flag = "*";\r
+ }\r
+ else if (scope == Dict.FIRST_MATCH)\r
+ {\r
+ flag = "!";\r
+ }\r
+ this.socket.writeUTFBytes("define " + flag + " \"" + term + "\"\r\n");\r
+ this.socket.flush();\r
+ }\r
+\r
+ //// Private functions ////\r
+\r
+ private function connected(event:Event):void\r
+ {\r
+ // Wait to dispatch an event until we get the 220 response.\r
+ }\r
+\r
+ private function disconnected(event:Event):void\r
+ {\r
+ dispatchEvent(new DisconnectedEvent());\r
+ }\r
+\r
+ private function incomingServerXML(event:ResultEvent):void\r
+ {\r
+ var dictd:Namespace = new Namespace("http://www.luetzschena-stahmeln.de/dictd/");\r
+ var result:XML = event.result as XML;\r
+ var server:String, description:String;\r
+ var servers:Array = new Array();\r
+ for each (var serverNode:XML in result.dictd::server)\r
+ {\r
+ server = serverNode.dictd::dictdurl;\r
+ description = serverNode.dictd::description;\r
+ if (StringUtil.trim(server).length != 0 &&\r
+ StringUtil.trim(description).length != 0)\r
+ {\r
+ var dServer:DictionaryServer = new DictionaryServer();\r
+ dServer.server = server.replace("dict://", "");\r
+ dServer.description = description;\r
+ servers.push(dServer);\r
+ }\r
+ }\r
+ var dEvent:DictionaryServerEvent = new DictionaryServerEvent();\r
+ dEvent.servers = servers;\r
+ dispatchEvent(dEvent);\r
+ }\r
+\r
+ private function incomingData(event:CompleteResponseEvent):void\r
+ { \r
+ var rawResponse:String = event.response;\r
+ var response:Response = this.parseRawResponse(rawResponse);\r
+ var responseCode:uint = response.code;\r
+ if (responseCode == 552) // no matches\r
+ {\r
+ throwNoMatchEvent(response);\r
+ }\r
+ else if (responseCode >= 400 && responseCode <= 599) // error\r
+ {\r
+ throwErrorEvent(response);\r
+ }\r
+ else if (responseCode == 220) // successful connection\r
+ {\r
+ dispatchEvent(new ConnectedEvent());\r
+ }\r
+ else if (responseCode == 110) // databases are being returned\r
+ {\r
+ throwDatabasesEvent(response); \r
+ }\r
+ else if (responseCode == 111) // matches strategies\r
+ {\r
+ throwMatchStrategiesEvent(response);\r
+ }\r
+ else if (responseCode == 152) // matches\r
+ {\r
+ throwMatchEvent(response);\r
+ }\r
+ else if (responseCode == 150)\r
+ {\r
+ throwDefinitionHeaderEvent(response);\r
+ }\r
+ else if (responseCode == 151)\r
+ {\r
+ throwDefinitionEvent(response);\r
+ }\r
+ }\r
+\r
+ private function ioError(event:IOErrorEvent):void\r
+ {\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function httpError(event:FaultEvent):void\r
+ {\r
+ trace("httpError!");\r
+ }\r
+\r
+ private function securityError(event:SecurityErrorEvent):void\r
+ {\r
+ trace("security error!");\r
+ trace(event.text);\r
+ }\r
+\r
+ // Dispatch new events.\r
+\r
+ private function throwDatabasesEvent(response:Response):void\r
+ {\r
+ var databases:Array = new Array();\r
+ var responseArray:Array = response.body.split("\r\n");\r
+ for each (var line:String in responseArray)\r
+ {\r
+ var name:String = line.substring(0, line.indexOf(" "));\r
+ if (name == "--exit--")\r
+ {\r
+ if (this.dbShortList)\r
+ {\r
+ break;\r
+ }\r
+ continue;\r
+ }\r
+ var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");\r
+ databases.push(new Database(name, description));\r
+ }\r
+ var event:DatabaseEvent = new DatabaseEvent();\r
+ event.databases = databases;\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function throwMatchStrategiesEvent(response:Response):void\r
+ {\r
+ var strategies:Array = new Array();\r
+ var responseArray:Array = response.body.split("\r\n");\r
+ for each (var line:String in responseArray)\r
+ {\r
+ var name:String = line.substring(0, line.indexOf(" "));\r
+ var description:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");\r
+ strategies.push(new MatchStrategy(name, description));\r
+ }\r
+ var event:MatchStrategiesEvent = new MatchStrategiesEvent();\r
+ event.strategies = strategies;\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function throwMatchEvent(response:Response):void\r
+ {\r
+ var matches:Array = new Array();\r
+ var responseArray:Array = response.body.split("\r\n");\r
+ for each (var line:String in responseArray)\r
+ {\r
+ var match:String = line.substring(line.indexOf(" ")+1, line.length).replace(/\"/g,"");\r
+ matches.push(match);\r
+ }\r
+ var event:MatchEvent = new MatchEvent();\r
+ event.matches = matches;\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function throwErrorEvent(response:Response):void\r
+ {\r
+ var event:ErrorEvent = new ErrorEvent();\r
+ event.code = response.code;\r
+ event.message = response.headerText;\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function throwNoMatchEvent(response:Response):void\r
+ {\r
+ dispatchEvent(new NoMatchEvent());\r
+ }\r
+\r
+ private function throwDefinitionHeaderEvent(response:Response):void\r
+ {\r
+ var event:DefinitionHeaderEvent = new DefinitionHeaderEvent();\r
+ event.definitionCount = uint(response.headerText.substring(0, response.headerText.indexOf(" ")));\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function throwDefinitionEvent(response:Response):void\r
+ {\r
+ var event:DefinitionEvent = new DefinitionEvent();\r
+ var def:Definition = new Definition();\r
+ var headerText:String = response.headerText;\r
+ var tokens:Array = headerText.match(/"[^"]+"/g);\r
+ def.term = String(tokens[0]).replace(/"/g, "");\r
+ def.database = String(tokens[1]).replace(/"/g, "");\r
+ def.definition = response.body;\r
+ event.definition = def;\r
+ dispatchEvent(event);\r
+ }\r
+\r
+ private function parseRawResponse(rawResponse:String):Response\r
+ {\r
+ var response:Response = new Response();\r
+ var fullHeader:String;\r
+ if (rawResponse.indexOf("\r\n") != -1)\r
+ {\r
+ fullHeader = rawResponse.substring(0, rawResponse.indexOf("\r\n"));\r
+ }\r
+ else\r
+ {\r
+ fullHeader = rawResponse;\r
+ }\r
+ var responseCodeMatch:Array = fullHeader.match(/^\d{3}/);\r
+ response.code = uint(responseCodeMatch[0]);\r
+ response.headerText = fullHeader.substring(fullHeader.indexOf(" ")+1, fullHeader.length);\r
+ var body:String = rawResponse.substring(rawResponse.indexOf("\r\n")+2, rawResponse.length);\r
+ body = body.replace(/\r\n\.\./, "\r\n.");\r
+ response.body = body;\r
+ return response;\r
+ }\r
+ }\r
+}
\ No newline at end of file