--- xmlTools/trunk/posUpdate/XmlPatch.cs 2013/05/10 14:42:11 868 +++ xmlTools/trunk/posUpdate/XmlPatch.cs 2013/05/25 21:53:39 874 @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Text; using System.Xml; +using IronJS; namespace xmlTools { @@ -14,6 +16,7 @@ namespace xmlTools String fileName; String forceFiles = ""; bool globalNoBackups = false; + IronJS.Hosting.CSharp.Context jsEngine = null; // initialize only when necessary public XmlPatch(String file, bool noBackups) { @@ -49,7 +52,7 @@ namespace xmlTools file.ReadLine(); //ignore start header while ((line = file.ReadLine()) != "") { - xmlToInject += line + "\n"; //get all the xml that will be injected + xmlToInject += line + System.Environment.NewLine; //get all the xml that will be injected } if (!addOperation(operation, xmlToInject)) { @@ -73,6 +76,22 @@ namespace xmlTools return false; } } + else if (line.StartsWith("@CUSTOMCODE ")) + { + string operation = line; + string jsCode = ""; + + file.ReadLine(); //ignore start header + while ((line = file.ReadLine()) != "") + { + jsCode += line + System.Environment.NewLine; //get all the xml that will be injected + } + if (!executeCode(operation, jsCode)) + { + Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error while performing code operation in patch file. Aborting..."); + return false; + } + } } file.Close(); @@ -90,23 +109,23 @@ namespace xmlTools { //@ADDTO File "example.xml" ParentElement "Animation" Element "Lookup" - string File = "", ParentElement = "", Element = ""; + string FileParam = "", ParentElementParam = "", ElementParam = ""; //---------------------------------------------------Parse Operation command (start) try { if (String.IsNullOrEmpty(forceFiles)) { - File = getPatchParameter(operation, "File"); + FileParam = getPatchParameter(operation, "File"); } else { - File = forceFiles; + FileParam = forceFiles; } - ParentElement = getPatchParameter(operation, "ParentElement"); //Get the ParentElement + ParentElementParam = getPatchParameter(operation, "ParentElement"); //Get the ParentElement - Element = getPatchParameter(operation, "Element"); //Get the Element + ElementParam = getPatchParameter(operation, "Element"); //Get the Element } catch (Exception e) { @@ -114,24 +133,24 @@ namespace xmlTools return false; } - if (String.IsNullOrEmpty(Element)) + if (String.IsNullOrEmpty(ElementParam)) { return false; } //---------------------------------------------------Parse Operation command (end) List filesToProcess = new List(); - if (String.IsNullOrEmpty(File)) + if (String.IsNullOrEmpty(FileParam)) { filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder } - else if (Util.containsWildcard(File)) + else if (Util.containsWildcard(FileParam)) { - filesToProcess = Util.getXmlFilesWildcard(File); + filesToProcess = Util.getXmlFilesWildcard(FileParam); } else { - filesToProcess.Add(File); + filesToProcess.Add(FileParam); } //---------------------------------------------------XML Injection (start) @@ -146,7 +165,7 @@ namespace xmlTools xdoc.Load(currFile); List myElements = new List(); - Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, Element, ParentElement); //Returns all after "Oni" element + Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, ElementParam, ParentElementParam); //Returns all after "Oni" element if (myElements.Count == 0) { @@ -182,23 +201,23 @@ namespace xmlTools { //@REMOVE File "example.xml" ParentElement "Particles" Element "Particle" - string File = "", ParentElement = "", Element = ""; + string FileParam = "", ParentElementParam = "", ElementParam = ""; //---------------------------------------------------Parse Operation command (start) try { if (String.IsNullOrEmpty(forceFiles)) { - File = getPatchParameter(operation, "File"); + FileParam = getPatchParameter(operation, "File"); } else { - File = forceFiles; + FileParam = forceFiles; } - ParentElement = getPatchParameter(operation, "ParentElement"); //Get the ParentElement + ParentElementParam = getPatchParameter(operation, "ParentElement"); //Get the ParentElement - Element = getPatchParameter(operation, "Element"); //Get the Element + ElementParam = getPatchParameter(operation, "Element"); //Get the Element } catch (Exception e) { @@ -206,7 +225,7 @@ namespace xmlTools return false; } - if (String.IsNullOrEmpty(Element)) + if (String.IsNullOrEmpty(ElementParam)) { return false; } @@ -214,17 +233,17 @@ namespace xmlTools //---------------------------------------------------Parse Operation command (end) List filesToProcess = new List(); - if (String.IsNullOrEmpty(File)) + if (String.IsNullOrEmpty(FileParam)) { filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder } - else if (Util.containsWildcard(File)) + else if (Util.containsWildcard(FileParam)) { - filesToProcess = Util.getXmlFilesWildcard(File); + filesToProcess = Util.getXmlFilesWildcard(FileParam); } else { - filesToProcess.Add(File); + filesToProcess.Add(FileParam); } //---------------------------------------------------XML Remove (start) @@ -241,7 +260,7 @@ namespace xmlTools xdoc.Load(currFile); List myElements = new List(); - Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, Element, ParentElement); //Returns all after "Oni" element + Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, ElementParam, ParentElementParam); //Returns all after "Oni" element if (myElements.Count == 0) { @@ -261,7 +280,7 @@ namespace xmlTools } /// - /// + /// Executes a command for xmlTools /// /// /// true or false depending if succeed or not @@ -284,7 +303,7 @@ namespace xmlTools string paramType = ""; // Filename already exists? - if (Util.ContainsIgnoreCase(command,"filename:")) + if (Util.ContainsIgnoreCase(command, "filename:")) { paramType = "filename:"; } @@ -295,7 +314,7 @@ namespace xmlTools // Add the filename if it doesn't exists else { - command = command.Insert(command.Length," -filename:" + this.forceFiles); + command = command.Insert(command.Length, " -filename:" + this.forceFiles); } if (!String.IsNullOrEmpty(paramType)) @@ -305,8 +324,9 @@ namespace xmlTools if (endIdx == -1) { endIdx = command.IndexOf("\n", startIdx); // or with endline - if(endIdx==-1){ // Filename parameters is the last one in the file (file ends with this parameter) - endIdx=command.Length-1; + if (endIdx == -1) + { // Filename parameters is the last one in the file (file ends with this parameter) + endIdx = command.Length - 1; } } string currFilename = command.Substring(startIdx, endIdx - startIdx); @@ -315,7 +335,7 @@ namespace xmlTools } - if (this.globalNoBackups && !Util.ContainsIgnoreCase(command,"nobackups")) // add noBackup flag if provided as global parameter + if (this.globalNoBackups && !Util.ContainsIgnoreCase(command, "nobackups")) // add noBackup flag if provided as global parameter { command = command.Insert(command.Length, " -nobackups"); } @@ -330,6 +350,110 @@ namespace xmlTools return true; } + + /// + /// Executes custom Javascript code over the xml file specified. Uses .NET JINT library. + /// + /// + /// + private bool executeCode(string operation, string jsCode) + { + string FileParam = ""; + + //---------------------------------------------------Parse Operation command (start) + try + { + if (String.IsNullOrEmpty(forceFiles)) + { + FileParam = getPatchParameter(operation, "File"); + } + else + { + FileParam = forceFiles; + } + + } + catch (Exception e) + { + Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error parsing codeOperation in Patch file.\n" + e.ToString()); + return false; + } + + //---------------------------------------------------Parse Operation command (end) + List filesToProcess = new List(); + if (String.IsNullOrEmpty(FileParam)) + { + filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder + } + else if (Util.containsWildcard(FileParam)) + { + filesToProcess = Util.getXmlFilesWildcard(FileParam); + } + else + { + filesToProcess.Add(FileParam); + } + + //---------------------------------------------------JS Code Proccess (start) + foreach (String currXMLFile in filesToProcess) + { + if (!this.globalNoBackups && !Util.ContainsIgnoreCase(operation, "NoBackups")) // only skip backup if specified via global parameter or in patch file + { + Util.backupFile(currXMLFile); + } + + string xmlFileContent = File.ReadAllText(currXMLFile); + + // Initialize Jint Engine + if (jsEngine == null) + { + jsEngine = new IronJS.Hosting.CSharp.Context(); + + // Load XML libraries + jsEngine.Execute(xmlTools.Properties.Resources.tinyxmlsax); + jsEngine.Execute(xmlTools.Properties.Resources.tinyxmlw3cdom); + } + + // Construct code to execute + StringBuilder sourceCode = new StringBuilder(); + + // give user the xml we needs to edit... + sourceCode.Append("var $xmlData='").Append(xmlFileContent.Replace(System.Environment.NewLine, " \\" + System.Environment.NewLine)).Append("';").AppendLine(); // replace is for multine string in javascript (http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript) + // append the user js code... + sourceCode.Append(jsCode).AppendLine(); + // return to .NET the new xml data + sourceCode.Append("$xmlData;"); + + try + { + xmlFileContent = jsEngine.Execute(sourceCode.ToString()).ToString(); + } + catch (Exception e) + { + Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error parsing code in customCodeOperation in Patch file.\n" + e.ToString()); + return false; + } + + // Let's see if the returned result is valid xml... + try + { + XmlDocument xmlDoc = new XmlDocument(); + + xmlDoc.LoadXml(xmlFileContent); + + xmlDoc.Save(currXMLFile); //saving the new xml with this method will auto ident it. + + } + catch (Exception e) + { + Program.printAppError(Program.appErrors.PATCH_CODE_PARSE_XML_OUTPUT_ERROR, "Error parsing result xml to customCodeOperation in Patch file.\n" + e.ToString()); + return false; + } + } + //---------------------------------------------------JS Code Proccess (end) + + return true; + } private string getPatchParameter(string line, string parameterName) {