ffead.server.doc
MethodInvoc.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*
17  * MethodInvoc.cpp
18  *
19  * Created on: Jan 30, 2010
20  * Author: sumeet
21  */
22 
23 #include "MethodInvoc.h"
24 
25 MethodInvoc::MethodInvoc() {
26  // TODO Auto-generated constructor stub
27 
28 }
29 
30 MethodInvoc::~MethodInvoc() {
31  // TODO Auto-generated destructor stub
32 }
33 MethodInvoc* _methinv_instance = NULL;
34 
35 void MethodInvoc::init()
36 {
37  if(_methinv_instance==NULL)
38  {
39  _methinv_instance = new MethodInvoc();
40  _methinv_instance->running = false;
41  }
42 }
43 void* MethodInvoc::service(void* arg)
44 {
45  int fd = *(int*)arg;
46  init();
47  string methInfo,retValue;
48  _methinv_instance->getServer().Receive(fd,methInfo,1024);
49  methInfo =methInfo.substr(0,methInfo.find_last_of(">")+1);
50  try
51  {
52  XmlParser parser("Parser");
53  if(methInfo.find("lang=\"c++\"")!=string::npos || methInfo.find("lang='c++'")!=string::npos)
54  {
55  Document doc = parser.getDocument(methInfo);
56  Element message = doc.getRootElement();
57  if(message.getTagName()!="method")
58  {
59  throw new MethodInvokerException("No method Tag\n",retValue);
60  }
61  if(message.getAttributes().size()<3)
62  {
63  throw new MethodInvokerException("name,class and lang are mandatory attributes\n",retValue);
64  }
65  else if(message.getAttribute("name")=="")
66  {
67  throw new MethodInvokerException("name attribute missing\n",retValue);
68  }
69  else if(message.getAttribute("className")=="")
70  {
71  throw new MethodInvokerException("class attribute missing\n",retValue);
72  }
73  else if(message.getAttribute("lang")=="")
74  {
75  throw new MethodInvokerException("lang attribute missing\n",retValue);
76  }
77  if(message.getChildElements().size()!=1)
78  {
79  throw new MethodInvokerException("message tag should have only one child tag\n",retValue);
80  }
81  else if(message.getChildElements().at(0).getTagName()!="args")
82  {
83  throw new MethodInvokerException("message tag should have an args child tag\n",retValue);
84  }
85  Serialize ser;
86  Reflector reflector;
87  args argus;
88  vals valus;
89  ElementList argts = message.getChildElements().at(0).getChildElements();
90  for (unsigned var = 0; var < argts.size(); var++)
91  {
92  void *value = NULL;
93  Element arg = argts.at(var);
94  if(arg.getTagName()!="argument" || arg.getAttribute("type")=="")
95  throw new MethodInvokerException("every argument tag should have a name and type attribute\n",retValue);
96  if(arg.getText()=="" && arg.getChildElements().size()==0)
97  throw new MethodInvokerException("argument value missing\n",retValue);
98  if(arg.getAttribute("type")=="int")
99  {
100  int *vt = new int;
101  *vt = CastUtil::lexical_cast<int>(arg.getText());
102  value = vt;
103  }
104  else if(arg.getAttribute("type")=="float")
105  {
106  float *vt = new float;
107  *vt = CastUtil::lexical_cast<float>(arg.getText());
108  value = vt;
109  }
110  else if(arg.getAttribute("type")=="double")
111  {
112  double *vt = new double;
113  *vt = CastUtil::lexical_cast<double>(arg.getText());
114  value = vt;
115  }
116  else if(arg.getAttribute("type")=="string")
117  {
118  string *vt = new string;
119  *vt = CastUtil::lexical_cast<string>(arg.getText());
120  value = vt;
121  }
122  else if(arg.getAttribute("type")!="")
123  {
124  Element obj = arg.getChildElements().at(0);
125  string objxml = obj.render();
126  string objClassName = obj.getTagName();
127  value = ser.unSerializeUnknown(objxml,arg.getAttribute("type"));
128  }
129  argus.push_back(arg.getAttribute("type"));
130  valus.push_back(value);
131  }
132  string className = message.getAttribute("className");
133  string returnType = message.getAttribute("returnType");
134  string lang = message.getAttribute("lang");
135  ClassInfo clas = reflector.getClassInfo(className);
136  string methodName = message.getAttribute("name");;
137  if(clas.getClassName()=="")
138  {
139  throw new MethodInvokerException("class does not exist or is not in the library path\n",retValue);
140  }
141  Method meth = clas.getMethod(methodName,argus);
142  if(meth.getMethodName()=="")
143  {
144  throw new MethodInvokerException("method does not exist for the class or the class does not exist in the library path\n",retValue);
145  }
146  else
147  {
148  args argus;
149  Constructor ctor = clas.getConstructor(argus);
150  void *_temp = reflector.newInstanceGVP(ctor);
151  if(returnType=="void" || returnType=="")
152  {
153  reflector.invokeMethod<void*>(_temp,meth,valus);
154  retValue = ("<return:void></return:void>");
155  }
156  else
157  {
158  if(returnType=="int")
159  {
160  int retv = reflector.invokeMethod<int>(_temp,meth,valus);
161  retValue = ("<return:int>"+CastUtil::lexical_cast<string>(retv)+"</return:int>");
162  }
163  else if(returnType=="float")
164  {
165  float retv = reflector.invokeMethod<float>(_temp,meth,valus);
166  retValue = ("<return:float>"+CastUtil::lexical_cast<string>(retv)+"</return:float>");
167  }
168  else if(returnType=="double")
169  {
170  double retv = reflector.invokeMethod<double>(_temp,meth,valus);
171  retValue = ("<return:double>"+CastUtil::lexical_cast<string>(retv)+"</return:double>");
172  }
173  else if(returnType=="string")
174  {
175  string retv = reflector.invokeMethod<string>(_temp,meth,valus);
176  retValue = ("<return:string>"+retv+"</return:string>");
177  }
178  else if(returnType!="")
179  {
180  void* retobj = reflector.invokeMethodUnknownReturn(_temp,meth,valus);
181  string oxml = ser.serializeUnknown(retobj,returnType);
182  retValue = ("<return:"+returnType+">"+oxml+"</return:"+returnType+">");
183  }
184  }
185 
186  }
187  }
188  else
189  {
190  retValue = "<return:exception>This is a C++ daemon</return:exception>";
191  }
192  if(retValue!="")
193  _methinv_instance->getServer().Send(fd,retValue);
194  close(fd);
195  }
196  catch(MethodInvokerException *e)
197  {
198  _methinv_instance->getServer().Send(fd,retValue);
199  close(fd);
200  }
201  catch(...)
202  {
203  retValue = ("<return:exception>XmlParseException occurred</return:exception>");
204  _methinv_instance->getServer().Send(fd,retValue);
205  close(fd);
206  }
207  return NULL;
208 }
209 
210 
211 void MethodInvoc::trigger(string port)
212 {
213  init();
214  if(_methinv_instance->running)
215  return;
216  Server serv(port,false,500,&service,2);
217  _methinv_instance->server = serv;
218  _methinv_instance->running = true;
219  return;
220 }
221 
222 void MethodInvoc::stop()
223 {
224  _methinv_instance->server.stop();
225 }