ffead.server.doc
ControllerHandler.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  * ControllerHandler.cpp
18  *
19  * Created on: Jun 17, 2012
20  * Author: Sumeet
21  */
22 
23 #include "ControllerHandler.h"
24 
25 ControllerHandler::ControllerHandler() {
26  // TODO Auto-generated constructor stub
27 
28 }
29 
30 ControllerHandler::~ControllerHandler() {
31  // TODO Auto-generated destructor stub
32 }
33 
34 bool ControllerHandler::handle(HttpRequest* req, HttpResponse& res, map<string, string> urlpattMap, map<string, string> mappattMap, void* dlib,
35  string ext, resFuncMap rstCntMap, map<string, string> mapMap, map<string, string> urlMap, string pthwofile)
36 {
37  Logger logger = Logger::getLogger("ControllerHandler");
38  string claz;
39  bool isContrl = false;
40  if((urlpattMap[req->getCntxt_name()+"*.*"]!="" || urlMap[req->getCntxt_name()+ext]!=""))
41  {
42  //logger << "Controller requested for " << req->getCntxt_name() << " name " << urlMap[req->getCntxt_name()+ext] << endl;
43  string controller;
44  if(urlpattMap[req->getCntxt_name()+"*.*"]!="")
45  controller = urlpattMap[req->getCntxt_name()+"*.*"];
46  else
47  controller = urlMap[req->getCntxt_name()+ext];
48  claz = "getReflectionCIFor" + controller;
49  string libName = Constants::INTER_LIB_FILE;
50  if(dlib == NULL)
51  {
52  cerr << dlerror() << endl;
53  exit(-1);
54  }
55  void *mkr = dlsym(dlib, claz.c_str());
56  if(mkr!=NULL)
57  {
58  FunPtr f = (FunPtr)mkr;
59  ClassInfo srv = f();
60  args argus;
61  Constructor ctor = srv.getConstructor(argus);
62  Reflector ref;
63  void *_temp = ref.newInstanceGVP(ctor);
64  Controller *thrd = (Controller *)_temp;
65  try{
66  logger << ("Controller " + controller + " called") << endl;
67  res = thrd->service(*req);
68  /*logger << res.getStatusCode() << endl;
69  logger << res.getContent_type() << endl;
70  logger << res.getContent_len() << endl;*/
71  if(res.getStatusCode()!="")
72  isContrl = true;
73  ext = AuthHandler::getFileExtension(req->getUrl());
74  //delete mkr;
75  }catch(...){
76  logger << "Controller Exception occurred" << endl;
77  }
78  logger << "Controller call complete" << endl;
79  }
80  }
81  else if((mappattMap[req->getCntxt_name()+"*.*"]!="" || mapMap[req->getCntxt_name()+ext]!=""))
82  {
83  string file = req->getFile();
84  string fili = file.substr(0,file.find_last_of("."));
85  if(mappattMap[req->getCntxt_name()+"*.*"]!="")
86  {
87  req->setFile(fili+mappattMap[req->getCntxt_name()+"*.*"]);
88  logger << ("URL mapped from * to " + mappattMap[req->getCntxt_name()+"*.*"]) << endl;
89  }
90  else
91  {
92  req->setFile(fili+mapMap[req->getCntxt_name()+ext]);
93  logger << ("URL mapped from " + ext + " to " + mapMap[req->getCntxt_name()+ext]) << endl;
94  }
95  }
96  else
97  {
98  resFuncMap::iterator it;
99  RestFunction rft;
100  bool flag = false;
101  int prsiz = 0;
102  vector<string> valss;
103  map<string, string> mapOfValues;
104  //logger << pthwofile << endl;
105  for (it=rstCntMap.begin();it!=rstCntMap.end();it++)
106  {
107  valss.clear();
108  //logger << it->first << endl;
109  //if(pthwofile.find(it->first)!=string::npos)
110  {
111  RestFunction ft = it->second;
112  prsiz = ft.params.size();
113  string pthwofiletemp(pthwofile);
114 
115  string baseUrl(it->first);
116  strVec resturlparts;
117  StringUtil::split(resturlparts, baseUrl, "/");
118 
119  strVec urlparts;
120  StringUtil::split(urlparts, pthwofiletemp, "/");
121 
122  if(urlparts.size()!=resturlparts.size())
123  {
124  flag = false;
125  //break;
126  }
127  else
128  {
129  flag = true;
130  }
131  if(flag)
132  {
133  bool fflag = true;
134  for (int var = 0; var < (int)resturlparts.size(); var++)
135  {
136  //logger << "resturlparts.at(var) = " << resturlparts.at(var) << endl;
137  if(resturlparts.at(var).find("{")!=string::npos && resturlparts.at(var).find("}")!=string::npos
138  && resturlparts.at(var).length()>2)
139  {
140  string paramname = resturlparts.at(var);
141  string pref, suff;
142  int st = paramname.find("{")+1;
143  pref = paramname.substr(0, st-1);
144  int len = paramname.find("}") - st;
145  suff = paramname.substr(paramname.find("}")+1);
146  paramname = paramname.substr(st, len);
147  string paramvalue = urlparts.at(var);
148  if(st>1)
149  {
150  int stpre = paramvalue.find(pref) + pref.length();
151  int len = paramvalue.length() - pref.length() - suff.length();
152  paramvalue = paramvalue.substr(stpre, len);
153  }
154  mapOfValues[paramname] = paramvalue;
155  //logger << "mapOfValues(" << paramname << ") = "<< paramvalue << endl;
156  logger << ("Restcontroller matched url : " + pthwofiletemp + ",param size: " + CastUtil::lexical_cast<string>(prsiz) +
157  ", against url: " + baseUrl) << endl;
158  }
159  else if(urlparts.at(var)!=resturlparts.at(var))
160  {
161  fflag = false;
162  break;
163  }
164  }
165  flag = fflag;
166  }
167 
168  string lhs = StringUtil::toUpperCopy(ft.meth);
169  string rhs = StringUtil::toUpperCopy(req->getMethod());
170  //if(prsiz==(int)valss.size() && lhs==rhs)
171  if(flag && lhs==rhs)
172  {
173 
174  logger << "Encountered rest controller url/method match" << endl;
175  rft = ft;
176  flag = true;
177  break;
178  }
179  else if(flag)
180  {
181  res.setHTTPResponseStatus(HTTPResponseStatus::InvalidMethod);
182  return true;
183  }
184  else
185  {
186  res.setHTTPResponseStatus(HTTPResponseStatus::NotFound);
187  //res.setContent_type(ContentTypes::CONTENT_TYPE_TEXT_PLAIN);
188  /*if(prsiz==valss.size())
189  res.setContent_str("Invalid number of arguments");
190  else
191  res.setContent_str("Invalid HTTPMethod used");*/
192  //logger << "Rest Controller Param/Method Error" << endl;
193  }
194  }
195  }
196  if(flag)
197  {
198  //logger << "inside restcontroller logic ..." << endl;
199  string libName = Constants::INTER_LIB_FILE;
200  if(dlib == NULL)
201  {
202  cerr << dlerror() << endl;
203  exit(-1);
204  }
205  string clasnam("getReflectionCIFor"+rft.clas);
206  void *mkr = dlsym(dlib, clasnam.c_str());
207  logger << mkr << endl;
208  if(mkr!=NULL)
209  {
210  FunPtr f = (FunPtr)mkr;
211  ClassInfo srv = f();
212  args argus;
213  Constructor ctor = srv.getConstructor(argus);
214  Reflector ref;
215  void *_temp = ref.newInstanceGVP(ctor);
216  RestController* rstcnt = (RestController*)_temp;
217  rstcnt->request = req;
218  rstcnt->response = &res;
219 
220  vals valus;
221  bool invValue = false;
222  for (int var = 0; var < prsiz; var++)
223  {
224  try
225  {
226  string icont = rft.icontentType;
227  string ocont = rft.ocontentType;
228 
229  if(icont=="")
230  icont = ContentTypes::CONTENT_TYPE_APPLICATION_JSON;
231  else if(icont!=req->getContent_type())
232  {
233  res.setHTTPResponseStatus(HTTPResponseStatus::UnsupportedMedia);
234  return true;
235  }
236 
237  if(ocont=="")
238  ocont = ContentTypes::CONTENT_TYPE_APPLICATION_JSON;
239 
240  req->setContent_type(icont);
241  res.setContent_type(ocont);
242 
243  string pmvalue;
244  if(rft.params.at(var).from=="path")
245  pmvalue = mapOfValues[rft.params.at(var).name];
246  else if(rft.params.at(var).from=="reqparam")
247  pmvalue = req->getQueryParam(rft.params.at(var).name);
248  else if(rft.params.at(var).from=="postparam")
249  pmvalue = req->getRequestParam(rft.params.at(var).name);
250  else if(rft.params.at(var).from=="header")
251  pmvalue = req->getXtraHeader(rft.params.at(var).name);
252  else
253  pmvalue = req->getContent();
254 
255  logger << ("Restcontroller parameter type/value = " + rft.params.at(var).type + "/" + pmvalue) << endl;
256  logger << ("Restcontroller content types input/output = " + icont + "/" + ocont) << endl;
257 
258  if(rft.params.at(var).type=="int")
259  {
260  argus.push_back(rft.params.at(var).type);
261  int* ival = new int(CastUtil::lexical_cast<int>(pmvalue));
262  valus.push_back(ival);
263  }
264  else if(rft.params.at(var).type=="short")
265  {
266  argus.push_back(rft.params.at(var).type);
267  short* ival = new short(CastUtil::lexical_cast<short>(pmvalue));
268  valus.push_back(ival);
269  }
270  else if(rft.params.at(var).type=="long")
271  {
272  argus.push_back(rft.params.at(var).type);
273  long* ival = new long(CastUtil::lexical_cast<long>(pmvalue));
274  valus.push_back(ival);
275  }
276  else if(rft.params.at(var).type=="double")
277  {
278  argus.push_back(rft.params.at(var).type);
279  double* ival = new double(CastUtil::lexical_cast<double>(pmvalue));
280  valus.push_back(ival);
281  }
282  else if(rft.params.at(var).type=="float")
283  {
284  argus.push_back(rft.params.at(var).type);
285  float* ival = new float(CastUtil::lexical_cast<float>(pmvalue));
286  valus.push_back(ival);
287  }
288  else if(rft.params.at(var).type=="bool")
289  {
290  argus.push_back(rft.params.at(var).type);
291  bool* ival = new bool(CastUtil::lexical_cast<bool>(pmvalue));
292  valus.push_back(ival);
293  }
294  else if(rft.params.at(var).type=="string" || rft.params.at(var).type=="std::string")
295  {
296  argus.push_back(rft.params.at(var).type);
297  string* sval = new string(pmvalue);
298  valus.push_back(sval);
299  }
300  else if(rft.params.at(var).type.find("vector&lt;")==0)
301  {
302  string stlcnt = rft.params.at(var).type;
303  StringUtil::replaceFirst(stlcnt,"vector&lt;","");
304  StringUtil::replaceFirst(stlcnt,"&gt;","");
305  StringUtil::replaceFirst(stlcnt," ","");
306  logger << ("Restcontroller param body holds vector of type " + stlcnt) << endl;
307  string typp = "vector<" + stlcnt + ">";
308  argus.push_back(typp);
309  void* voidPvect = NULL;
310  if(icont==ContentTypes::CONTENT_TYPE_APPLICATION_JSON)
311  {
312  voidPvect = JSONSerialize::unSerializeUnknown(pmvalue, "std::vector<"+stlcnt+">");
313  }
314  else
315  {
316  voidPvect = XMLSerialize::unSerializeUnknown(pmvalue, "std::vector<"+stlcnt+",");
317  }
318  if(voidPvect==NULL)
319  {
320  res.setHTTPResponseStatus(HTTPResponseStatus::BadRequest);
321  return true;
322  }
323  valus.push_back(voidPvect);
324  }
325  else
326  {
327  argus.push_back(rft.params.at(var).type);
328  void* voidPvect = NULL;
329  if(icont==ContentTypes::CONTENT_TYPE_APPLICATION_JSON)
330  {
331  voidPvect = JSONSerialize::unSerializeUnknown(pmvalue, rft.params.at(var).type);
332  }
333  else
334  {
335  voidPvect = XMLSerialize::unSerializeUnknown(pmvalue, rft.params.at(var).type);
336  }
337  if(voidPvect==NULL)
338  {
339  res.setHTTPResponseStatus(HTTPResponseStatus::BadRequest);
340  return true;
341  }
342  valus.push_back(voidPvect);
343  }
344  } catch (const char* ex) {
345  logger << "Restcontroller exception occurred" << endl;
346  logger << ex << endl;
347  invValue= true;
348  res.setHTTPResponseStatus(HTTPResponseStatus::BadRequest);
349  return true;
350  } catch (...) {
351  logger << "Restcontroller exception occurred" << endl;
352  invValue= true;
353  res.setHTTPResponseStatus(HTTPResponseStatus::BadRequest);
354  return true;
355  }
356  }
357 
358  Method meth = srv.getMethod(rft.name, argus);
359  if(meth.getMethodName()!="" && !invValue)
360  {
361  ref.invokeMethodUnknownReturn(_temp,meth,valus);
362  logger << "Successfully called restcontroller" << endl;
363  //return;
364  }
365  else
366  {
367  res.setHTTPResponseStatus(HTTPResponseStatus::NotFound);
368  //res.setContent_type(ContentTypes::CONTENT_TYPE_TEXT_PLAIN);
369  /*if(invValue)
370  res.setContent_str("Invalid value passed as URL param");
371  else
372  res.setContent_str("Rest Controller Method Not Found");*/
373  logger << "Rest Controller Method Not Found" << endl;
374  //return;
375  }
376  }
377  }
378  }
379  return isContrl;
380 }