/*
*
* ProLinga-UI
*
* Copyright (C) 2002-2008 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-UI.
*
* ProLinga-UI is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProLinga-UI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProLinga-UI. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "UICommon.h"
#include
#include
#include "UIMain.hpp"
#include "UCUICommand.hpp"
#include "UCScreen.hpp"
#include "UIError.hpp"
/* Global Config Pointer */
//extern ConfigUIPtr confUIPtr;
xmlDocPtr UCCreateResponse(void)
{
xmlDocPtr docRes;
xmlNodePtr curRes;
/* Set up Response file */
docRes = xmlNewDoc((const xmlChar *)XML_VERSION);
docRes->children = xmlNewDocNode(docRes, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curRes = xmlDocGetRootElement(docRes);
xmlNewTextChild (curRes, NULL, (const xmlChar *)"UI", (const xmlChar *)"");
curRes = curRes->xmlChildrenNode;
xmlNewProp (curRes, (const xmlChar *)"Version", (const xmlChar *)UI_DOC_VERSION);
/* return */
return docRes;
}
xmlDocPtr UCCreateCommandDoc(xmlNodePtr curReq)
{
xmlDocPtr docCmd = NULL;
xmlNodePtr curCmd;
/* Set node pointer to object in repository command */
curReq = curReq->xmlChildrenNode;
while (curReq != NULL)
{
if (!xmlStrcmp(curReq->name, (const xmlChar *) "Object"))
break;
curReq = curReq->next;
}
/* Create new Command Doc */
docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
docCmd->children = xmlNewDocNode(docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(docCmd);
curCmd->xmlChildrenNode = xmlCopyNodeList(curReq);
/* Return */
return docCmd;
}
xmlDocPtr UCCreateObjectDoc(const xmlNodePtr curReqCmd)
{
xmlDocPtr docObj;
xmlNodePtr curObj;
/* Create new Object Doc */
docObj = xmlNewDoc((const xmlChar *)XML_VERSION);
docObj->children = xmlNewDocNode(docObj, NULL, (const xmlChar *)ROOT_ELEM, NULL);
/* Set node pointer */
curObj = xmlDocGetRootElement(docObj);
/* Copy Object Node list */
curObj->xmlChildrenNode = xmlCopyNode(curReqCmd, 1);
/* Return */
return docObj;
}
xmlDocPtr UCCreateResponseCommand(const char *cmdName)
{
xmlDocPtr docCmd;
xmlNodePtr curCmd;
/* Create Command Response */
docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
docCmd->children = xmlNewDocNode(docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(docCmd);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Command", (const xmlChar *)"");
curCmd = curCmd->xmlChildrenNode;
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)cmdName);
xmlNewProp (curCmd, (const xmlChar *)"Mode", (const xmlChar *)"Response");
/* Return */
return docCmd;
}
void RCCreateResponseObject(const char *objApplication, const char *objType, const char *objName, xmlDocPtr *docCmd)
{
xmlNodePtr curCmd;
*docCmd = xmlNewDoc((const xmlChar *)XML_VERSION);
(**docCmd).children = xmlNewDocNode(*docCmd, NULL, (const xmlChar *)ROOT_ELEM, NULL);
curCmd = xmlDocGetRootElement(*docCmd);
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
xmlNewProp (curCmd, (const xmlChar *)"Application", (const xmlChar *)objApplication);
xmlNewProp (curCmd, (const xmlChar *)"Type", (const xmlChar *)objType);
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)"objName");
}
void UCInsertResponseObject(const char *objName, xmlDocPtr docCmd)
{
xmlNodePtr curCmd;
/* Insert name in Command Response */
curCmd = xmlDocGetRootElement(docCmd);
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "text"))
curCmd = curCmd->next;
curCmd = curCmd->xmlChildrenNode;
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "text"))
curCmd = curCmd->next;
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Object", (const xmlChar *)"");
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)objName);
}
void UCInsertResponseCommandError(const int id, const char *severity, const char *description, const char *externalDesc, xmlDocPtr docCmd)
{
xmlNodePtr curCmd;
char dummyId[10]="";
/* Set Pointer */
curCmd = xmlDocGetRootElement(docCmd);
curCmd = curCmd->xmlChildrenNode;
/* Insert Error */
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
sprintf(dummyId, "%d", id);
xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)dummyId);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Description", (const xmlChar *)description);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"ExternalDescription", (const xmlChar *)externalDesc);
}
void UCInsertResponseObjectError(const int id, const char *severity, const char *description, const char *externalDesc, xmlDocPtr docCmd)
{
xmlNodePtr curCmd;
char dummyId[10]="";
/* Set Pointer */
curCmd = xmlDocGetRootElement(docCmd);
curCmd = curCmd->xmlChildrenNode;
curCmd = xmlGetLastChild(curCmd);
/* Insert Error */
curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
sprintf(dummyId, "%d", id);
xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)dummyId);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Severity", (const xmlChar *)severity);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Description", (const xmlChar *)description);
xmlNewTextChild (curCmd, NULL, (const xmlChar *)"ExternalDescription", (const xmlChar *)externalDesc);
}
void UCInsertResponseObjectDoc(const xmlDocPtr docObj, xmlDocPtr docCmd)
{
xmlNodePtr curObj, curCmd ;
/* Set Pointer Command Response */
curCmd = xmlDocGetRootElement(docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
/* Set Pointer Object */
curObj = xmlDocGetRootElement(docObj);
curObj = curObj->xmlChildrenNode;
while (curObj != NULL)
{
if (!xmlStrcmp(curObj->name, (const xmlChar *) "Object"))
break;
curObj = curObj->next;
}
/* Merge */
xmlAddChild(curCmd, xmlCopyNodeList(curObj));
}
void UCSetResponseCommandStatus(const int cmdStatus, xmlDocPtr docCmd)
{
xmlNodePtr curCmd;
/* Write Status */
curCmd = xmlDocGetRootElement(docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
if (cmdStatus == 0)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Ok");
else if (cmdStatus == 1)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Warning");
else if (cmdStatus == 2)
xmlNewProp (curCmd, (const xmlChar *)"Status", (const xmlChar *)"Error");
}
void UCMergeResponse(const xmlDocPtr docSrc, xmlDocPtr docDest)
{
xmlNodePtr curSrc, curDest;
/* Set pointer in source document */
curDest = xmlDocGetRootElement(docDest);
curDest = curDest->xmlChildrenNode;
while (curDest != NULL)
{
if (!xmlStrcmp(curDest->name, (const xmlChar *) "UI"))
break;
curDest = curDest->next;
}
/* Set pointer in destination document */
curSrc = xmlDocGetRootElement(docSrc);
curSrc = curSrc->xmlChildrenNode;
while (curSrc != NULL)
{
if (!xmlStrcmp(curSrc->name, (const xmlChar *) "Command"))
break;
curSrc = curSrc->next;
}
/* Merge */
xmlAddChild(curDest, xmlCopyNodeList(curSrc));
}
xmlDocPtr UCCommandExec(const char *cmdName, const xmlDocPtr docReqCmd)
{
xmlDocPtr docResCmd = NULL, docReturn = NULL, docObj = NULL;
xmlNodePtr curReqCmd;
char *objName = NULL;
char *externalError;
int dbStatus = 0, cmdStatus = 0;
int objCount = 0;
/* Create Command Response */
docResCmd = UCCreateResponseCommand(cmdName);
/* Set pointer to command */
curReqCmd = xmlDocGetRootElement(docReqCmd);
/* Loop through all Objects */
for (curReqCmd = curReqCmd->xmlChildrenNode; curReqCmd != NULL; curReqCmd = curReqCmd->next)
{
if (xmlStrcmp(curReqCmd->name, (const xmlChar *) "Object")) continue;
/* Get Name Details */
objName = (char *)xmlGetProp(curReqCmd, (const xmlChar *)"Name");
if (objName == NULL)
objName = "";
/* Determine command and call appropriate function */
if (!strcmp(cmdName, "Screen"))
{
/* Create Object Doc */
docObj = UCCreateObjectDoc(curReqCmd);
/* Screen Command */
dbStatus = UCScreen(docObj, objName, &externalError, &docReturn);
if (dbStatus == 0)
{
/* Merge result in response */
UCInsertResponseObjectDoc(docReturn, docResCmd);
xmlFreeDoc(docReturn);
}
else
{
/* Insert Object line in response */
UCInsertResponseObject(objName, docResCmd);
}
/* Up the objCount */
objCount++;
}
else if (!strcmp(cmdName, "Ping"))
{
/* Dummy to test if service is available */
dbStatus = 0;
}
else
{
/* Invalid Command */
dbStatus = 19002;
//continue;
}
/* Error handling */
if (dbStatus != 0)
{
/* If external / 3rd party error */
if (dbStatus == 90001)
{
UCInsertResponseObjectError(dbStatus, "Error", "External warning/error", externalError, docResCmd);
delete externalError;
cmdStatus = 2;
}
else
{
UCInsertResponseObjectError(dbStatus, errorSeverity[errorTable19000[(dbStatus-19000)].severity], errorTable19000[(dbStatus-19000)].description, "", docResCmd);
if (cmdStatus < errorTable19000[(dbStatus-19000)].severity)
cmdStatus = errorTable19000[(dbStatus-19000)].severity;
}
}
}
/* If no Objects, only Ping command allowed */
if (objCount == 0)
{
if (!strcmp(cmdName, "Ping"))
dbStatus = 0;
else
dbStatus = 19002;
/* Error handling */
if (dbStatus != 0)
{
/* If external / 3rd party error */
if (dbStatus == 90001)
{
UCInsertResponseCommandError(dbStatus, "Error", "External warning/error", externalError, docResCmd);
delete externalError;
cmdStatus = 2;
}
else
{
UCInsertResponseCommandError(dbStatus, errorSeverity[errorTable19000[(dbStatus-19000)].severity], errorTable19000[(dbStatus-19000)].description, "", docResCmd);
if (cmdStatus < errorTable19000[(dbStatus-19000)].severity)
cmdStatus = errorTable19000[(dbStatus-19000)].severity;
}
}
}
/* Write Status */
UCSetResponseCommandStatus(cmdStatus, docResCmd);
/* Return */
return docResCmd;
}
xmlDocPtr UCUICommand(const xmlDocPtr docReq)
{
xmlDocPtr docReqCmd = NULL, docRes = NULL, docResCmd = NULL;
xmlNodePtr curReq = NULL;
char *cmdName;
int dbStatus;
/* Set up response document */
docRes = UCCreateResponse();
/* Point to root element */
curReq = xmlDocGetRootElement(docReq);
/* Down 1 level (/ProLinga/UI) */
curReq = curReq->xmlChildrenNode;
while (curReq != NULL)
{
if (xmlNodeIsText(curReq) == 0)
break;
curReq = curReq->next;
}
/* Loop through all UI Commands */
for (curReq = curReq->xmlChildrenNode; curReq != NULL; curReq = curReq->next)
{
if (xmlStrcmp(curReq->name, (const xmlChar *) "Command")) continue;
/* Get command name */
cmdName = (char *)xmlGetProp(curReq, (const xmlChar *)"Name");
/* Create Command document */
docReqCmd = UCCreateCommandDoc(curReq);
/* Execute Command */
docResCmd = UCCommandExec(cmdName, docReqCmd);
/* Merge response level2 in level 1 */
UCMergeResponse(docResCmd, docRes);
/* Clean up */
xmlFreeDoc(docReqCmd);
xmlFreeDoc(docResCmd);
}
/* Debug */
/* Print document */
/*
xmlBufferPtr buf = xmlBufferCreate();
curResponse = xmlDocGetRootElement(docResponse);
xmlNodeDump(buf, docResponse, curResponse, 0, 1);
printf("QQQ\n%s\n", (char *)xmlBufferContent(buf));
xmlBufferFree(buf);
*/
/* Release + cleanup */
//xmlCleanupParser();
/* Return OK */
return docRes;
}