From bb3fad646f94739a876869464a484c99795bce61 Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Tue, 3 Jun 2008 08:13:20 +0000
Subject: Added support for lua validator programs.

---
 server/src/luaquerymapper.cc  |  1 -
 server/src/queryhandler.cc    |  4 ++--
 server/src/queryparser.cc     |  5 +++++
 server/src/server.cc          | 20 ++++++++++++++++++++
 server/src/template.h         |  6 ++++++
 server/src/templateparser.cc  | 38 ++++++++++++++++++++++++++++++++++++--
 server/src/templateparser.h   |  5 ++++-
 server/src/widgetgenerator.cc |  2 +-
 server/xml/example2.xml       | 16 +++++++++++-----
 9 files changed, 85 insertions(+), 12 deletions(-)

diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc
index c99b48b..b698fe9 100644
--- a/server/src/luaquerymapper.cc
+++ b/server/src/luaquerymapper.cc
@@ -60,7 +60,6 @@ LUAQueryMapper::LUAQueryMapper(QueryResult &res)
 
   luaL_openlibs(L);
 
-  // FIXME: Insert these variables directly into the LUA stack instead of parsing them.
   std::string preload = loadresultstring(res);
 
   int s = luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload");
diff --git a/server/src/queryhandler.cc b/server/src/queryhandler.cc
index 309c014..cd96b03 100644
--- a/server/src/queryhandler.cc
+++ b/server/src/queryhandler.cc
@@ -176,8 +176,8 @@ std::string QueryHandler::exec()
             "                    device_type=\"%s\"\n"
             "                    filter=\"latest\"\n"
             "                    location=\"all\"/>\n",
-            query.attributes["device_id"].c_str(),
-            query.attributes["device_type"].c_str());
+            query.attributes["class"].c_str(),
+            query.attributes["class"].c_str());
 
     socket->write(buf, strlen(buf));
 
diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc
index fc64c76..0135515 100644
--- a/server/src/queryparser.cc
+++ b/server/src/queryparser.cc
@@ -47,6 +47,11 @@ void QueryParser::startTag(std::string name, std::map< std::string, std::string>
 
   if(name == "result") {
     this->timestamp = atol(attributes["timestamp"].c_str());
+
+    QueryResult q;
+    q.timestamp = this->timestamp;
+    stack.back()->groups[attributes["class"]] = q;
+    stack.push_back(&stack.back()->groups[attributes["class"]]);
   }
 
   if(name == "group") {
diff --git a/server/src/server.cc b/server/src/server.cc
index e85c35c..f74c2b0 100644
--- a/server/src/server.cc
+++ b/server/src/server.cc
@@ -150,6 +150,26 @@ static void connection(TCPSocket &socket)
       socket.write("\">\n");
 
       if(macro.attributes["name"] == request.macro) {
+        // Handle lua programs
+        if(macro.luaprograms.size()) {
+          socket.write("      <luaprograms>\n");
+
+          std::vector< LUAProgram >::iterator lpi = macro.luaprograms.begin();
+          while(lpi != macro.luaprograms.end()) {
+            socket.write("        <luaprogram name=\"");
+            socket.write(lpi->attributes["name"]);
+            socket.write("\">\n");
+            
+            socket.write(lpi->attributes["lua"]);
+
+            socket.write("\n        </luaprogram>\n");
+
+            lpi++;
+          }
+
+          socket.write("      </luaprograms>\n");
+        }
+        
         widgetgenerator(socket, macro, lqm, db);
       }
 
diff --git a/server/src/template.h b/server/src/template.h
index 954aa76..f19746a 100644
--- a/server/src/template.h
+++ b/server/src/template.h
@@ -36,6 +36,11 @@ public:
   std::map< std::string, std::string > attributes;
 };
 
+class LUAProgram {
+public:
+  std::map< std::string, std::string > attributes;
+};
+
 class Map {
 public:
   std::map< std::string, std::string > attributes;
@@ -50,6 +55,7 @@ class Macro {
 public:
   std::vector< Query > queries;
   std::vector< Map > maps;
+  std::vector< LUAProgram > luaprograms;
   Widget window;
   std::map< std::string, std::string > attributes;
 };
diff --git a/server/src/templateparser.cc b/server/src/templateparser.cc
index d35811a..04650ca 100644
--- a/server/src/templateparser.cc
+++ b/server/src/templateparser.cc
@@ -65,6 +65,7 @@ TemplateParser::TemplateParser(std::string course)
   t = NULL;
   current_macro = NULL;
   current_map = NULL;
+  current_luaprogram = NULL;
 
   file = XML"/";
   file.append(course);
@@ -85,11 +86,14 @@ TemplateParser::~TemplateParser()
 void TemplateParser::characterData(std::string &data)
 {
   if(state == MAP) {
-    //    assert(current_macro->maps.size()); // No maps present!
-    //    current_macro->maps.back().attributes["lua"].append(data);
     assert(current_map); // No map present!
     current_map->attributes["lua"].append(data);
   }
+
+  if(state == LUAPROGRAM) {
+    assert(current_luaprogram); // No lua program present!
+    current_luaprogram->attributes["lua"].append(data);
+  }
 }
 
 void TemplateParser::startTag(std::string name, std::map< std::string, std::string> attributes)
@@ -183,6 +187,31 @@ void TemplateParser::startTag(std::string name, std::map< std::string, std::stri
     return;
   }
 
+  // Enable LUA Program parsing
+  if(name == "luaprograms") {
+    if(state != MACRO) error("luaprograms found outside macro.");
+    state = LUAPROGRAMS;
+
+    assert(current_macro); // No macro is currently available, cannot create maps!
+
+    return;
+  }
+
+  // Create Query
+  if(name == "luaprogram") {
+    if(state != LUAPROGRAMS) error("lua program found outside maps.");
+    state = LUAPROGRAM;
+
+    assert(current_macro); // No macro is currently available, cannot create map!
+
+    LUAProgram l;
+    l.attributes = attributes;
+    current_macro->luaprograms.push_back(l);
+    current_luaprogram = &(current_macro->luaprograms.back());
+
+    return;
+  }
+
   // Enable widget parsing
   if(name == "window") {
 
@@ -243,6 +272,11 @@ void TemplateParser::endTag(std::string name)
     current_map = NULL;
     state = MAPS;
   }
+  if(name == "luaprograms") state = MACRO;
+  if(name == "luaprogram") {
+    current_luaprogram = NULL;
+    state = LUAPROGRAMS;
+  }
   if(name == "window") state = MACRO;
   
   if(state == WINDOW) {
diff --git a/server/src/templateparser.h b/server/src/templateparser.h
index 70197eb..61ad42a 100644
--- a/server/src/templateparser.h
+++ b/server/src/templateparser.h
@@ -39,7 +39,9 @@ typedef enum {
   QUERY,
   MAPS,
   MAP,
-  WINDOW
+  WINDOW,
+  LUAPROGRAMS,
+  LUAPROGRAM
 } ParserState;
 
 class TemplateParser : public SAXParser {
@@ -67,6 +69,7 @@ private:
   Template *t;
   Macro *current_macro;
   Map *current_map;
+  LUAProgram *current_luaprogram;
   std::vector< Widget* > widgetstack;
 
   // Error callback function.
diff --git a/server/src/widgetgenerator.cc b/server/src/widgetgenerator.cc
index 52752cc..6234513 100644
--- a/server/src/widgetgenerator.cc
+++ b/server/src/widgetgenerator.cc
@@ -113,6 +113,6 @@ void widgetgenerator(TCPSocket &socket, Macro &macro, LUAQueryMapper &mapper, Da
   get_fields(macro.window, fields);
 
   Values values = db.getValues("2003791613", fields);
-
+  
   send_macro_widget(macro, macro.window, socket, "      ", mapper, values);
 }
diff --git a/server/xml/example2.xml b/server/xml/example2.xml
index 0bfee27..ddcc4e6 100644
--- a/server/xml/example2.xml
+++ b/server/xml/example2.xml
@@ -22,6 +22,16 @@
           return lensmeter.right.cyl.value, lensmeter.right.cyl.timestamp
         </map>
       </maps>
+      <luaprograms>
+	<luaprogram name="theanswer">
+	  if( tonumber(value) == 42 )
+	  then
+	    return true
+	  else
+	    return false
+	  end
+	</luaprogram>
+      </luaprograms>
       <window name="mainwindow"
               caption="Fundus"
               width="500"
@@ -30,11 +40,7 @@
         <frame name="linse_frame" caption="Linser:" layout="vbox">
           <frame name="linse_framea" layout="hbox">
             <label name="a" width="300" caption="Akse rotation:"/>
-            <lineedit name="linse4"
-		      regexp="[24]*"
-		      map="axis"
-		      lua_validator="if( tonumber(value) == 42 ) then return 'true' else return 'false' end"
-		      value="90K"/>
+            <lineedit name="linse4" regexp="[24]*" map="axis" lua="theanswer" value="90K"/>
           </frame>
           <frame name="linse_frameb" layout="hbox">
             <label name="b" width="300" caption="Sphere:"/>
-- 
cgit v1.2.3