/*
*
* ProLinga-Validate
*
* Copyright (C) 2002-2008 Xobas Software.
* All rights reserved.
*
* This file is part of ProLinga-Validate.
*
* ProLinga-Validate 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-Validate 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-Validate. If not, see .
*
* More information is available at the following addresses:
*
* Website : http://www.prolinga.org
*
* Email : prolinga-list@prolinga.org
*
*
*/
#include "ValCommon.h"
#include
#include
#include "VCValidateCommand.hpp"
#include "CmdValObject.hpp"
#include "CmdValLogic.hpp"
#include "ValMain.hpp"
//#ifndef __ERROR_H
#include "ValError.hpp"
//#endif
bool VCisOnlySpace(const char *str)
{
int i,j;
j = strlen(str);
for(i=0;ixmlChildrenNode != NULL)
{
VCremoveWhiteSpace(cur->xmlChildrenNode);
}
if ((!strncmp((char *)cur->name, "text",4)) && (VCisOnlySpace((char *)cur->content)))
{
curRemove = cur;
cur = cur->next;
xmlUnlinkNode(curRemove);
xmlFreeNode(curRemove);
}
else
{
cur = cur->next;
}
}
}
void VCInsertError(const char *Id, const char *Severity, const char *Description, xmlDocPtr *docResponse, xmlNodePtr *curResponse)
{
/* Insert Error */
*curResponse = xmlNewTextChild (*curResponse, NULL, (const xmlChar *)"Error", (const xmlChar *)"");
xmlNewProp (*curResponse, (const xmlChar *)"Id", (const xmlChar *)Id);
xmlNewTextChild (*curResponse, NULL, (const xmlChar *)"Severity", (const xmlChar *)Severity);
xmlNewTextChild (*curResponse, NULL, (const xmlChar *)"Description", (const xmlChar *)Description);
}
void VCCreateResponse(xmlDocPtr *docResponse, xmlNodePtr *curResponse)
{
/* Set up Response file */
*docResponse = xmlNewDoc((const xmlChar *)XML_VERSION);
(*docResponse)->children = xmlNewDocNode(*docResponse, NULL, (const xmlChar *)ROOT_ELEM, NULL);
*curResponse = xmlDocGetRootElement(*docResponse);
xmlNewTextChild (*curResponse, NULL, (const xmlChar *)"Validate", (const xmlChar *)"");
*curResponse = (*curResponse)->xmlChildrenNode;
xmlNewProp (*curResponse, (const xmlChar *)"Version", (const xmlChar *)VAL_DOC_VERSION);
}
int VCWriteResponse(const xmlDocPtr docResponse, const char *rcOut)
{
return xmlSaveFile(rcOut, docResponse);
}
void VCCreateCommandDoc(xmlNodePtr cur, xmlDocPtr *docCmd)
{
xmlNodePtr curCmd;
/* Set node pointer to object in repository command */
cur = cur->xmlChildrenNode;
while (cur != NULL)
{
if (!xmlStrcmp(cur->name, (const xmlChar *) "Object"))
break;
cur = cur->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(cur);
}
void VCCreateResponseCommand(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");
}
void VCInsertResponseObject(const char *objApplication, const char *objType, const char *objName, xmlDocPtr **docCmd)
{
xmlNodePtr curCmd;
/* Insert appn, type and 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 *)"Application", (const xmlChar *)objApplication);
xmlNewProp (curCmd, (const xmlChar *)"Type", (const xmlChar *)objType);
//curCmd = xmlNewTextChild (curCmd, NULL, (const xmlChar *)"Name", (const xmlChar *)objName);
xmlNewProp (curCmd, (const xmlChar *)"Name", (const xmlChar *)objName);
}
void VCInsertResponseObjectError(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 VCInsertResponseObjectDoc(const xmlDocPtr docObj, xmlDocPtr **docCmd)
{
xmlNodePtr curObj, curCmd ;
/* Set Pointer Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
curCmd = xmlGetLastChild(curCmd);
/* Set Pointer Object */
curObj = xmlDocGetRootElement(docObj);
curObj = curObj->xmlChildrenNode;
curObj = xmlGetLastChild(curObj);
/* Merge */
xmlAddChild(curCmd, xmlCopyNodeList(curObj));
}
void VCOLDInsertResponseObjectDoc(const xmlDocPtr docObj, xmlDocPtr **docCmd)
{
xmlNodePtr curObj, curCmd ;
//xmlAttrPtr attrCmd;
/* Set Pointer Command Response */
curCmd = xmlDocGetRootElement(**docCmd);
curCmd = curCmd->xmlChildrenNode;
while (curCmd != NULL)
{
if (!xmlStrcmp(curCmd->name, (const xmlChar *) "Command"))
break;
curCmd = curCmd->next;
}
//attrCmd = xmlNewProp (curCmd, (const xmlChar *)"Id", (const xmlChar *)"1");
/* 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 VCSetResponseCommandStatus(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 VCMergeResponse(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 *) "Validate"))
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));
}
int VCCommandExec(const char *cmdName, const xmlDocPtr docCmd, xmlDocPtr *docRespCmd)
{
xmlDocPtr docError = NULL;
xmlNodePtr curCmd;
char *objApplication = NULL, *objType = NULL, *objName = NULL;
char *externalError;
int retStatus, cmdStatus = 0;
/* Create Command Response */
VCCreateResponseCommand(cmdName, &docRespCmd);
/* Set pointer to command */
curCmd = xmlDocGetRootElement(docCmd);
/* Loop through all Objects */
for (curCmd = curCmd->xmlChildrenNode; curCmd != NULL; curCmd = curCmd->next)
{
if (xmlStrcmp(curCmd->name, (const xmlChar *) "Object")) continue;
/* Get Object Index Details */
objApplication = (char *)xmlGetProp(curCmd, (const xmlChar *)"Application");
objType = (char *)xmlGetProp(curCmd, (const xmlChar *)"Type");
objName = (char *)xmlGetProp(curCmd, (const xmlChar *)"Name");
/* Determine command and call appropriate function */
if (!strcmp(cmdName, "TransformOnly"))
{
/* Validate Logic Command */
retStatus = CmdValLogic(true, objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(cmdName, "Validate"))
{
if (!strcmp(objType, "Constant"))
{
/* Validate Constant Command */
retStatus = CmdValConstant(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Index"))
{
/* Validate Index Command */
retStatus = CmdValIndex(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Logic"))
{
/* Validate Logic Command */
retStatus = CmdValLogic(false, objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Record"))
{
/* Validate Record Command */
retStatus = CmdValRecord(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Table"))
{
/* Validate Table Command */
retStatus = CmdValTable(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Thread"))
{
/* Validate Thread Command */
retStatus = CmdValThread(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "Variable"))
{
/* Validate Variable Command */
retStatus = CmdValVariable(objApplication, objType, objName, &externalError, &docError);
}
else if (!strcmp(objType, "VariableGroup"))
{
/* Validate Variable Group Command */
retStatus = CmdValVariableGroup(objApplication, objType, objName, &externalError, &docError);
}
else
{
/* Generate warning */
retStatus = 30012;
}
/* Insert Object line in response */
VCInsertResponseObject(objApplication, objType, objName, &docRespCmd);
}
else if (!strcmp(cmdName, "Ping"))
{
/* Dummy to test if service is available */
retStatus = 0;
}
else
{
/* Invalid Command */
retStatus = 0;
continue;
}
/* Error handling */
if (retStatus != 0)
{
/* If external / 3rd party error */
if (retStatus == 90001)
{
VCInsertResponseObjectError(retStatus, "Error", "External warning/error", externalError, &docRespCmd);
delete externalError;
cmdStatus = 2;
}
else
{
VCInsertResponseObjectError(retStatus, errorValSeverity[errorTable30000[(retStatus-30000)].severity], errorTable30000[(retStatus-30000)].description, "", &docRespCmd);
if (cmdStatus < errorTable30000[(retStatus-30000)].severity)
cmdStatus = errorTable30000[(retStatus-30000)].severity;
if (retStatus == 30010)
{
/* Insert Error document */
VCInsertResponseObjectDoc(docError, &docRespCmd);
}
}
}
}
/* Write Status */
VCSetResponseCommandStatus(cmdStatus, &docRespCmd);
/* Return */
return 0;
}
xmlDocPtr VCValidateCommand(const xmlDocPtr doc)
{
xmlDocPtr docCmd, docResponse, docRespCmd;
xmlNodePtr cur, curResponse;
char *cmdName;
int retStatus;
/* Set up response document */
VCCreateResponse(&docResponse, &curResponse);
cur = xmlDocGetRootElement(doc);
/* Check if correct repository XML and version */
cur = cur->xmlChildrenNode;
if (!xmlStrcmp(cur->name, (const xmlChar *) "text"))
cur = cur->next;
/* Loop through all Validate Commands */
for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next)
{
if (xmlStrcmp(cur->name, (const xmlChar *) "Command")) continue;
/* Get command name */
cmdName = (char *)xmlGetProp(cur, (const xmlChar *)"Name");
/* Create Command document */
VCCreateCommandDoc(cur, &docCmd);
/* Execute Command */
retStatus = VCCommandExec(cmdName, docCmd, &docRespCmd);
/* Merge response level2 in level 1 */
VCMergeResponse(docRespCmd, &docResponse);
/* Release Command Doc */
xmlFreeDoc(docCmd);
xmlFreeDoc(docRespCmd);
}
/* Debug */
/* Print document */
/* buf = xmlBufferCreate();
curResponse = xmlDocGetRootElement(docResponse);
xmlNodeDump(buf, docResponse, curResponse, 0, 1);
printf("%s\n", (char *)xmlBufferContent(buf));
xmlBufferFree(buf);
*/
/* Release + cleanup */
//xmlCleanupParser();
/* Return OK */
return docResponse;
}