ffead.server.doc
WsUtil.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  * WsUtil.cpp
18  *
19  * Created on: Sep 21, 2009
20  * Author: sumeet
21  */
22 
23 #include "WsUtil.h"
24 
25 WsUtil::WsUtil() {
26  logger = Logger::getLogger("WsUtil");
27 }
28 
29 WsUtil::~WsUtil() {
30  // TODO Auto-generated destructor stub
31 }
32 
33 string WsUtil::generateAllWSDL(vector<string> files,string resp,map<string,string> &wsmap)
34 {
35  string ret,headers="#include \"Exception.h\"\n#include \"string\"\n#include <sstream>\n#include \"CastUtil.h\"\n#include \"Element.h\"\ntypedef vector<Element> ElementList;\ntypedef map<string,string> AttributeList;\n";
36  for(unsigned int var = 0; var < files.size(); ++var)
37  {
38  string webdir = resp+"../web/"+files.at(var);
39  ret += generateWSDL(webdir+"/config/ws.xml",webdir+"/include/",resp,headers,wsmap,files.at(var));
40  }
41  ret = (headers + "using namespace std;\n\n" + ret);
42  return ret;
43 }
44 
45 string WsUtil::generateWSDL(string file,string usrinc,string resp,string &headers,map<string,string> &wsmap,string appname)
46 {
47  XmlParser parser("Parser");
48  Document doc = parser.getDocument(file);
49  Element root = doc.getRootElement();
50  typedef vector<Element> ElementList;
51  typedef map<string,string> strMap;
52  typedef map<string,strMap> meth_Map;
53  typedef map<string,meth_Map> ws_inp_out_Map;
54  ElementList wsvcs = root.getChildElements();
55  if(wsvcs.size()==0)
56  return "";
57  Reflection ref;
58  TemplateEngine templ;
59  ws_inp_out_Map ws_info;
60  string ws_funcs,obj_mapng,retObj_xml;
61  for(unsigned int i=0;i<wsvcs.size();i++)
62  {
63  meth_Map meth_info;
64  StringContext gcntxt;
65  string ws_name,reqr_res_bind,wsdl_msgs,wsdl_ops,wsdl_bind,wsdl,wsdl_obj_bind;
66  Element ws = wsvcs.at(i);
67  ws_name = ws.getAttribute("class");
68  gcntxt["WS_NAME"] = ws_name;
69  wsmap[ws_name] = appname;
70  logger << ("Web service " + ws_name + " found for appname " + appname) << endl;
71  strVec info = ref.getAfcObjectData(usrinc+ws.getAttribute("class")+".h", false);
72  headers.append("#include \""+ws.getAttribute("class")+".h\"\n");
73 
74  for(unsigned int i=0;i<info.size();i++)
75  {
76  string temp,temp11;
77  strMap in_out_info;
78  temp = info.at(i);
79  temp11 = temp.substr(temp.find("(")+1);
80  temp = temp.substr(0,temp.find("("));
81 
82  //StringUtil::replaceFirst(temp,"("," ");
83  StringUtil::replaceAll(temp11,";","");
84  StringUtil::replaceFirst(temp11,")"," ");
85  strVec results,results1;
86  StringUtil::split(results, temp, (" "));
87  StringUtil::split(results1, temp11, (","));
88  string retType,methName,inp_params;
89  if(results.size()<2)
90  continue;
91  if(results.size()>0 && (results.at(0)==ws.getAttribute("class") || temp.find("~")!=string::npos))
92  continue;
93 
94  methName = results.at(1);
95 
96  in_out_info["RETURN"] = ws.getElementByName(methName).getAttribute("outname");
97  //logger << in_out_info["RETURN"] << flush;
98  in_out_info["RETURNTYP"] = results.at(0);
99  if(results.at(0).find("vector<")!=string::npos)
100  {
101  string vecn = results.at(0);
102  StringUtil::replaceFirst(vecn,"vector<"," ");
103  StringUtil::replaceFirst(vecn,">"," ");
104  StringUtil::trim(vecn);
105  if(vecn=="int" || vecn=="double" || vecn=="float" || vecn=="string")
106  {
107  retType = "\n<xsd:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\""+in_out_info["RETURN"]+"\" type=\"xsd:"+vecn+"\"/>";
108  }
109  else
110  {
111  results1.push_back(vecn);
112  retType = "\n<xsd:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\""+in_out_info["RETURN"]+"\" type=\"ns0:"+vecn+"\"/>";
113  }
114  }
115  else
116  {
117  if(results.at(0)!="void")
118  {
119  if(results.at(0)=="int" || results.at(0)=="double" || results.at(0)=="float" || results.at(0)=="string")
120  retType = "\n<xsd:element name=\""+in_out_info["RETURN"]+"\" type=\"xsd:"+results.at(0)+"\"/>";
121  else
122  retType = "\n<xsd:element name=\""+in_out_info["RETURN"]+"\" type=\"ns0:"+results.at(0)+"\"/>";
123  }
124  }
125  for(unsigned int j=0;j<results1.size();j++)
126  {
127  string type;
128  strVec results2;
129  StringUtil::split(results2, results1.at(j), (" "));
130  if(results2.size()<2)continue;
131  type = results2.at(0);
132  int srn = j;
133  char chr = CastUtil::lexical_cast<char>(j);
134  stringstream ss;
135  ss << srn;
136  string te;
137  ss >> te;
138  if(type=="int" || type=="float" || type=="double")
139  {
140  inp_params.append("\n<xsd:element name=\""+results2.at(1)+"\" type=\"xsd:"+type+"\"/>");
141  in_out_info[chr+results2.at(1)] = type;
142  }
143  else if(type=="string")
144  {
145  inp_params.append("\n<xsd:element minOccurs=\"0\" name=\""+results2.at(1)+"\" type=\"xsd:string\"/>");
146  in_out_info[chr+results2.at(1)] = type;
147  }
148  else if(type!="")
149  {
150  if(results2.size()>=2)
151  in_out_info[chr+results2.at(1)] = type;
152  else
153  logger << ("Invalid thing happening " + results1.at(j)) << endl;
154  strMap allfs,tyfs;
155  if(type.find("vector<")!=string::npos && results2.size()==2)
156  {
157  string vecn = type;
158  StringUtil::replaceFirst(vecn,"vector<"," ");
159  StringUtil::replaceFirst(vecn,">"," ");
160  StringUtil::trim(vecn);
161  headers.append("#include \""+vecn+".h\"\n");
162  type = vecn;
163  inp_params.append("\n<xsd:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\""+results2.at(1)+"\" type=\"ns0:"+type+"\"/>");
164  }
165  else if(results2.size()==2)
166  {
167  headers.append("#include \""+type+".h\"\n");
168  inp_params.append("\n<xsd:element minOccurs=\"0\" name=\""+results2.at(1)+"\" type=\"ns0:"+type+"\"/>");
169  }
170  strVec onjinf = ref.getAfcObjectData(usrinc+type+".h", false);
171  if(type=="int" || type=="float" || type=="double" || type=="string")
172  continue;
173  obj_mapng.append(type+" _getObj"+type+"(Element ele)\n{\n");
174  obj_mapng.append(type+" _obj;\n");
175  retObj_xml.append("string _getRetXmlFor"+type+"("+type+" _obj,string namespce)\n{\n");
176  for(unsigned int k=0;k<onjinf.size();k++)
177  {
178  string temp1,field,type;
179  temp1 = onjinf.at(k);
180  if(temp1.find(",")!=string::npos)
181  continue;
182  size_t s = temp1.find("get");
183  size_t s1 = temp1.find("set");
184  if(s!=string::npos)
185  {
186  size_t e = temp1.find("(");
187  field = temp1.substr(s+3,e-s+3);
188  field = AfcUtil::reverseCamelCased(field);
189  field = field.substr(0,field.find("("));
190  //logger << "\nField--- " << field << flush;
191  allfs[field] = "";
192  }
193  else if(s1!=string::npos)
194  {
195  size_t e = temp1.find("(");
196  size_t ed = temp1.find(")");
197  field = temp1.substr(s1+3,e-s1+3);
198  field = AfcUtil::reverseCamelCased(field);
199  field = field.substr(0,field.find("("));
200  type = temp1.substr(e+1,ed-e-1);
201  strVec results3;
202  StringUtil::split(results3, type, (" "));
203  type = results3.at(0);
204  //logger << "\nField--- " << field << flush;
205  //logger << "\nType--- " << type << flush;
206  allfs[field] = field;
207  tyfs[field] = type;
208  }
209  }
210  strMap::iterator iter;
211  bool flag = false;
212  string obj_binding;
213  retObj_xml.append("string _ret;\n");
214  retObj_xml.append("string val;\n");
215  retObj_xml.append("stringstream ss;\n");
216  for(iter=allfs.begin();iter!=allfs.end();iter++)
217  {
218  if(iter->second!="")
219  {
220  flag = true;
221  string typ;
222  typ = tyfs[iter->second];
223  if(typ=="int" || typ=="float" || typ=="double")
224  {
225  retObj_xml.append("ss << _obj.get"+AfcUtil::camelCased(iter->second)+"();\n");
226  retObj_xml.append("ss >> val;\n");
227  obj_binding.append("\n<xsd:element name=\""+iter->second+"\" type=\"xsd:"+typ+"\"/>");
228  }
229  else if(typ=="string")
230  {
231  retObj_xml.append("val = _obj.get"+AfcUtil::camelCased(iter->second)+"();\n");
232  obj_binding.append("\n<xsd:element minOccurs=\"0\" name=\""+iter->second+"\" type=\"xsd:string\"/>");
233  }
234  obj_mapng.append("_obj.set"+AfcUtil::camelCased(iter->second)+"(CastUtil::lexical_cast<"+typ+">(ele.getElementByName(\""+iter->second+"\").getText()));\n");
235  retObj_xml.append("_ret.append(\"<\"+namespce+\":"+iter->second+">\"+val+\"</\"+namespce+\":"+iter->second+">\");\n");
236  }
237  }
238  obj_mapng.append("return _obj;\n}\n");
239  retObj_xml.append("return _ret;\n}\n");
240  if(flag)
241  {
242  StringContext cntxt1;
243  cntxt1["OBJ"] = type;
244  cntxt1["OBJ_MEMBERS"] = obj_binding;
245  wsdl_obj_bind.append(templ.evaluate(resp+"templateObjBin.wsdl",cntxt1));
246  }
247  }
248  }
249  meth_info[methName] = in_out_info;
250  StringContext cntxt;
251  cntxt["METH_NAME"] = methName;
252  cntxt["RET_TYPE"] = retType;
253  cntxt["INP_PARAMS"] = inp_params;
254  reqr_res_bind.append("\n"+templ.evaluate(resp+"templateReqRes.wsdl",cntxt));
255  wsdl_msgs.append("\n"+templ.evaluate(resp+"templateWsdlMsg.wsdl",cntxt));
256  wsdl_ops.append("\n"+templ.evaluate(resp+"templateWsdlOpe.wsdl",cntxt));
257  wsdl_bind.append("\n"+templ.evaluate(resp+"templateWsdlBind.wsdl",cntxt));
258  }
259  ws_info[ws_name] = meth_info;
260  gcntxt["REQ_RES_BINDING"] = reqr_res_bind;
261  gcntxt["WSDL_MESSAGES"] = wsdl_msgs;
262  gcntxt["WSDL_OPERATIONS"] = wsdl_ops;
263  gcntxt["WSDL_BINDING"] = wsdl_bind;
264  gcntxt["OBJ_BINDING"] = wsdl_obj_bind;
265  gcntxt["URL"] = "http://localhost:8080";
266  wsdl = templ.evaluate(resp+"template.wsdl",gcntxt);
267  AfcUtil::writeTofile(resp+ws_name+".wsdl",wsdl,true);
268  ws_funcs.append(obj_mapng);
269  ws_funcs.append(retObj_xml);
270  ws_funcs.append("extern \"C\"\n{\n");
271  ws_inp_out_Map::iterator iter;
272  for(iter=ws_info.begin();iter!=ws_info.end();iter++)
273  {
274  string ws_n = iter->first;
275  meth_Map meth = iter->second;
276  meth_Map::iterator iter1;
277  for(iter1=meth.begin();iter1!=meth.end();iter1++)
278  {
279  string me_n = iter1->first;
280  strMap pars = iter1->second;
281  ws_funcs.append("string "+me_n+ws_n+"(Element _req)\n{\nElement ele;\n");
282  ws_funcs.append("string _retStr;\n");
283  ws_funcs.append("try{\n");
284  strMap::iterator iter2;
285  string args;
286  unsigned int ter = 1;
287  //logger << me_n << ws_n << pars.size() << endl;
288  for(iter2=pars.begin();iter2!=pars.end();iter2++)
289  {
290  if(iter2->first!="RETURN" && iter2->first!="RETURNTYP")
291  {
292  string argname = iter2->first.substr(1);
293  if(iter2->second=="int" || iter2->second=="double" || iter2->second=="float" || iter2->second=="string")
294  {
295  ws_funcs.append("ele = _req.getElementByName(\""+argname+"\");\n");
296  ws_funcs.append(iter2->second+" "+argname+";\n");
297  ws_funcs.append("if(ele.getTagName()!=\"\")");
298  ws_funcs.append(argname+" = CastUtil::lexical_cast<"+iter2->second+">(ele.getText());\n");
299  }
300  else if(iter2->second.find("vector<")!=string::npos)
301  {
302  string vecn = iter2->second;
303  StringUtil::replaceFirst(vecn,"vector<"," ");
304  StringUtil::replaceFirst(vecn,">"," ");
305  StringUtil::trim(vecn);
306  if(vecn=="int" || vecn=="double" || vecn=="float" || vecn=="string")
307  {
308  ws_funcs.append("vector<"+vecn+"> "+argname+";\n");
309  ws_funcs.append("ElementList list = _req.getElementsByName(\""+argname+"\");\n");
310  ws_funcs.append("for(int i=0;i<list.size();i++)");
311  ws_funcs.append(argname+".push_back(CastUtil::lexical_cast<"+vecn+">(list.at(i).getText()));\n");
312  }
313  else
314  {
315  ws_funcs.append("vector<"+vecn+"> "+argname+";\n");
316  ws_funcs.append("ElementList list = _req.getElementsByName(\""+argname+"\");\n");
317  ws_funcs.append("for(int i=0;i<list.size();i++)");
318  ws_funcs.append(argname+".push_back(_getObjTest(list.at(i)));\n");
319  }
320  }
321  else
322  {
323  ws_funcs.append("ele = _req.getElementByName(\""+argname+"\");\n");
324  ws_funcs.append(iter2->second+" "+argname+";\n");
325  ws_funcs.append("if(ele.getTagName()!=\"\")");
326  ws_funcs.append(argname+" = _getObj"+iter2->second+"(ele);\n");
327  }
328  args.append(argname);
329  if(ter++<pars.size()-2)
330  args.append(",");
331  }
332  }
333  ws_funcs.append(ws_n+" _obj;\n");
334 
335  ws_funcs.append("AttributeList attl = _req.getAttributes();\n");
336  ws_funcs.append("AttributeList::iterator it;\n");
337  ws_funcs.append("_retStr = \"<\" + _req.getTagNameSpc() + \"Response\";\n");
338  ws_funcs.append("for(it=attl.begin();it!=attl.end();it++)\n");
339  ws_funcs.append("_retStr.append(\" \" + it->first + \"=\\\"\" + it->second + \"\\\" \");\n");
340  ws_funcs.append("_retStr.append(\">\");\n");
341  if(pars["RETURNTYP"]=="void")
342  {
343  ws_funcs.append("_obj."+me_n+"("+args+");\n");
344  }
345  else if(pars["RETURNTYP"]=="int" || pars["RETURNTYP"]=="double" || pars["RETURNTYP"]=="float" || pars["RETURNTYP"]=="string")
346  {
347  ws_funcs.append(pars["RETURNTYP"]+" _retval;\n");
348  ws_funcs.append("_retval = _obj."+me_n+"("+args+");\n");
349  ws_funcs.append("_retStr += \"<\" + _req.getNameSpc() +\":"+pars["RETURN"]+">\"+_retval+\"</\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\";\n");
350  }
351  else if(pars["RETURNTYP"]!="")
352  {
353  ws_funcs.append(pars["RETURNTYP"]+" _retval;\n");
354  ws_funcs.append("_retval = _obj."+me_n+"("+args+");\n");
355  if(pars["RETURNTYP"].find("vector<")!=string::npos)
356  {
357  string vecn = pars["RETURNTYP"];
358  StringUtil::replaceFirst(vecn,"vector<"," ");
359  StringUtil::replaceFirst(vecn,">"," ");
360  StringUtil::trim(vecn);
361  if(vecn=="int" || vecn=="double" || vecn=="float" || vecn=="string")
362  {
363  ws_funcs.append("for(int i=0;i<_retval.size();i++)");
364  ws_funcs.append("_retStr += \"<\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\"+CastUtil::lexical_cast<string>(_retval.at(i))+\"</\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\";\n");
365  }
366  else
367  {
368  ws_funcs.append("for(int i=0;i<_retval.size();i++)");
369  ws_funcs.append("_retStr += \"<\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\"+_getRetXmlFor"+vecn+"(_retval.at(i),_req.getNameSpc())+\"</\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\";\n");
370  }
371  }
372  else
373  ws_funcs.append("_retStr += \"<\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\"+_getRetXmlFor"+pars["RETURNTYP"]+"(_retval,_req.getNameSpc())+\"</\" + _req.getNameSpc() + \":"+pars["RETURN"]+">\";\n");
374  }
375  ws_funcs.append("_retStr += \"</\" + _req.getTagNameSpc() + \"Response>\";\n");
376  ws_funcs.append("}catch(Exception e){\n");
377  ws_funcs.append("return e.getMessage();\n}\n");
378  ws_funcs.append("catch(...){\n");
379  ws_funcs.append("return \"<soap:Fault><faultcode>soap:Server</faultcode><faultstring>Exception occurred</faultstring></soap:Fault>\";\n}\n");
380  ws_funcs.append("return _retStr;\n}\n");
381  }
382  ws_funcs.append("}\n");
383  }
384  //AfcUtil::writeTofile(rtdcfp+"WsInterface.cpp",ws_funcs,true);
385  }
386  return ws_funcs;
387 }