| 1 | #include "xmlpatch.h" | 
|---|
| 2 |  | 
|---|
| 3 | XmlPatch::XmlPatch(QString patchFilesWildcard, QString forceTargetFilesWildcard, bool noBackups, bool noVerbose) | 
|---|
| 4 | { | 
|---|
| 5 | this->patchFilesToProcess=UtilXmlTools::getAllPatchFilesByWildcard(patchFilesWildcard); | 
|---|
| 6 | this->forceTargetFilesWildcard=forceTargetFilesWildcard; | 
|---|
| 7 | this->backupsEnabled=!noBackups; | 
|---|
| 8 | this->verboseEnabled=!noVerbose; | 
|---|
| 9 |  | 
|---|
| 10 | if(forceTargetFilesWildcard!=""){ | 
|---|
| 11 | std::cout << "User forced patch in the target file(s): " << forceTargetFilesWildcard.toUtf8().constData() << std::endl; | 
|---|
| 12 | } | 
|---|
| 13 |  | 
|---|
| 14 | if(this->patchFilesToProcess.isEmpty()){ | 
|---|
| 15 | UtilXmlTools::displayErrorMessage("Loading patch files","No .patch or .oni-patch files were found for the wildcard: "+patchFilesWildcard); | 
|---|
| 16 | } | 
|---|
| 17 |  | 
|---|
| 18 | } | 
|---|
| 19 |  | 
|---|
| 20 | void XmlPatch::readAndProcessPatchFile(){ | 
|---|
| 21 |  | 
|---|
| 22 | // Process all PatchFiles | 
|---|
| 23 | for(int i=0; i<this->patchFilesToProcess.size(); i++){ | 
|---|
| 24 |  | 
|---|
| 25 | QFile inputFile(this->patchFilesToProcess[i]); | 
|---|
| 26 |  | 
|---|
| 27 | if (inputFile.open(QIODevice::ReadOnly)) | 
|---|
| 28 | { | 
|---|
| 29 |  | 
|---|
| 30 | QTextStream fileStream(&inputFile); | 
|---|
| 31 |  | 
|---|
| 32 | checkPatchVersion(this->patchFilesToProcess[i], fileStream); | 
|---|
| 33 | checkAndProcessValidCommands(fileStream); | 
|---|
| 34 |  | 
|---|
| 35 | inputFile.close(); | 
|---|
| 36 | } | 
|---|
| 37 | else{ | 
|---|
| 38 | UtilXmlTools::displayErrorMessage("Read patch file", "Error opening patch file: '" + this->patchFilesToProcess[i] + "'.\n" + inputFile.errorString()); | 
|---|
| 39 | } | 
|---|
| 40 |  | 
|---|
| 41 | } | 
|---|
| 42 |  | 
|---|
| 43 | UtilXmlTools::displaySuccessMessage(this->patchFilesToProcess.size(),"Patch File(s)"); | 
|---|
| 44 |  | 
|---|
| 45 | } | 
|---|
| 46 |  | 
|---|
| 47 | void XmlPatch::insertNodesOperation(const QString &xmlString, XmlFilter &filters, const QString &xPathExpression, const QString &filesWildcard){ | 
|---|
| 48 |  | 
|---|
| 49 | QVector<QString> filesToProcess; | 
|---|
| 50 | QList<pugi::xml_node> nodesToInsertion; | 
|---|
| 51 | pugi::xml_document newNode; | 
|---|
| 52 | pugi::xml_parse_result result; | 
|---|
| 53 |  | 
|---|
| 54 | filesToProcess=UtilXmlTools::getAllXmlFilesByWildcard(filesWildcard); | 
|---|
| 55 |  | 
|---|
| 56 | if(filesToProcess.isEmpty()){ | 
|---|
| 57 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES","No XML files were found for the wildcard: "+filesWildcard); | 
|---|
| 58 | } | 
|---|
| 59 |  | 
|---|
| 60 | result=newNode.load(xmlString.toUtf8().constData()); // load xml to insert | 
|---|
| 61 |  | 
|---|
| 62 | if(result.status!=pugi::status_ok){ | 
|---|
| 63 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES", "The xml node to insert is invalid.\n" + Util::toQString(result.description())); | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | // Process all XmlFiles | 
|---|
| 67 | for(int i=0; i<filesToProcess.size(); i++){ | 
|---|
| 68 |  | 
|---|
| 69 | UtilXmlTools::loadXmlFile(filesToProcess[i],this->document,this->rootNode,this->backupsEnabled,this->verboseEnabled,"@ADD_INSIDE_NODES"); | 
|---|
| 70 |  | 
|---|
| 71 | // Check how the element will be fetched via element name or xpath expression | 
|---|
| 72 | if(xPathExpression.isEmpty()){ | 
|---|
| 73 | UtilXmlTools::getAllNamedElements(this->rootNode,nodesToInsertion,filters); | 
|---|
| 74 | } | 
|---|
| 75 | else{ | 
|---|
| 76 | UtilXmlTools::getAllXpathElements(xPathExpression,this->document,nodesToInsertion); | 
|---|
| 77 | } | 
|---|
| 78 |  | 
|---|
| 79 | if(nodesToInsertion[0].type()==pugi::node_null){ | 
|---|
| 80 |  | 
|---|
| 81 | QString errMessage; | 
|---|
| 82 |  | 
|---|
| 83 | if(xPathExpression.isEmpty()){ | 
|---|
| 84 | errMessage = "No node was found with an ElementName: '" + filters.getElementName() + "'"; | 
|---|
| 85 | if(filters.getParentElementName()!=""){ | 
|---|
| 86 | errMessage += " and a ParentElementName: '" + filters.getParentElementName() + "'"; | 
|---|
| 87 | } | 
|---|
| 88 | if(filters.getAttributeName()!=""){ | 
|---|
| 89 | errMessage += " and an AttributeName: '" + filters.getAttributeName() + "' and an AttributeValue: '" + filters.getAttributeValue() + "'"; | 
|---|
| 90 | } | 
|---|
| 91 | } | 
|---|
| 92 | else{ | 
|---|
| 93 | errMessage = "No node was found with an XPathExpression: '" + xPathExpression + "'"; | 
|---|
| 94 | } | 
|---|
| 95 |  | 
|---|
| 96 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES",errMessage); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | for(int j=0; j<nodesToInsertion.size(); j++){ | 
|---|
| 100 | for (pugi::xml_node currNodeToInsert = newNode.first_child(); currNodeToInsert; currNodeToInsert = currNodeToInsert.next_sibling()) | 
|---|
| 101 | { | 
|---|
| 102 | nodesToInsertion[j].append_copy(currNodeToInsert); // append the new node | 
|---|
| 103 | } | 
|---|
| 104 |  | 
|---|
| 105 | } | 
|---|
| 106 |  | 
|---|
| 107 | UtilXmlTools::saveXmlFile(filesToProcess[i],this->document, "@ADD_INSIDE_NODES"); | 
|---|
| 108 |  | 
|---|
| 109 | nodesToInsertion.clear(); | 
|---|
| 110 | } | 
|---|
| 111 |  | 
|---|
| 112 | UtilXmlTools::displaySuccessMessage(filesToProcess.size(),"@ADD_INSIDE_NODES"); | 
|---|
| 113 | } | 
|---|
| 114 |  | 
|---|
| 115 | void XmlPatch::removeNodesOperation(XmlFilter &filters, const QString &xPathExpression, const QString &filesWildcard){ | 
|---|
| 116 |  | 
|---|
| 117 | QVector<QString> filesToProcess; | 
|---|
| 118 |  | 
|---|
| 119 | QList<pugi::xml_node> nodesToDeletion; | 
|---|
| 120 |  | 
|---|
| 121 | filesToProcess=UtilXmlTools::getAllXmlFilesByWildcard(filesWildcard); | 
|---|
| 122 |  | 
|---|
| 123 | if(filesToProcess.isEmpty()){ | 
|---|
| 124 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES","No XML files were found for the wildcard: "+filesWildcard); | 
|---|
| 125 | } | 
|---|
| 126 |  | 
|---|
| 127 | // Process all XmlFiles | 
|---|
| 128 | for(int i=0; i<filesToProcess.size(); i++){ | 
|---|
| 129 |  | 
|---|
| 130 | UtilXmlTools::loadXmlFile(filesToProcess[i],this->document,this->rootNode,this->backupsEnabled,this->verboseEnabled,"@REMOVE_NODES"); | 
|---|
| 131 |  | 
|---|
| 132 | // Check how the element will be fetched via element name or xpath expression | 
|---|
| 133 | if(xPathExpression.isEmpty()){ | 
|---|
| 134 | UtilXmlTools::getAllNamedElements(this->rootNode,nodesToDeletion,filters); | 
|---|
| 135 | } | 
|---|
| 136 | else{ | 
|---|
| 137 | UtilXmlTools::getAllXpathElements(xPathExpression,this->document,nodesToDeletion); | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | if(nodesToDeletion[0].type()==pugi::node_null){ | 
|---|
| 141 |  | 
|---|
| 142 | QString errMessage; | 
|---|
| 143 |  | 
|---|
| 144 | if(xPathExpression.isEmpty()){ | 
|---|
| 145 | errMessage = "No node was found with an ElementName: '" + filters.getElementName() + "'"; | 
|---|
| 146 | if(filters.getParentElementName()!=""){ | 
|---|
| 147 | errMessage += " and a ParentElementName: '" + filters.getParentElementName() + "'"; | 
|---|
| 148 | } | 
|---|
| 149 | if(filters.getAttributeName()!=""){ | 
|---|
| 150 | errMessage += " and an AttributeName: '" + filters.getAttributeName() + "' and an AttributeValue: '" + filters.getAttributeValue() + "'"; | 
|---|
| 151 | } | 
|---|
| 152 | } | 
|---|
| 153 | else{ | 
|---|
| 154 | errMessage = "No node was found with an XPathExpression: '" + xPathExpression + "'"; | 
|---|
| 155 | } | 
|---|
| 156 |  | 
|---|
| 157 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES",errMessage); | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | // Delete all the specified nodes | 
|---|
| 161 | for(int j=0; j<nodesToDeletion.size(); j++){ | 
|---|
| 162 | if(!nodesToDeletion[j].parent().remove_child(nodesToDeletion[j])){  // remove the node | 
|---|
| 163 |  | 
|---|
| 164 | QString errMessage; | 
|---|
| 165 | if(xPathExpression.isEmpty()){ | 
|---|
| 166 | errMessage = "Couldn't remove the node with Element '" + filters.getElementName() + "'"; | 
|---|
| 167 |  | 
|---|
| 168 | if(filters.getParentElementName()!=""){ | 
|---|
| 169 | errMessage += " and a ParentElement: '" + filters.getParentElementName() + "'"; | 
|---|
| 170 | } | 
|---|
| 171 | } | 
|---|
| 172 | else{ | 
|---|
| 173 | errMessage = "Couldn't remove the node with the XPathExpression '" + xPathExpression + "'"; | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES",errMessage); | 
|---|
| 177 | } | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | UtilXmlTools::saveXmlFile(filesToProcess[i],this->document, "@REMOVE_NODES"); | 
|---|
| 181 |  | 
|---|
| 182 | nodesToDeletion.clear(); | 
|---|
| 183 | } | 
|---|
| 184 |  | 
|---|
| 185 | UtilXmlTools::displaySuccessMessage(filesToProcess.size(), "@REMOVE_NODES"); | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | void XmlPatch::executeCommandOperation(const QString &commandString){ | 
|---|
| 189 |  | 
|---|
| 190 | // Avoid infinite fork loops | 
|---|
| 191 | if(commandString.contains("-p ") || commandString.contains("--patch-files ")){ | 
|---|
| 192 | UtilXmlTools::displayErrorMessage("@COMMAND","Use of --patch-files option is not allowed inside a patch file"); | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | // Reserved to AEI | 
|---|
| 196 | if(commandString.contains("--aei-patch-files-list ")){ | 
|---|
| 197 | UtilXmlTools::displayErrorMessage("@COMMAND","Use of --aei-patch-files-list option is not allowed inside a patch file"); | 
|---|
| 198 | } | 
|---|
| 199 |  | 
|---|
| 200 | std::cout << "@COMMAND patch operation output:\n" | 
|---|
| 201 | << "########################################################################" | 
|---|
| 202 | << std::endl; | 
|---|
| 203 |  | 
|---|
| 204 | OptionsParser myParser(Util::QStringToArgsArray(commandString)); | 
|---|
| 205 | myParser.parse(); | 
|---|
| 206 |  | 
|---|
| 207 | std::cout | 
|---|
| 208 | << "########################################################################" | 
|---|
| 209 | << std::endl; | 
|---|
| 210 |  | 
|---|
| 211 | UtilXmlTools::displaySuccessMessage(1,"@COMMAND"); | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | void XmlPatch::executeCustomCommandOperation(const QString &jsString, const QString &filesWildcard){ | 
|---|
| 215 |  | 
|---|
| 216 | QVector<QString> filesToProcess=UtilXmlTools::getAllXmlFilesByWildcard(filesWildcard); | 
|---|
| 217 |  | 
|---|
| 218 | if(filesToProcess.isEmpty()){ | 
|---|
| 219 | UtilXmlTools::displayErrorMessage("@CUSTOM_CODE","No XML files were found for the wildcard: "+filesWildcard); | 
|---|
| 220 | } | 
|---|
| 221 |  | 
|---|
| 222 | this->customCodeOperation.executeCustomCode(jsString,filesToProcess,this->backupsEnabled,this->verboseEnabled); | 
|---|
| 223 |  | 
|---|
| 224 |  | 
|---|
| 225 | UtilXmlTools::displaySuccessMessage(filesToProcess.size(), "@CUSTOM_CODE"); | 
|---|
| 226 | } | 
|---|
| 227 |  | 
|---|
| 228 | void XmlPatch::checkPatchVersion(const QString &file, QTextStream &fileStream){ | 
|---|
| 229 |  | 
|---|
| 230 | QString line, patchVersion=""; | 
|---|
| 231 |  | 
|---|
| 232 | // First get the patch version and check its validity | 
|---|
| 233 | while ( !fileStream.atEnd() ){ | 
|---|
| 234 | line = fileStream.readLine(); | 
|---|
| 235 |  | 
|---|
| 236 | if(line.startsWith('#')){ // Ignore comments | 
|---|
| 237 | continue; | 
|---|
| 238 | } | 
|---|
| 239 | else if(line.startsWith("@XML_TOOLS")){ | 
|---|
| 240 |  | 
|---|
| 241 | patchVersion=getPatchParameterValue(line,"Version"); | 
|---|
| 242 |  | 
|---|
| 243 | if(!patchVersion.startsWith("2.0")){ | 
|---|
| 244 | QString errMessage; | 
|---|
| 245 |  | 
|---|
| 246 | errMessage = "The current patch version is incompatible with this XmlTools version:\n"; | 
|---|
| 247 | errMessage += "Patch file name: '" + file + "'\n"; | 
|---|
| 248 | errMessage += "XmlTools version:  " + GlobalVars::AppVersion + "\n" + "CurrPatch version: " + patchVersion + ""; | 
|---|
| 249 | UtilXmlTools::displayErrorMessage("@XML_TOOLS",errMessage); | 
|---|
| 250 | } | 
|---|
| 251 | break; // We have got what we wanted | 
|---|
| 252 | } | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 | if(patchVersion==""){ | 
|---|
| 256 | UtilXmlTools::displayErrorMessage("@XML_TOOLS","Patch version not found."); | 
|---|
| 257 | } | 
|---|
| 258 |  | 
|---|
| 259 | } | 
|---|
| 260 |  | 
|---|
| 261 | void XmlPatch::checkAndProcessValidCommands(QTextStream &fileStream){ | 
|---|
| 262 |  | 
|---|
| 263 | QString line, filesWildcard; | 
|---|
| 264 | QString xmlToInsert, command, jsCode; | 
|---|
| 265 | QString xPathExpression; | 
|---|
| 266 | XmlFilter filters; | 
|---|
| 267 |  | 
|---|
| 268 | // Process the rest of the commands in patch file | 
|---|
| 269 | while ( !fileStream.atEnd() ){ | 
|---|
| 270 | line = fileStream.readLine(); | 
|---|
| 271 |  | 
|---|
| 272 | if(line.startsWith('#')){ // Ignore comments | 
|---|
| 273 | continue; | 
|---|
| 274 | } | 
|---|
| 275 | else if(line.startsWith("@ADD_INSIDE_NODES")){ | 
|---|
| 276 | xPathExpression=getPatchParameterValue(line,"XPathExpression"); | 
|---|
| 277 | filters.setElementName(getPatchParameterValue(line,"ElementName")); | 
|---|
| 278 | filters.setParentElementName(getPatchParameterValue(line,"ParentElementName")); | 
|---|
| 279 | filters.setAttributeName(getPatchParameterValue(line,"AttributeName")); | 
|---|
| 280 | filters.setAttributeValue(getPatchParameterValue(line,"AttributeValue")); | 
|---|
| 281 |  | 
|---|
| 282 | if(this->forceTargetFilesWildcard!=""){ | 
|---|
| 283 | filesWildcard=this->forceTargetFilesWildcard; | 
|---|
| 284 | } | 
|---|
| 285 | else{ | 
|---|
| 286 | filesWildcard=getPatchParameterValue(line,"Files"); | 
|---|
| 287 | } | 
|---|
| 288 |  | 
|---|
| 289 | // Check options | 
|---|
| 290 | if(xPathExpression.isEmpty() && filters.getElementName().isEmpty()){ | 
|---|
| 291 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES","ElementName option or XPathExpression option is required."); | 
|---|
| 292 | } | 
|---|
| 293 | else if(!xPathExpression.isEmpty() && !filters.getElementName().isEmpty()){ | 
|---|
| 294 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES","ElementName option and XPathExpression option cannot be used simultaneously."); | 
|---|
| 295 | } | 
|---|
| 296 | if(filters.getAttributeName()!="" && filters.getAttributeValue()==""){ | 
|---|
| 297 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES","AttributeValue option is required if using AttributeName option."); | 
|---|
| 298 | } | 
|---|
| 299 |  | 
|---|
| 300 | if(filters.getAttributeValue()!="" && filters.getAttributeName()==""){ | 
|---|
| 301 | UtilXmlTools::displayErrorMessage("@ADD_INSIDE_NODES","AttributeName option is required if using AttributeValue option."); | 
|---|
| 302 | } | 
|---|
| 303 |  | 
|---|
| 304 | while ( !fileStream.atEnd() && !line.startsWith("</xml>")){ | 
|---|
| 305 | line = fileStream.readLine(); | 
|---|
| 306 |  | 
|---|
| 307 | if(!line.startsWith("<xml>") && !line.startsWith("</xml>")){ | 
|---|
| 308 | xmlToInsert += line + "\n"; | 
|---|
| 309 | } | 
|---|
| 310 | } | 
|---|
| 311 |  | 
|---|
| 312 | insertNodesOperation(xmlToInsert,filters,xPathExpression,filesWildcard); | 
|---|
| 313 |  | 
|---|
| 314 | xmlToInsert.clear(); | 
|---|
| 315 | filters.clear(); | 
|---|
| 316 | xPathExpression.clear(); | 
|---|
| 317 | filesWildcard.clear(); | 
|---|
| 318 | } | 
|---|
| 319 | else if(line.startsWith("@REMOVE_NODES")){ | 
|---|
| 320 |  | 
|---|
| 321 | xPathExpression=getPatchParameterValue(line,"XPathExpression"); | 
|---|
| 322 | filters.setElementName(getPatchParameterValue(line,"ElementName")); | 
|---|
| 323 | filters.setParentElementName(getPatchParameterValue(line,"ParentElementName")); | 
|---|
| 324 | filters.setAttributeName(getPatchParameterValue(line,"AttributeName")); | 
|---|
| 325 | filters.setAttributeValue(getPatchParameterValue(line,"AttributeValue")); | 
|---|
| 326 |  | 
|---|
| 327 | if(this->forceTargetFilesWildcard!=""){ | 
|---|
| 328 | filesWildcard=this->forceTargetFilesWildcard; | 
|---|
| 329 | } | 
|---|
| 330 | else{ | 
|---|
| 331 | filesWildcard=getPatchParameterValue(line,"Files"); | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 | // Check options | 
|---|
| 335 | if(xPathExpression.isEmpty() && filters.getElementName().isEmpty()){ | 
|---|
| 336 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES","ElementName option or XPathExpression option is required."); | 
|---|
| 337 | } | 
|---|
| 338 | else if(!xPathExpression.isEmpty() && !filters.getElementName().isEmpty()){ | 
|---|
| 339 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES","ElementName option and XPathExpression option cannot be used simultaneously."); | 
|---|
| 340 | } | 
|---|
| 341 |  | 
|---|
| 342 | if(filters.getAttributeName()!="" && filters.getAttributeValue()==""){ | 
|---|
| 343 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES","AttributeValue option is required if using AttributeName option."); | 
|---|
| 344 | } | 
|---|
| 345 |  | 
|---|
| 346 | if(filters.getAttributeValue()!="" && filters.getAttributeName()==""){ | 
|---|
| 347 | UtilXmlTools::displayErrorMessage("@REMOVE_NODES","AttributeName option is required if using AttributeValue option."); | 
|---|
| 348 | } | 
|---|
| 349 |  | 
|---|
| 350 | removeNodesOperation(filters,xPathExpression,filesWildcard); | 
|---|
| 351 |  | 
|---|
| 352 | filters.clear(); | 
|---|
| 353 | xPathExpression.clear(); | 
|---|
| 354 | filesWildcard.clear(); | 
|---|
| 355 | } | 
|---|
| 356 | else if(line.startsWith("@COMMAND")){ | 
|---|
| 357 |  | 
|---|
| 358 | command=GlobalVars::AppExecutable; | 
|---|
| 359 |  | 
|---|
| 360 | // Append files if forced to | 
|---|
| 361 | if(!this->forceTargetFilesWildcard.isEmpty()){ | 
|---|
| 362 | command+=" --files '"+this->forceTargetFilesWildcard+"' "; | 
|---|
| 363 | } | 
|---|
| 364 |  | 
|---|
| 365 | command+=" "+getPatchParameterValue(line,"Options"); | 
|---|
| 366 |  | 
|---|
| 367 | // Add --no-backups and --no-verbose if patch was called with that arguments | 
|---|
| 368 | if(!this->backupsEnabled){ | 
|---|
| 369 | command.append(" --no-backups "); | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | if(!this->verboseEnabled){ | 
|---|
| 373 | command.append(" --no-verbose "); | 
|---|
| 374 | } | 
|---|
| 375 |  | 
|---|
| 376 | command.replace("'","\""); //replace apostrophe by quotes, to avoid problems | 
|---|
| 377 | command.replace("\"\"","'"); // this allow to use '' as ' ('' is transformed in "" and then in ') | 
|---|
| 378 |  | 
|---|
| 379 | executeCommandOperation(command); | 
|---|
| 380 |  | 
|---|
| 381 | command.clear(); | 
|---|
| 382 | filesWildcard.clear(); | 
|---|
| 383 | } | 
|---|
| 384 | else if(line.startsWith("@CUSTOM_CODE")){ | 
|---|
| 385 |  | 
|---|
| 386 | if(this->forceTargetFilesWildcard!=""){ | 
|---|
| 387 | filesWildcard=this->forceTargetFilesWildcard; | 
|---|
| 388 | } | 
|---|
| 389 | else{ | 
|---|
| 390 | filesWildcard=getPatchParameterValue(line,"Files"); | 
|---|
| 391 | } | 
|---|
| 392 |  | 
|---|
| 393 | while ( !fileStream.atEnd() && !line.startsWith("</code>")){ | 
|---|
| 394 |  | 
|---|
| 395 | line = fileStream.readLine(); | 
|---|
| 396 |  | 
|---|
| 397 | if(!line.startsWith("<code>") && !line.startsWith("</code>")){ | 
|---|
| 398 | jsCode += line + "\n"; | 
|---|
| 399 | } | 
|---|
| 400 | } | 
|---|
| 401 |  | 
|---|
| 402 | executeCustomCommandOperation(jsCode,filesWildcard); | 
|---|
| 403 |  | 
|---|
| 404 | jsCode.clear(); | 
|---|
| 405 | filesWildcard.clear(); | 
|---|
| 406 | } | 
|---|
| 407 | } | 
|---|
| 408 | } | 
|---|
| 409 |  | 
|---|
| 410 | QString XmlPatch::getPatchParameterValue(const QString& line, QString parameter){ | 
|---|
| 411 |  | 
|---|
| 412 | int startValueIdx, endValueIdx; | 
|---|
| 413 |  | 
|---|
| 414 | parameter=" "+parameter+" "; // Parameters include a space before and after it's value. | 
|---|
| 415 |  | 
|---|
| 416 | if(!line.contains(parameter)){ | 
|---|
| 417 | if(parameter==" ParentElementName " || parameter==" AttributeName " || parameter==" AttributeValue " | 
|---|
| 418 | || parameter==" ElementName " || parameter==" XPathExpression "){ | 
|---|
| 419 | return ""; // not mandatory | 
|---|
| 420 | } | 
|---|
| 421 | parameter.remove(" "); // just remove the space added so it doesn't look weird when outputted to the user | 
|---|
| 422 |  | 
|---|
| 423 | UtilXmlTools::displayErrorMessage("Read patch file parameter","Couldn't retrieve '" + parameter + "' parameter."); | 
|---|
| 424 | } | 
|---|
| 425 |  | 
|---|
| 426 | startValueIdx=line.indexOf(parameter); // get the position where parameter is defined | 
|---|
| 427 | endValueIdx=line.indexOf("\"",startValueIdx)+1; // get the position where parameter value begins (+1 to ignore mandotory quote) | 
|---|
| 428 |  | 
|---|
| 429 | startValueIdx=endValueIdx; | 
|---|
| 430 | endValueIdx=line.indexOf("\"",startValueIdx); // get the last mandatory quote of the value | 
|---|
| 431 |  | 
|---|
| 432 | return line.mid(startValueIdx,endValueIdx-startValueIdx); // return the value of the parameter (is in the middle of the mandatory quotes) | 
|---|
| 433 | } | 
|---|