11package protocol
22
33import (
4+ "fmt"
45 "log"
56 "net/http"
67 "os"
@@ -45,6 +46,12 @@ type KeywordNamesReturnValue struct {
4546 Keywords []interface {}
4647}
4748
49+ var offeredLibrary interface {}
50+
51+ func (h * RobotRemoteService ) InitilizeRemoteLibrary (library interface {}) {
52+ offeredLibrary = library
53+ }
54+
4855//sample XML-RPC input: <methodCall><methodName>GetKeywordNames</methodName><params></params></methodCall>
4956/* sample XML-RPC output:
5057 * <methodResponse><params><param><value><array><data>
@@ -56,6 +63,13 @@ type KeywordNamesReturnValue struct {
5663func (h * RobotRemoteService ) GetKeywordNames (r * http.Request , args * struct {}, reply * KeywordNamesReturnValue ) error {
5764 //TODO: use reflection to generate array of keywords (found in the imported namespace) to return in reply
5865 //maybe rather than all imported packages, restrict to a specific one, etc. as specified at server startup?
66+ //keywordLibrary := new(offeredLibrary)
67+ libraryKeywords := reflect .TypeOf (offeredLibrary )
68+ //libraryKeywords := reflect.PtrTo(reflect.TypeOf(offeredLibrary{}))
69+ log .Printf ("Found %d keywords" , libraryKeywords .NumMethod ())
70+ for i := 0 ; i < libraryKeywords .NumMethod (); i ++ {
71+ reply .Keywords = append (reply .Keywords , libraryKeywords .Method (i ).Name )
72+ }
5973
6074 //add special keyword built-in to the server:
6175 reply .Keywords = append (reply .Keywords , "StopRemoteServer" )
@@ -76,6 +90,10 @@ func _stopRemoteServer() {
7690 os .Exit (1 )
7791}
7892
93+ type Response struct {
94+ Content RunKeywordReturnValue
95+ }
96+
7997type RunKeywordReturnValue struct {
8098 Return interface {} `xml:"return"`
8199 Status string `xml:"status"`
@@ -131,36 +149,45 @@ type KeywordAndArgsInput struct {
131149 */
132150//this function doesn't fully work yet, see
133151//https://github.com/divan/gorilla-xmlrpc/issues/ #16 and 18
134- func (h * RobotRemoteService ) RunKeyword (r * http.Request , args * KeywordAndArgsInput , reply * RunKeywordReturnValue ) error {
152+ func (h * RobotRemoteService ) RunKeyword (r * http.Request , args * KeywordAndArgsInput , reply * Response ) error {
135153 //use reflection to run function "keyword name" out of 1st arg
136154 //with 2nd arg (array) containing the args for the keyword function
137155 //sample debug/test code for now...
138156 log .Printf ("keyword: %+v\n " , args .KeywordName )
157+ log .Printf ("args: %+v\n " , args .KeywordAguments )
158+
159+ reply .Content .Status = "PASS"
160+
139161 if args .KeywordName == "StopRemoteServer" {
140162 go h .StopRemoteServer ()
141- }
142- log .Printf ("args: %+v\n " , args .KeywordAguments )
143- for _ , a := range args .KeywordAguments {
144- log .Printf ("arg: %+v\n " , a )
145- switch reflect .TypeOf (a ).Kind () {
146- case reflect .Slice :
147- log .Printf ("args:\n " )
148- s := reflect .ValueOf (a )
149- for i := 0 ; i < s .Len (); i ++ {
150- log .Printf ("%v: %+v\n " , i , s .Index (i ))
163+ } else {
164+ method := reflect .ValueOf (offeredLibrary ).MethodByName (args .KeywordName )
165+ if method .Type ().NumIn () == len (args .KeywordAguments ) {
166+ in := make ([]reflect.Value , method .Type ().NumIn ())
167+ for i := 0 ; i < method .Type ().NumIn (); i ++ {
168+ var object interface {}
169+ if method .Type ().In (i ).Kind () == reflect .Ptr {
170+ object = offeredLibrary
171+ } else {
172+ object = args .KeywordAguments [i ]
173+ }
174+ fmt .Println (i , "->" , object )
175+ in [i ] = reflect .ValueOf (object )
176+ }
177+ returnValue := method .Call (in )
178+ if method .Type ().NumOut () == 1 {
179+ reply .Content .Return = returnValue [0 ].Interface ()
180+ } else if method .Type ().NumOut () > 1 {
181+ reply .Content .Stderr = "supporting only 0 or 1 return values"
151182 }
152- default :
153- log .Println ("Somehow didn't get an array of arguments for keyword." )
183+ } else {
184+ reply .Content .Stderr = fmt .Sprintf ("incorrect amount of input variables; expected %d and got %d" , method .Type ().NumIn ()- 1 , len (args .KeywordAguments ))
185+ reply .Content .Status = "FAIL"
154186 }
155187 }
156- //and return the results in struct below (sample static output for now):
157- var retval interface {}
158- retval = 42 //truth of life
159- reply .Return = retval
160- reply .Status = "FAIL"
161- reply .Stdout = "TODO: stdout from keyword execution gets piped into this"
162- reply .Stderr = "TODO: stderr from keyword execution gets piped into this"
163- reply .Traceback = "TODO: stack trace info goes here, if any..."
188+ reply .Content .Stdout = "TODO: stdout from keyword execution gets piped into this"
189+ //reply.Content.Stderr = "TODO: stderr from keyword execution gets piped into this"
190+ reply .Content .Traceback = "TODO: stack trace info goes here, if any..."
164191 return nil
165192}
166193
@@ -179,9 +206,21 @@ type KeywordArgumentsReturnValue struct {
179206//sample XML-RPC output: <methodResponse><params><param><value><array><data><value><string>arg1</string></value>...</data></array></value></param></params></methodResponse>
180207func (h * RobotRemoteService ) GetKeywordArguments (r * http.Request , args * KeywordInput , reply * KeywordArgumentsReturnValue ) error {
181208 //use reflection to get the arguments to keyword function and pass back to reply
182- reply .KeywordAguments = make ([]interface {}, 0 ) //if to pass back no arguments
183- //http://stackoverflow.com/questions/12990338/cannot-convert-string-to-interface
184- //else something like reply.KeywordAguments = append(reply.KeywordAguments,"two","arguments")
209+ log .Printf ("Getting arguments for %s" , args .KeywordName )
210+ method := reflect .ValueOf (offeredLibrary ).MethodByName (args .KeywordName )
211+ j := 0
212+ if args .KeywordName != "StopRemoteServer" {
213+ for i := 0 ; i < method .Type ().NumIn (); i ++ {
214+ if method .Type ().In (i ).Kind () != reflect .Ptr {
215+ methodName := method .Type ().In (i ).Name ()
216+ if len (methodName ) == 0 || methodName == method .Type ().In (i ).Kind ().String () {
217+ methodName = fmt .Sprintf ("arg%d" , j )
218+ }
219+ reply .KeywordAguments = append (reply .KeywordAguments , methodName )
220+ j ++
221+ }
222+ }
223+ }
185224 return nil
186225}
187226
0 commit comments