/* * * 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; }