| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 | using System.Diagnostics; | 
 
 
 
 
 | 4 | using System.IO; | 
 
 
 
 
 | 5 | using System.Text; | 
 
 
 
 
 | 6 | using System.Xml; | 
 
 
 
 
 | 7 | using IronJS; | 
 
 
 
 
 | 8 |  | 
 
 
 
 
 | 9 | namespace xmlTools | 
 
 
 
 
 | 10 | { | 
 
 
 
 
 | 11 | /// <summary> | 
 
 
 
 
 | 12 | /// This classes parses a .patch xml tools file and applies its content to the files which it specifies | 
 
 
 
 
 | 13 | /// </summary> | 
 
 
 
 
 | 14 | class XmlPatch | 
 
 
 
 
 | 15 | { | 
 
 
 
 
 | 16 | String fileName; | 
 
 
 
 
 | 17 | String forceFiles = ""; | 
 
 
 
 
 | 18 | bool globalNoBackups = false; | 
 
 
 
 
 | 19 | IronJS.Hosting.CSharp.Context jsEngine = null; // initialize only when necessary | 
 
 
 
 
 | 20 |  | 
 
 
 
 
 | 21 | public XmlPatch(String file, bool noBackups) | 
 
 
 
 
 | 22 | { | 
 
 
 
 
 | 23 | fileName = file; | 
 
 
 
 
 | 24 | globalNoBackups = noBackups; | 
 
 
 
 
 | 25 | } | 
 
 
 
 
 | 26 |  | 
 
 
 
 
 | 27 | public XmlPatch(String file, String forceInFiles, bool noBackups) | 
 
 
 
 
 | 28 | { | 
 
 
 
 
 | 29 | fileName = file; | 
 
 
 
 
 | 30 | forceFiles = forceInFiles; //We support apply the operation in diverse forced files (NameOfFile parameter will be ignored) | 
 
 
 
 
 | 31 | globalNoBackups = noBackups; | 
 
 
 
 
 | 32 | } | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | /// <summary> | 
 
 
 
 
 | 35 | /// Applies the patch file. Returns true if successful otherwise returns false. | 
 
 
 
 
 | 36 | /// </summary> | 
 
 
 
 
 | 37 | /// <returns></returns> | 
 
 
 
 
 | 38 | public bool startPatch() | 
 
 
 
 
 | 39 | { | 
 
 
 
 
 | 40 | string line; | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | // Read the file and display it line by line. | 
 
 
 
 
 | 43 | System.IO.StreamReader file = new System.IO.StreamReader(fileName); | 
 
 
 
 
 | 44 |  | 
 
 
 
 
 | 45 | while ((line = file.ReadLine()) != null) //read while we don't reach the end of the file | 
 
 
 
 
 | 46 | { | 
 
 
 
 
 | 47 | if (line.StartsWith("@ADDTO ")) | 
 
 
 
 
 | 48 | { | 
 
 
 
 
 | 49 | string operation = line; | 
 
 
 
 
 | 50 | string xmlToInject = ""; | 
 
 
 
 
 | 51 |  | 
 
 
 
 
 | 52 | file.ReadLine(); //ignore <xml> start header | 
 
 
 
 
 | 53 | while ((line = file.ReadLine()) != "</xml>") | 
 
 
 
 
 | 54 | { | 
 
 
 
 
 | 55 | xmlToInject += line + System.Environment.NewLine; //get all the xml that will be injected | 
 
 
 
 
 | 56 | } | 
 
 
 
 
 | 57 | if (!addOperation(operation, xmlToInject)) | 
 
 
 
 
 | 58 | { | 
 
 
 
 
 | 59 | Program.printAppError(Program.appErrors.PATCH_ADDTO_PROCESS_ERROR, "Error while performing adding operation in patch file. Aborting..."); | 
 
 
 
 
 | 60 | return false; | 
 
 
 
 
 | 61 | } | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 | else if (line.StartsWith("@REMOVE ")) | 
 
 
 
 
 | 64 | { | 
 
 
 
 
 | 65 | if (!removeOperation(line)) | 
 
 
 
 
 | 66 | { | 
 
 
 
 
 | 67 | Program.printAppError(Program.appErrors.PATCH_REMOVE_PROCESS_ERROR, "Error while performing remove operation in patch file. Aborting..."); | 
 
 
 
 
 | 68 | return false; | 
 
 
 
 
 | 69 | } | 
 
 
 
 
 | 70 | } | 
 
 
 
 
 | 71 | else if (line.StartsWith("@COMMAND ")) | 
 
 
 
 
 | 72 | { | 
 
 
 
 
 | 73 | if (!executeCommand(line)) | 
 
 
 
 
 | 74 | { | 
 
 
 
 
 | 75 | Program.printAppError(Program.appErrors.PATCH_COMMAND_PROCESS_ERROR, "Error while performing command operation in patch file. Aborting..."); | 
 
 
 
 
 | 76 | return false; | 
 
 
 
 
 | 77 | } | 
 
 
 
 
 | 78 | } | 
 
 
 
 
 | 79 | else if (line.StartsWith("@CUSTOMCODE ")) | 
 
 
 
 
 | 80 | { | 
 
 
 
 
 | 81 | string operation = line; | 
 
 
 
 
 | 82 | string jsCode = ""; | 
 
 
 
 
 | 83 |  | 
 
 
 
 
 | 84 | file.ReadLine(); //ignore <xml> start header | 
 
 
 
 
 | 85 | while ((line = file.ReadLine()) != "</code>") | 
 
 
 
 
 | 86 | { | 
 
 
 
 
 | 87 | jsCode += line + System.Environment.NewLine; //get all the xml that will be injected | 
 
 
 
 
 | 88 | } | 
 
 
 
 
 | 89 | if (!executeCode(operation, jsCode)) | 
 
 
 
 
 | 90 | { | 
 
 
 
 
 | 91 | Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error while performing code operation in patch file. Aborting..."); | 
 
 
 
 
 | 92 | return false; | 
 
 
 
 
 | 93 | } | 
 
 
 
 
 | 94 | } | 
 
 
 
 
 | 95 | } | 
 
 
 
 
 | 96 |  | 
 
 
 
 
 | 97 | file.Close(); | 
 
 
 
 
 | 98 |  | 
 
 
 
 
 | 99 | return true; | 
 
 
 
 
 | 100 | } | 
 
 
 
 
 | 101 |  | 
 
 
 
 
 | 102 | /// <summary> | 
 
 
 
 
 | 103 | /// Inserts xml in a desired Element. Returns true or false if it succeeds | 
 
 
 
 
 | 104 | /// </summary> | 
 
 
 
 
 | 105 | /// <param name="operation"></param> | 
 
 
 
 
 | 106 | /// <param name="xmlToInject"></param> | 
 
 
 
 
 | 107 | /// <returns></returns> | 
 
 
 
 
 | 108 | private bool addOperation(string operation, string xmlToInject) | 
 
 
 
 
 | 109 | { | 
 
 
 
 
 | 110 | //@ADDTO File "example.xml" ParentElement "Animation" Element "Lookup" | 
 
 
 
 
 | 111 |  | 
 
 
 
 
 | 112 | string FileParam = "", ParentElementParam = "", ElementParam = ""; | 
 
 
 
 
 | 113 |  | 
 
 
 
 
 | 114 | //---------------------------------------------------Parse Operation command (start) | 
 
 
 
 
 | 115 | try | 
 
 
 
 
 | 116 | { | 
 
 
 
 
 | 117 | if (String.IsNullOrEmpty(forceFiles)) | 
 
 
 
 
 | 118 | { | 
 
 
 
 
 | 119 | FileParam = getPatchParameter(operation, "File"); | 
 
 
 
 
 | 120 | } | 
 
 
 
 
 | 121 | else | 
 
 
 
 
 | 122 | { | 
 
 
 
 
 | 123 | FileParam = forceFiles; | 
 
 
 
 
 | 124 | } | 
 
 
 
 
 | 125 |  | 
 
 
 
 
 | 126 | ParentElementParam = getPatchParameter(operation, "ParentElement"); //Get the ParentElement | 
 
 
 
 
 | 127 |  | 
 
 
 
 
 | 128 | ElementParam = getPatchParameter(operation, "Element"); //Get the Element | 
 
 
 
 
 | 129 | } | 
 
 
 
 
 | 130 | catch (Exception e) | 
 
 
 
 
 | 131 | { | 
 
 
 
 
 | 132 | Program.printAppError(Program.appErrors.PATCH_ADDTO_ERROR_PARSING_XML, "Error parsing addOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 133 | return false; | 
 
 
 
 
 | 134 | } | 
 
 
 
 
 | 135 |  | 
 
 
 
 
 | 136 | if (String.IsNullOrEmpty(ElementParam)) | 
 
 
 
 
 | 137 | { | 
 
 
 
 
 | 138 | return false; | 
 
 
 
 
 | 139 | } | 
 
 
 
 
 | 140 |  | 
 
 
 
 
 | 141 | //---------------------------------------------------Parse Operation command (end) | 
 
 
 
 
 | 142 | List<String> filesToProcess = new List<String>(); | 
 
 
 
 
 | 143 | if (String.IsNullOrEmpty(FileParam)) | 
 
 
 
 
 | 144 | { | 
 
 
 
 
 | 145 | filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder | 
 
 
 
 
 | 146 | } | 
 
 
 
 
 | 147 | else if (Util.containsWildcard(FileParam)) | 
 
 
 
 
 | 148 | { | 
 
 
 
 
 | 149 | filesToProcess = Util.getXmlFilesWildcard(FileParam); | 
 
 
 
 
 | 150 | } | 
 
 
 
 
 | 151 | else | 
 
 
 
 
 | 152 | { | 
 
 
 
 
 | 153 | filesToProcess.Add(FileParam); | 
 
 
 
 
 | 154 | } | 
 
 
 
 
 | 155 |  | 
 
 
 
 
 | 156 | //---------------------------------------------------XML Injection (start) | 
 
 
 
 
 | 157 | foreach (String currFile in filesToProcess) | 
 
 
 
 
 | 158 | { | 
 
 
 
 
 | 159 | if (!this.globalNoBackups && !Util.ContainsIgnoreCase(operation, "NoBackups")) // only skip backup if specified via global parameter or in patch file | 
 
 
 
 
 | 160 | { | 
 
 
 
 
 | 161 | Util.backupFile(currFile); | 
 
 
 
 
 | 162 | } | 
 
 
 
 
 | 163 |  | 
 
 
 
 
 | 164 | XmlDocument xdoc = new XmlDocument(); | 
 
 
 
 
 | 165 | xdoc.Load(currFile); | 
 
 
 
 
 | 166 |  | 
 
 
 
 
 | 167 | List<XmlNode> myElements = new List<XmlNode>(); | 
 
 
 
 
 | 168 | Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, ElementParam, ParentElementParam); //Returns all after "Oni" element | 
 
 
 
 
 | 169 |  | 
 
 
 
 
 | 170 | if (myElements.Count == 0) | 
 
 
 
 
 | 171 | { | 
 
 
 
 
 | 172 | Program.printAppError(Program.appErrors.PATCH_ELEMENT_NOT_FOUND, "Error in addOperation in Patch file: the element specified doesn't exist."); | 
 
 
 
 
 | 173 | return false; | 
 
 
 
 
 | 174 | } | 
 
 
 
 
 | 175 |  | 
 
 
 
 
 | 176 | try | 
 
 
 
 
 | 177 | { | 
 
 
 
 
 | 178 | XmlNode newXml = xdoc.ImportNode(Util.stringToXmlNode(xmlToInject), true); //necessary to import node or ArgumentException will be thrown when appending | 
 
 
 
 
 | 179 |  | 
 
 
 
 
 | 180 | myElements[myElements.Count - 1].AppendChild(newXml); // Append the code after last element | 
 
 
 
 
 | 181 |  | 
 
 
 
 
 | 182 | xdoc.Save(currFile); | 
 
 
 
 
 | 183 | } | 
 
 
 
 
 | 184 | catch (XmlException e) | 
 
 
 
 
 | 185 | { | 
 
 
 
 
 | 186 | Program.printAppError(Program.appErrors.PATCH_ADDTO_ERROR_PARSING_XML, "Error parsing xml to addOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 187 | return false; | 
 
 
 
 
 | 188 | } | 
 
 
 
 
 | 189 | } | 
 
 
 
 
 | 190 | //---------------------------------------------------XML Injection (end) | 
 
 
 
 
 | 191 |  | 
 
 
 
 
 | 192 | return true; | 
 
 
 
 
 | 193 | } | 
 
 
 
 
 | 194 |  | 
 
 
 
 
 | 195 | /// <summary> | 
 
 
 
 
 | 196 | /// Removes a xml element, right now it removes the first element it finds with matchs "Element" and "ParentElement" parameters | 
 
 
 
 
 | 197 | /// </summary> | 
 
 
 
 
 | 198 | /// <param name="operation"></param> | 
 
 
 
 
 | 199 | /// <returns>true or false depending if succeed or not</returns> | 
 
 
 
 
 | 200 | private bool removeOperation(string operation) | 
 
 
 
 
 | 201 | { | 
 
 
 
 
 | 202 | //@REMOVE File "example.xml" ParentElement "Particles" Element "Particle" | 
 
 
 
 
 | 203 |  | 
 
 
 
 
 | 204 | string FileParam = "", ParentElementParam = "", ElementParam = ""; | 
 
 
 
 
 | 205 |  | 
 
 
 
 
 | 206 | //---------------------------------------------------Parse Operation command (start) | 
 
 
 
 
 | 207 | try | 
 
 
 
 
 | 208 | { | 
 
 
 
 
 | 209 | if (String.IsNullOrEmpty(forceFiles)) | 
 
 
 
 
 | 210 | { | 
 
 
 
 
 | 211 | FileParam = getPatchParameter(operation, "File"); | 
 
 
 
 
 | 212 | } | 
 
 
 
 
 | 213 | else | 
 
 
 
 
 | 214 | { | 
 
 
 
 
 | 215 | FileParam = forceFiles; | 
 
 
 
 
 | 216 | } | 
 
 
 
 
 | 217 |  | 
 
 
 
 
 | 218 | ParentElementParam = getPatchParameter(operation, "ParentElement"); //Get the ParentElement | 
 
 
 
 
 | 219 |  | 
 
 
 
 
 | 220 | ElementParam = getPatchParameter(operation, "Element"); //Get the Element | 
 
 
 
 
 | 221 | } | 
 
 
 
 
 | 222 | catch (Exception e) | 
 
 
 
 
 | 223 | { | 
 
 
 
 
 | 224 | Program.printAppError(Program.appErrors.PATCH_REMOVE_PROCESS_ERROR, "Error parsing removeOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 225 | return false; | 
 
 
 
 
 | 226 | } | 
 
 
 
 
 | 227 |  | 
 
 
 
 
 | 228 | if (String.IsNullOrEmpty(ElementParam)) | 
 
 
 
 
 | 229 | { | 
 
 
 
 
 | 230 | return false; | 
 
 
 
 
 | 231 | } | 
 
 
 
 
 | 232 |  | 
 
 
 
 
 | 233 | //---------------------------------------------------Parse Operation command (end) | 
 
 
 
 
 | 234 |  | 
 
 
 
 
 | 235 | List<String> filesToProcess = new List<String>(); | 
 
 
 
 
 | 236 | if (String.IsNullOrEmpty(FileParam)) | 
 
 
 
 
 | 237 | { | 
 
 
 
 
 | 238 | filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder | 
 
 
 
 
 | 239 | } | 
 
 
 
 
 | 240 | else if (Util.containsWildcard(FileParam)) | 
 
 
 
 
 | 241 | { | 
 
 
 
 
 | 242 | filesToProcess = Util.getXmlFilesWildcard(FileParam); | 
 
 
 
 
 | 243 | } | 
 
 
 
 
 | 244 | else | 
 
 
 
 
 | 245 | { | 
 
 
 
 
 | 246 | filesToProcess.Add(FileParam); | 
 
 
 
 
 | 247 | } | 
 
 
 
 
 | 248 |  | 
 
 
 
 
 | 249 | //---------------------------------------------------XML Remove (start) | 
 
 
 
 
 | 250 |  | 
 
 
 
 
 | 251 | foreach (String currFile in filesToProcess) | 
 
 
 
 
 | 252 | { | 
 
 
 
 
 | 253 |  | 
 
 
 
 
 | 254 | if (!this.globalNoBackups && !Util.ContainsIgnoreCase(operation, "NoBackups")) // only skip backup if specified via global parameter or in patch file | 
 
 
 
 
 | 255 | { | 
 
 
 
 
 | 256 | Util.backupFile(currFile); | 
 
 
 
 
 | 257 | } | 
 
 
 
 
 | 258 |  | 
 
 
 
 
 | 259 | XmlDocument xdoc = new XmlDocument(); | 
 
 
 
 
 | 260 | xdoc.Load(currFile); | 
 
 
 
 
 | 261 |  | 
 
 
 
 
 | 262 | List<XmlNode> myElements = new List<XmlNode>(); | 
 
 
 
 
 | 263 | Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, ElementParam, ParentElementParam); //Returns all after "Oni" element | 
 
 
 
 
 | 264 |  | 
 
 
 
 
 | 265 | if (myElements.Count == 0) | 
 
 
 
 
 | 266 | { | 
 
 
 
 
 | 267 | Program.printAppError(Program.appErrors.PATCH_ELEMENT_NOT_FOUND, "Error in removeOperation in Patch file: the element specified doesn't exist."); | 
 
 
 
 
 | 268 | return false; | 
 
 
 
 
 | 269 | } | 
 
 
 
 
 | 270 |  | 
 
 
 
 
 | 271 | myElements[0].ParentNode.RemoveChild(myElements[0]); // Removes the first occurrence which matches the "Element" and "ParentElement" given | 
 
 
 
 
 | 272 |  | 
 
 
 
 
 | 273 | xdoc.Save(currFile); | 
 
 
 
 
 | 274 |  | 
 
 
 
 
 | 275 | } | 
 
 
 
 
 | 276 | //---------------------------------------------------XML Remove (end) | 
 
 
 
 
 | 277 |  | 
 
 
 
 
 | 278 |  | 
 
 
 
 
 | 279 | return true; | 
 
 
 
 
 | 280 | } | 
 
 
 
 
 | 281 |  | 
 
 
 
 
 | 282 | /// <summary> | 
 
 
 
 
 | 283 | ///  Executes a command for xmlTools | 
 
 
 
 
 | 284 | /// </summary> | 
 
 
 
 
 | 285 | /// <param name="command"></param> | 
 
 
 
 
 | 286 | /// <returns>true or false depending if succeed or not</returns> | 
 
 
 
 
 | 287 | private bool executeCommand(string command) | 
 
 
 
 
 | 288 | { | 
 
 
 
 
 | 289 | //---------------------------------------------------Parse Operation command (start) | 
 
 
 
 
 | 290 |  | 
 
 
 
 
 | 291 | command = command.Replace("@COMMAND ", ""); //get only the command to process | 
 
 
 
 
 | 292 |  | 
 
 
 
 
 | 293 | if (String.IsNullOrEmpty(command.Trim())) | 
 
 
 
 
 | 294 | { | 
 
 
 
 
 | 295 | Program.printAppError(Program.appErrors.PATCH_COMMAND_NOT_FOUND, "Error parsing commandOperation in Patch file: Command is empty."); | 
 
 
 
 
 | 296 | return false; | 
 
 
 
 
 | 297 | } | 
 
 
 
 
 | 298 |  | 
 
 
 
 
 | 299 | try | 
 
 
 
 
 | 300 | { | 
 
 
 
 
 | 301 | if (!String.IsNullOrEmpty(forceFiles)) | 
 
 
 
 
 | 302 | { | 
 
 
 
 
 | 303 | string paramType = ""; | 
 
 
 
 
 | 304 |  | 
 
 
 
 
 | 305 | // Filename already exists? | 
 
 
 
 
 | 306 | if (Util.ContainsIgnoreCase(command, "filename:")) | 
 
 
 
 
 | 307 | { | 
 
 
 
 
 | 308 | paramType = "filename:"; | 
 
 
 
 
 | 309 | } | 
 
 
 
 
 | 310 | else if (Util.ContainsIgnoreCase(command, "filename=")) | 
 
 
 
 
 | 311 | { | 
 
 
 
 
 | 312 | paramType = "filename="; | 
 
 
 
 
 | 313 | } | 
 
 
 
 
 | 314 | // Add the filename if it doesn't exists | 
 
 
 
 
 | 315 | else | 
 
 
 
 
 | 316 | { | 
 
 
 
 
 | 317 | command = command.Insert(command.Length, " -filename:" + this.forceFiles); | 
 
 
 
 
 | 318 | } | 
 
 
 
 
 | 319 |  | 
 
 
 
 
 | 320 | if (!String.IsNullOrEmpty(paramType)) | 
 
 
 
 
 | 321 | { | 
 
 
 
 
 | 322 | int startIdx = command.IndexOf(paramType) + paramType.Length; | 
 
 
 
 
 | 323 | int endIdx = command.IndexOf(" ", startIdx); // it may end with space | 
 
 
 
 
 | 324 | if (endIdx == -1) | 
 
 
 
 
 | 325 | { | 
 
 
 
 
 | 326 | endIdx = command.IndexOf("\n", startIdx); // or with endline | 
 
 
 
 
 | 327 | if (endIdx == -1) | 
 
 
 
 
 | 328 | { // Filename parameters is the last one in the file (file ends with this parameter) | 
 
 
 
 
 | 329 | endIdx = command.Length - 1; | 
 
 
 
 
 | 330 | } | 
 
 
 
 
 | 331 | } | 
 
 
 
 
 | 332 | string currFilename = command.Substring(startIdx, endIdx - startIdx); | 
 
 
 
 
 | 333 | command = command.Replace(currFilename, this.forceFiles); | 
 
 
 
 
 | 334 | } | 
 
 
 
 
 | 335 |  | 
 
 
 
 
 | 336 | } | 
 
 
 
 
 | 337 |  | 
 
 
 
 
 | 338 | if (this.globalNoBackups && !Util.ContainsIgnoreCase(command, "nobackups")) // add noBackup flag if provided as global parameter | 
 
 
 
 
 | 339 | { | 
 
 
 
 
 | 340 | command = command.Insert(command.Length, " -nobackups"); | 
 
 
 
 
 | 341 | } | 
 
 
 
 
 | 342 |  | 
 
 
 
 
 | 343 | Program.Main(Util.stringToArgsArray(command)); // use the current process is more efficient than start a new one | 
 
 
 
 
 | 344 | } | 
 
 
 
 
 | 345 | catch (Exception e) | 
 
 
 
 
 | 346 | { | 
 
 
 
 
 | 347 | Program.printAppError(Program.appErrors.PATCH_COMMAND_PROCESS_ERROR, "Error processing command in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 348 | return false; | 
 
 
 
 
 | 349 | } | 
 
 
 
 
 | 350 |  | 
 
 
 
 
 | 351 | return true; | 
 
 
 
 
 | 352 | } | 
 
 
 
 
 | 353 |  | 
 
 
 
 
 | 354 | /// <summary> | 
 
 
 
 
 | 355 | /// Executes custom Javascript code over the xml file specified. Uses .NET JINT library. | 
 
 
 
 
 | 356 | /// </summary> | 
 
 
 
 
 | 357 | /// <param name="command"></param> | 
 
 
 
 
 | 358 | /// <returns></returns> | 
 
 
 
 
 | 359 | private bool executeCode(string operation, string jsCode) | 
 
 
 
 
 | 360 | { | 
 
 
 
 
 | 361 | string FileParam = ""; | 
 
 
 
 
 | 362 |  | 
 
 
 
 
 | 363 | //---------------------------------------------------Parse Operation command (start) | 
 
 
 
 
 | 364 | try | 
 
 
 
 
 | 365 | { | 
 
 
 
 
 | 366 | if (String.IsNullOrEmpty(forceFiles)) | 
 
 
 
 
 | 367 | { | 
 
 
 
 
 | 368 | FileParam = getPatchParameter(operation, "File"); | 
 
 
 
 
 | 369 | } | 
 
 
 
 
 | 370 | else | 
 
 
 
 
 | 371 | { | 
 
 
 
 
 | 372 | FileParam = forceFiles; | 
 
 
 
 
 | 373 | } | 
 
 
 
 
 | 374 |  | 
 
 
 
 
 | 375 | } | 
 
 
 
 
 | 376 | catch (Exception e) | 
 
 
 
 
 | 377 | { | 
 
 
 
 
 | 378 | Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error parsing codeOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 379 | return false; | 
 
 
 
 
 | 380 | } | 
 
 
 
 
 | 381 |  | 
 
 
 
 
 | 382 | //---------------------------------------------------Parse Operation command (end) | 
 
 
 
 
 | 383 | List<String> filesToProcess = new List<String>(); | 
 
 
 
 
 | 384 | if (String.IsNullOrEmpty(FileParam)) | 
 
 
 
 
 | 385 | { | 
 
 
 
 
 | 386 | filesToProcess = Util.getAllXmlFiles(); //no file specified, use all xml files found in same folder | 
 
 
 
 
 | 387 | } | 
 
 
 
 
 | 388 | else if (Util.containsWildcard(FileParam)) | 
 
 
 
 
 | 389 | { | 
 
 
 
 
 | 390 | filesToProcess = Util.getXmlFilesWildcard(FileParam); | 
 
 
 
 
 | 391 | } | 
 
 
 
 
 | 392 | else | 
 
 
 
 
 | 393 | { | 
 
 
 
 
 | 394 | filesToProcess.Add(FileParam); | 
 
 
 
 
 | 395 | } | 
 
 
 
 
 | 396 |  | 
 
 
 
 
 | 397 | //---------------------------------------------------JS Code Proccess (start) | 
 
 
 
 
 | 398 | foreach (String currXMLFile in filesToProcess) | 
 
 
 
 
 | 399 | { | 
 
 
 
 
 | 400 | if (!this.globalNoBackups && !Util.ContainsIgnoreCase(operation, "NoBackups")) // only skip backup if specified via global parameter or in patch file | 
 
 
 
 
 | 401 | { | 
 
 
 
 
 | 402 | Util.backupFile(currXMLFile); | 
 
 
 
 
 | 403 | } | 
 
 
 
 
 | 404 |  | 
 
 
 
 
 | 405 | string xmlFileContent = File.ReadAllText(currXMLFile); | 
 
 
 
 
 | 406 |  | 
 
 
 
 
 | 407 | // Initialize Jint Engine | 
 
 
 
 
 | 408 | if (jsEngine == null) | 
 
 
 
 
 | 409 | { | 
 
 
 
 
 | 410 | jsEngine = new IronJS.Hosting.CSharp.Context(); | 
 
 
 
 
 | 411 |  | 
 
 
 
 
 | 412 | // Load XML libraries | 
 
 
 
 
 | 413 | jsEngine.Execute(xmlTools.Properties.Resources.tinyxmlsax); | 
 
 
 
 
 | 414 | jsEngine.Execute(xmlTools.Properties.Resources.tinyxmlw3cdom); | 
 
 
 
 
 | 415 | } | 
 
 
 
 
 | 416 |  | 
 
 
 
 
 | 417 | // Construct code to execute | 
 
 
 
 
 | 418 | StringBuilder sourceCode = new StringBuilder(); | 
 
 
 
 
 | 419 |  | 
 
 
 
 
 | 420 | // give user the xml we needs to edit... | 
 
 
 
 
 | 421 | 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) | 
 
 
 
 
 | 422 | // append the user js code... | 
 
 
 
 
 | 423 | sourceCode.Append(jsCode).AppendLine(); | 
 
 
 
 
 | 424 | // return to .NET the new xml data | 
 
 
 
 
 | 425 | sourceCode.Append("$xmlData;"); | 
 
 
 
 
 | 426 |  | 
 
 
 
 
 | 427 | try | 
 
 
 
 
 | 428 | { | 
 
 
 
 
 | 429 | xmlFileContent = jsEngine.Execute(sourceCode.ToString()).ToString(); | 
 
 
 
 
 | 430 | } | 
 
 
 
 
 | 431 | catch (Exception e) | 
 
 
 
 
 | 432 | { | 
 
 
 
 
 | 433 | Program.printAppError(Program.appErrors.PATCH_CODE_PROCESS_ERROR, "Error parsing code in customCodeOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 434 | return false; | 
 
 
 
 
 | 435 | } | 
 
 
 
 
 | 436 |  | 
 
 
 
 
 | 437 | // Let's see if the returned result is valid xml... | 
 
 
 
 
 | 438 | try | 
 
 
 
 
 | 439 | { | 
 
 
 
 
 | 440 | XmlDocument xmlDoc = new XmlDocument(); | 
 
 
 
 
 | 441 |  | 
 
 
 
 
 | 442 | xmlDoc.LoadXml(xmlFileContent); | 
 
 
 
 
 | 443 |  | 
 
 
 
 
 | 444 | xmlDoc.Save(currXMLFile); //saving the new xml with this method will auto ident it. | 
 
 
 
 
 | 445 |  | 
 
 
 
 
 | 446 | } | 
 
 
 
 
 | 447 | catch (Exception e) | 
 
 
 
 
 | 448 | { | 
 
 
 
 
 | 449 | Program.printAppError(Program.appErrors.PATCH_CODE_PARSE_XML_OUTPUT_ERROR, "Error parsing result xml to customCodeOperation in Patch file.\n" + e.ToString()); | 
 
 
 
 
 | 450 | return false; | 
 
 
 
 
 | 451 | } | 
 
 
 
 
 | 452 | } | 
 
 
 
 
 | 453 | //---------------------------------------------------JS Code Proccess (end) | 
 
 
 
 
 | 454 |  | 
 
 
 
 
 | 455 | return true; | 
 
 
 
 
 | 456 | } | 
 
 
 
 
 | 457 |  | 
 
 
 
 
 | 458 | private string getPatchParameter(string line, string parameterName) | 
 
 
 
 
 | 459 | { | 
 
 
 
 
 | 460 | string result = ""; | 
 
 
 
 
 | 461 | int startIdx = 0, endIdx = 0; | 
 
 
 
 
 | 462 |  | 
 
 
 
 
 | 463 | string temp = parameterName + " \""; | 
 
 
 
 
 | 464 |  | 
 
 
 
 
 | 465 | startIdx = line.IndexOf(temp); | 
 
 
 
 
 | 466 | if (startIdx != -1) //we have Parameter specified | 
 
 
 
 
 | 467 | { | 
 
 
 
 
 | 468 | startIdx += temp.Length; | 
 
 
 
 
 | 469 | endIdx = line.IndexOf("\"", startIdx); | 
 
 
 
 
 | 470 | result = line.Substring(startIdx, endIdx - startIdx); //Get the parameter value | 
 
 
 
 
 | 471 | } | 
 
 
 
 
 | 472 |  | 
 
 
 
 
 | 473 | return result; | 
 
 
 
 
 | 474 | } | 
 
 
 
 
 | 475 | } | 
 
 
 
 
 | 476 | } |