001package com.ganteater.ae.processor; 002 003import java.io.BufferedReader; 004import java.io.ByteArrayOutputStream; 005import java.io.File; 006import java.io.FileInputStream; 007import java.io.FileNotFoundException; 008import java.io.FileOutputStream; 009import java.io.FileReader; 010import java.io.IOException; 011import java.io.InputStream; 012import java.io.InputStreamReader; 013import java.io.OutputStream; 014import java.io.StringReader; 015import java.io.StringWriter; 016import java.net.Inet4Address; 017import java.net.InetAddress; 018import java.net.NetworkInterface; 019import java.net.Socket; 020import java.net.SocketException; 021import java.net.SocketTimeoutException; 022import java.net.URL; 023import java.net.URLConnection; 024import java.net.UnknownHostException; 025import java.security.NoSuchAlgorithmException; 026import java.security.SecureRandom; 027import java.text.DateFormat; 028import java.text.ParsePosition; 029import java.text.SimpleDateFormat; 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.Base64; 033import java.util.Calendar; 034import java.util.Collection; 035import java.util.Date; 036import java.util.Enumeration; 037import java.util.HashMap; 038import java.util.HashSet; 039import java.util.Iterator; 040import java.util.LinkedHashMap; 041import java.util.LinkedHashSet; 042import java.util.List; 043import java.util.Map; 044import java.util.Map.Entry; 045import java.util.Properties; 046import java.util.Random; 047import java.util.Set; 048import java.util.StringTokenizer; 049import java.util.TimeZone; 050import java.util.UUID; 051import java.util.concurrent.Executors; 052import java.util.concurrent.ThreadPoolExecutor; 053import java.util.concurrent.TimeUnit; 054import java.util.regex.Matcher; 055import java.util.regex.Pattern; 056import java.util.stream.Collectors; 057import java.util.stream.IntStream; 058 059import javax.swing.JOptionPane; 060import javax.xml.transform.Source; 061import javax.xml.transform.Transformer; 062import javax.xml.transform.TransformerFactory; 063import javax.xml.transform.stream.StreamResult; 064import javax.xml.transform.stream.StreamSource; 065 066import org.apache.commons.beanutils.ConvertUtils; 067import org.apache.commons.collections.CollectionUtils; 068import org.apache.commons.collections.MapUtils; 069import org.apache.commons.io.FileUtils; 070import org.apache.commons.io.IOUtils; 071import org.apache.commons.io.filefilter.TrueFileFilter; 072import org.apache.commons.jexl3.JexlBuilder; 073import org.apache.commons.jexl3.JexlContext; 074import org.apache.commons.jexl3.JexlEngine; 075import org.apache.commons.jexl3.JexlExpression; 076import org.apache.commons.jexl3.MapContext; 077import org.apache.commons.lang.ArrayUtils; 078import org.apache.commons.lang.BooleanUtils; 079import org.apache.commons.lang.ObjectUtils; 080import org.apache.commons.lang.StringEscapeUtils; 081import org.apache.commons.lang.StringUtils; 082import org.apache.commons.lang.math.NumberUtils; 083import org.apache.commons.lang3.SystemUtils; 084import org.apache.http.auth.AuthScope; 085import org.apache.http.auth.UsernamePasswordCredentials; 086import org.apache.http.client.CredentialsProvider; 087import org.apache.http.client.config.RequestConfig; 088import org.apache.http.client.methods.CloseableHttpResponse; 089import org.apache.http.client.methods.HttpGet; 090import org.apache.http.client.methods.HttpPost; 091import org.apache.http.client.methods.HttpRequestBase; 092import org.apache.http.client.protocol.HttpClientContext; 093import org.apache.http.client.utils.URLEncodedUtils; 094import org.apache.http.entity.ByteArrayEntity; 095import org.apache.http.impl.client.BasicCredentialsProvider; 096import org.apache.http.impl.client.CloseableHttpClient; 097import org.apache.http.impl.client.HttpClients; 098import org.apache.sling.commons.json.JSONArray; 099import org.apache.sling.commons.json.JSONException; 100import org.apache.sling.commons.json.JSONObject; 101 102import com.ganteater.ae.AEManager; 103import com.ganteater.ae.AEWorkspace; 104import com.ganteater.ae.ChoiceTaskRunner; 105import com.ganteater.ae.CommandException; 106import com.ganteater.ae.ILogger; 107import com.ganteater.ae.MultiTaskRunDialog; 108import com.ganteater.ae.OperationHolder; 109import com.ganteater.ae.RecipeListener; 110import com.ganteater.ae.RecipeRunner; 111import com.ganteater.ae.TaskCancelingException; 112import com.ganteater.ae.processor.annotation.CommandExamples; 113import com.ganteater.ae.processor.annotation.CommandHotHepl; 114import com.ganteater.ae.util.AEUtils; 115import com.ganteater.ae.util.AssertionFailedError; 116import com.ganteater.ae.util.NameValuePairImplementation; 117import com.ganteater.ae.util.TestCase; 118import com.ganteater.ae.util.xml.easyparser.EasyParser; 119import com.ganteater.ae.util.xml.easyparser.EasyUtils; 120import com.ganteater.ae.util.xml.easyparser.Node; 121import com.opencsv.CSVReader; 122 123import okhttp3.MediaType; 124import okhttp3.OkHttpClient; 125import okhttp3.Request.Builder; 126import okhttp3.Response; 127 128public class BaseProcessor extends Processor { 129 130 private Random random; 131 132 protected BaseProcessor() { 133 } 134 135 public BaseProcessor(Processor parent) throws CommandException { 136 init(parent); 137 } 138 139 public BaseProcessor(AEManager manager, ILogger log, File baseDir) { 140 super(manager, log, baseDir); 141 } 142 143 public BaseProcessor(Map<String, Object> hashMap, Node node, File baseDir) { 144 super(hashMap, node, baseDir); 145 } 146 147 public BaseProcessor(Node configNode, Map<String, Object> startVariables, RecipeListener listener, File startDir, 148 ILogger aLog, Processor parent) throws CommandException { 149 super(configNode, startVariables, listener, startDir, aLog, parent); 150 } 151 152 @CommandExamples({ "<Regexp name='type:property' source='type:property' regex='type:string' />" }) 153 public void runCommandRegexp(final Node aCurrentAction) throws Throwable { 154 final String theName = replaceProperties(aCurrentAction.getAttribute("name")); 155 final String source = replaceProperties(aCurrentAction.getAttribute("source")); 156 String variableValue = (String) getVariableValue(source); 157 158 String theText = null; 159 String regex = replaceProperties(aCurrentAction.getAttribute("regex")); 160 Pattern pattern = Pattern.compile(regex); 161 Matcher matcher = pattern.matcher(variableValue); 162 if (matcher.find()) { 163 theText = matcher.group(1); 164 } 165 166 setVariableValue(theName, theText); 167 } 168 169 @CommandHotHepl("<html>Replaces each substring of this string</html>") 170 @CommandExamples({ "<Replace name='type:property' oldChar='type:integer' newChar='type:integer'/>", 171 "<Replace name='type:property' regex='' replacement=''/>", 172 "<Replace name='type:property' unescape='enum:java|csv|html|javascript|xml' />", 173 "<Replace name='type:property' escape='enum:java|csv|html|javascript|xml|sql' />" }) 174 public void runCommandReplace(final Node command) throws Throwable { 175 String name = replaceProperties(command.getAttribute("name")); 176 177 Object variableValue = getVariableValue(name); 178 String value = null; 179 if (variableValue instanceof String) { 180 value = (String) variableValue; 181 } else if (variableValue instanceof byte[]) { 182 value = new String((byte[]) variableValue); 183 } else { 184 value = ObjectUtils.toString(variableValue); 185 } 186 value = replaceProperties(value); 187 188 final String theOldChar = replaceProperties(command.getAttribute("oldChar")); 189 final String theNewChar = replaceProperties(command.getAttribute("newChar")); 190 if (theOldChar != null) { 191 value = value.replace(theOldChar, theNewChar); 192 } 193 194 final String regex = replaceProperties(command.getAttribute("regex")); 195 final String replacement = replaceProperties(command.getAttribute("replacement")); 196 if (regex != null && value != null) { 197 value = value.replaceAll(regex, replacement); 198 } 199 200 String unescape = attr(command, "unescape"); 201 if (unescape != null) { 202 unescape = unescape.toLowerCase(); 203 switch (unescape) { 204 case "csv": { 205 value = StringEscapeUtils.unescapeCsv(value); 206 break; 207 } 208 case "html": { 209 value = StringEscapeUtils.unescapeHtml(value); 210 break; 211 } 212 case "java": { 213 value = StringEscapeUtils.unescapeJava(value); 214 break; 215 } 216 case "javascript": { 217 value = StringEscapeUtils.unescapeJavaScript(value); 218 break; 219 } 220 case "xml": { 221 value = StringEscapeUtils.unescapeXml(value); 222 break; 223 } 224 } 225 } 226 227 String escape = attr(command, "escape"); 228 if (escape != null) { 229 escape = escape.toLowerCase(); 230 switch (escape) { 231 case "csv": { 232 value = StringEscapeUtils.escapeCsv(value); 233 break; 234 } 235 case "html": { 236 value = StringEscapeUtils.escapeHtml(value); 237 break; 238 } 239 case "java": { 240 value = StringEscapeUtils.escapeJava(value); 241 break; 242 } 243 case "javascript": { 244 value = StringEscapeUtils.escapeJavaScript(value); 245 break; 246 } 247 case "sql": { 248 value = StringEscapeUtils.escapeSql(value); 249 break; 250 } 251 case "xml": { 252 value = StringEscapeUtils.escapeXml(value); 253 break; 254 } 255 } 256 } 257 258 setVariableValue(name, value); 259 } 260 261 @CommandHotHepl("<html>Data checking.</html>") 262 @CommandExamples({ 263 "<CheckValue actual='type:string' expected='type:string' mode='enum:normal|trimLines' condition='enum:unequal|equal' onErrorMsg='type:string'/>", 264 "<CheckValue value='type:string' regex='type:string' onErrorMsg='type:string'/>" }) 265 public void runCommandCheckValue(final Node aCurrentAction) throws Throwable { 266 267 final String theErrorMsg = replaceProperties(aCurrentAction.getAttribute("onErrorMsg")); 268 269 final String theRegex = replaceProperties(aCurrentAction.getAttribute("regex")); 270 271 if (theRegex == null) { 272 final boolean theTrimLines = "trimLines".equals(replaceProperties(aCurrentAction.getAttribute("mode"))); 273 try { 274 String actual = replaceProperties(aCurrentAction.getAttribute("actual")); 275 String expected = replaceProperties(aCurrentAction.getAttribute("expected")); 276 if (theTrimLines) { 277 actual = getTrimmedLines(actual); 278 expected = getTrimmedLines(expected); 279 } 280 281 final boolean unequal = "unequal".equals(replaceProperties(aCurrentAction.getAttribute("condition"))); 282 if (unequal) { 283 boolean equals = StringUtils.equals(expected, actual); 284 TestCase.assertFalse(theErrorMsg, equals); 285 } else { 286 TestCase.assertEquals(theErrorMsg, expected, actual); 287 } 288 } catch (final Throwable e) { 289 taskNode(aCurrentAction, false); 290 throw e; 291 } 292 } else { 293 final String theValue = replaceProperties(aCurrentAction.getAttribute("value")); 294 final Pattern p = Pattern.compile(theRegex); 295 final Matcher m = p.matcher(theValue); 296 if (m.find() == false) { 297 taskNode(aCurrentAction, false); 298 TestCase.fail("Regex validation failed. Regex:" + theRegex + ", value:" + theValue); 299 } 300 } 301 302 } 303 304 @CommandHotHepl("<html>Asserts that an object isn't null.</html>") 305 @CommandExamples({ "<CheckNotNull name='type:property' onErrorMsg='type:string'/>" }) 306 public void runCommandCheckNotNull(final Node aCurrentAction) throws Throwable { 307 final String theName = replaceProperties(aCurrentAction.getAttribute("name")); 308 final String theErrorMsg = replaceProperties(aCurrentAction.getAttribute("onErrorMsg")); 309 Object theValue = getVariableValue(theName); 310 if (theValue != null && theValue instanceof String[] && ((String[]) theValue).length == 0) { 311 theValue = null; 312 } 313 try { 314 TestCase.assertNotNull(theErrorMsg, theValue); 315 } catch (final Throwable e) { 316 taskNode(aCurrentAction, false); 317 throw e; 318 } 319 } 320 321 @CommandHotHepl("<html>Interactive choice command.</html>") 322 @CommandExamples({ "<Choice name='type:property'>" + "<Task name='type:string'>...</Task></Choice>", 323 "<Choice name='type:property' mode='enum:default|table'>" + "<Task name='type:string'>...</Task></Choice>", 324 "<Choice name='type:property' mode='enum:default|table' type='setup'>" 325 + "<Task name='type:string'/></Choice>", 326 "<Choice name='type:property' mode='enum:default|table' type='call-task'>" 327 + "<Task name='type:task'/></Choice>", 328 "<Choice name='type:property'><Task name='type:string'>...</Task><Started>...</Started></Choice>", 329 "<Choice name='type:property' runAllTaskName='type:string' mode='enum:default|table' type='enum:default|call-task'>" 330 + "<Task name='type:string'>...</Task><Started>...</Started></Choice>" }) 331 public void runCommandChoice(final Node aCurrentAction) throws Throwable { 332 333 final String nameOfChoice = replaceProperties(aCurrentAction.getAttribute("name")); 334 Object preset = getVariableValue(nameOfChoice); 335 336 String description = replaceProperties(aCurrentAction.getAttribute("description")); 337 338 final String theRunAllTaskName = replaceProperties(aCurrentAction.getAttribute("runAllTaskName")); 339 String type = replaceProperties(aCurrentAction.getAttribute("type")); 340 final boolean callType = "call-task".equals(type); 341 342 final Map<String, Node> tablesNodes = new LinkedHashMap<>(); 343 344 final String theMode = replaceProperties(aCurrentAction.getAttribute("mode")); 345 346 final Node[] taskNodes = aCurrentAction.getNodes("Task"); 347 for (int i = 0; i < taskNodes.length; i++) { 348 final String name = replaceProperties(taskNodes[i].getAttribute("name")); 349 350 if ("table".equals(theMode) && name != null && name.equals(theRunAllTaskName)) { 351 continue; 352 } 353 354 if (!callType || getListener().getManager().getTestPath(name) != null) { 355 tablesNodes.put(name, taskNodes[i]); 356 } 357 } 358 359 final String[] names = tablesNodes.keySet().toArray(new String[tablesNodes.size()]); 360 361 debug("Task list: " + nameOfChoice); 362 363 final List<String> activeNodes = new ArrayList<>(); 364 365 if ("table".equals(theMode) || "hidden".equals(theMode)) { 366 367 final String exceptionIgnore = replaceProperties(aCurrentAction.getAttribute("exception")); 368 boolean startsWith = false; 369 if (exceptionIgnore != null) { 370 startsWith = exceptionIgnore.startsWith("ignore"); 371 } 372 373 ChoiceTaskRunner choiceRunner = new ChoiceTaskRunner(nameOfChoice, preset == null); 374 boolean visible = !"hidden".equals(theMode); 375 final MultiTaskRunDialog inputSelectChoice = this.recipeListener.getManager().tasksChoice(choiceRunner, 376 names, startsWith, preset, this, visible); 377 378 try { 379 final Iterator<String> selectedTasks = inputSelectChoice.getSelectedTasks(); 380 381 List<String> selectedTaskNames = new ArrayList<>(); 382 while (selectedTasks.hasNext()) { 383 String selectedTask = selectedTasks.next(); 384 activeNodes.add(selectedTask); 385 386 selectedTaskNames.add(selectedTask); 387 inputSelectChoice.begin(selectedTask); 388 389 try { 390 Node action = tablesNodes.get(selectedTask); 391 startCommandInformation(action); 392 393 if (callType) { 394 runCommandTask(action); 395 } else { 396 taskNode(action, false); 397 } 398 inputSelectChoice.end(selectedTask, true); 399 400 } catch (final Throwable e) { 401 inputSelectChoice.end(selectedTask, false); 402 if (inputSelectChoice.isExceptionIgnore() == false) { 403 throw e; 404 } 405 } 406 } 407 408 if ("setup".equals(type)) { 409 setVariableValue(nameOfChoice, selectedTaskNames.toArray(new String[selectedTaskNames.size()])); 410 } 411 } finally { 412 inputSelectChoice.done(); 413 if (inputSelectChoice.isStarted()) { 414 Node[] nodes = aCurrentAction.getNodes("Started"); 415 for (Node node : nodes) { 416 taskNode(node); 417 } 418 } 419 } 420 421 } else { 422 if (this.recipeListener.getManager() != null) { 423 boolean notifyMe = this.recipeListener.isNotifyMe(); 424 description = StringUtils.defaultString(description, nameOfChoice); 425 final String inputSelectChoice = this.recipeListener.getManager().inputChoice(nameOfChoice, description, 426 names, ObjectUtils.toString(preset, null), this, notifyMe); 427 if (inputSelectChoice != null) { 428 activeNodes.add(inputSelectChoice); 429 } 430 } 431 432 debug("Select task: " + (activeNodes != null ? activeNodes : "<not chosen>")); 433 434 if (!activeNodes.isEmpty()) { 435 if (activeNodes.get(0).equals(theRunAllTaskName) == false) { 436 437 if (callType) { 438 runCommandTask(tablesNodes.get(activeNodes.get(0))); 439 } else { 440 taskNode(tablesNodes.get(activeNodes.get(0))); 441 } 442 443 } else { 444 for (int i = 0; i < names.length; i++) { 445 final String theActiveNode = names[i]; 446 if (theActiveNode.equals(theRunAllTaskName) == false) { 447 if (callType) { 448 runCommandTask(tablesNodes.get(theActiveNode)); 449 } else { 450 taskNode(tablesNodes.get(theActiveNode)); 451 } 452 } 453 } 454 } 455 } 456 } 457 458 setVariableValue(nameOfChoice, activeNodes); 459 } 460 461 @CommandHotHepl("<html>Runnable block. Should be use with <Threads/>.</html>") 462 @CommandExamples({ "<Runnable name='type:property' threadLog='true'>...</Runnable>" }) 463 public void runCommandRunnable(final Node aCurrentAction) throws CommandException { 464 final String theName = replaceProperties(aCurrentAction.getAttribute("name")); 465 String theNameThreads = getTestName(aCurrentAction); 466 if (theNameThreads == null) { 467 theNameThreads = "Thread"; 468 } 469 470 boolean threadLog = Boolean.valueOf(StringUtils.defaultIfBlank(attr(aCurrentAction, "threadLog"), "false")); 471 ILogger theLog = this.log; 472 if (threadLog) { 473 theLog = this.recipeListener.createLog(theNameThreads, false); 474 } 475 476 Node task = new Node("Task"); 477 task.setAttribute("description", aCurrentAction.getAttribute("name")); 478 task.addAll(aCurrentAction); 479 final TaskProcessorThread runnable = new TaskProcessorThread(this, task, getBaseDir(), theLog); 480 setVariableValue(theName, runnable); 481 } 482 483 @CommandHotHepl("<html>Sorts the array of objects.</html>") 484 @CommandExamples({ "<Sort name='type:property' type='enum:natural|random' />" }) 485 public void runCommandSort(final Node aCurrentAction) { 486 final String theName = replaceProperties(aCurrentAction.getAttribute("name")); 487 String theType = replaceProperties(aCurrentAction.getAttribute("type")); 488 if (theType == null) { 489 theType = "natural"; 490 } 491 492 final Object theObject = getVariableValue(theName); 493 if (theObject instanceof String[]) { 494 String[] theArray = (String[]) theObject; 495 if ("natural".equals(theType)) { 496 Arrays.sort(theArray); 497 } else if ("random".equals(theType)) { 498 theArray = randomSort(theArray); 499 } else { 500 throw new IllegalArgumentException("Sort type should be following value: natural, random."); 501 } 502 setVariableValue(theName, theArray); 503 } 504 } 505 506 @CommandHotHepl("<html>Searches the specified array for the specified object.</html>") 507 @CommandExamples({ "<CheckInArray value='type:string' array='type:property' onErrorMsg='type:string'/>" }) 508 public void runCommandCheckInArray(final Node aCurrentAction) throws Throwable { 509 final String theValue = replaceProperties(aCurrentAction.getAttribute("value")); 510 final String theArrayName = replaceProperties(aCurrentAction.getAttribute("array")); 511 final String theErrorMsg = replaceProperties(aCurrentAction.getAttribute("onErrorMsg")); 512 final Object theObject = getVariableValue(theArrayName); 513 if (theObject != null && theObject instanceof String[]) { 514 final String[] theValues = (String[]) theObject; 515 Arrays.sort(theValues); 516 try { 517 TestCase.assertTrue(theErrorMsg, Arrays.binarySearch(theValues, theValue) >= 0); 518 } catch (final Throwable e) { 519 taskNode(aCurrentAction, false); 520 throw e; 521 } 522 } 523 } 524 525 public void runCommandTokenizer(final Node aCurrentVar) { 526 final String theAttribut = aCurrentVar.getAttribute("name"); 527 String theDelimAttribut = aCurrentVar.getAttribute("delim"); 528 if (theDelimAttribut == null) { 529 theDelimAttribut = ";"; 530 } 531 final Object theObjectValue = getVariableValue(theAttribut); 532 if (theObjectValue == null) { 533 return; 534 } 535 String theLine = null; 536 if (theObjectValue instanceof String) { 537 theLine = (String) getVariableValue(theAttribut); 538 } else if (theObjectValue instanceof String[] && ((String[]) getVariableValue(theAttribut)).length == 1) { 539 theLine = ((String[]) getVariableValue(theAttribut))[0]; 540 } 541 final ArrayList<String> theArrayList = new ArrayList<String>(); 542 if (theLine != null) { 543 final StringTokenizer theStringTokenizer = new StringTokenizer(theLine, theDelimAttribut); 544 while (theStringTokenizer.hasMoreTokens()) { 545 theArrayList.add(theStringTokenizer.nextToken()); 546 } 547 final String[] theArray = new String[theArrayList.size()]; 548 for (int i = 0; i < theArrayList.size(); i++) { 549 if (isStopped()) { 550 break; 551 } 552 theArray[i] = theArrayList.get(i); 553 } 554 setVariableValue(theAttribut, theArray); 555 } else { 556 debug("Tokenized empty string is ignored."); 557 } 558 } 559 560 @CommandExamples({ "<Date name='type:string' format='type:string' />", 561 "<Date name='type:string' format='type:string' source='type:property' sformat='type:string' />", 562 "<Date name='type:string' format='type:string' shift='1s|1m|1h|1M|1Y' />" }) 563 public void runCommandDate(final Node aCurrentAction) throws Throwable { 564 final String name = replaceProperties(aCurrentAction.getAttribute("name")); 565 String value = replaceProperties(aCurrentAction.getAttribute("value")); 566 if (value == null) { 567 String source = aCurrentAction.getAttribute("source"); 568 if (source != null) { 569 value = (String) getVariableValue(replaceProperties(source)); 570 } 571 } 572 573 if (value == null) { 574 Object variableValue = getVariableValue(name); 575 if (variableValue != null) { 576 value = ObjectUtils.toString(variableValue); 577 } 578 } 579 580 String format = replaceProperties(aCurrentAction.getAttribute("format")); 581 String sformat = StringUtils.defaultString(replaceProperties(aCurrentAction.getAttribute("sformat")), format); 582 583 SimpleDateFormat dateFor = null; 584 if (sformat != null && !"ms".equals(sformat)) { 585 dateFor = new SimpleDateFormat(sformat); 586 dateFor.setTimeZone(TimeZone.getTimeZone("UTC")); 587 } 588 String stringDate = null; 589 if (value == null) { 590 if (dateFor != null) { 591 stringDate = dateFor.format(new Date()); 592 } else { 593 stringDate = Long.toString(new Date().getTime()); 594 } 595 value = stringDate; 596 } 597 598 final String shift = replaceProperties(StringUtils.trim(aCurrentAction.getAttribute("shift"))); 599 600 Date date; 601 if (dateFor != null) { 602 date = dateFor.parse(value); 603 } else { 604 date = new Date(Long.parseLong(value)); 605 } 606 607 if (shift != null) { 608 Calendar c = Calendar.getInstance(); 609 c.setTime(date); 610 String substring = StringUtils.substring(shift, 0, shift.length() - 1); 611 int shiftValue = Integer.parseInt(substring); 612 switch (shift.charAt(shift.length() - 1)) { 613 case 's': 614 c.add(Calendar.SECOND, shiftValue); 615 break; 616 case 'm': 617 c.add(Calendar.MINUTE, shiftValue); 618 break; 619 case 'h': 620 c.add(Calendar.HOUR, shiftValue); 621 break; 622 case 'd': 623 c.add(Calendar.DAY_OF_MONTH, shiftValue); 624 break; 625 case 'w': 626 c.add(Calendar.WEEK_OF_MONTH, shiftValue); 627 break; 628 case 'M': 629 c.add(Calendar.MONTH, shiftValue); 630 break; 631 case 'Y': 632 c.add(Calendar.YEAR, shiftValue); 633 break; 634 } 635 636 date = c.getTime(); 637 } 638 639 if (format != null && !"ms".equals(format)) { 640 dateFor = new SimpleDateFormat(format); 641 dateFor.setTimeZone(TimeZone.getTimeZone("UTC")); 642 stringDate = dateFor.format(date); 643 } else { 644 stringDate = Long.toString(date.getTime()); 645 } 646 647 setVariableValue(name, stringDate); 648 } 649 650 @CommandHotHepl("<html>Waiting command in millisecond.</html>") 651 @CommandExamples({ "<Wait delay='type:integer'/>", "<Wait/>" }) 652 public void runCommandWait(final Node aCurrentAction) { 653 final String theValue = replaceProperties(aCurrentAction.getAttribute("delay")); 654 if (theValue != null) { 655 wait(theValue); 656 } else { 657 pause(); 658 } 659 } 660 661 @CommandHotHepl("<html>Presentation panel frame.</html>") 662 @CommandExamples({ 663 "<Frame frameId='type:string' reuse='false' type='TextPanel'/><Out frameId='type:attr' level='debug'/>", 664 "<Frame frameId='type:string' reuse='false' type='HTMLPanel'/><Out frameId='type:attr' level='debug'/>", 665 "<Frame frameId='type:string' reuse='false' type='XYLineChart' title='type:string' xAxisLabel='type:string' yAxisLabel='type:string'/><Out frameId='type:attr' series='type:string' x='type:integer' level='debug'>...</Out>", 666 "<Frame frameId='type:string' reuse='false' type='BarChart' title='type:string' xAxisLabel='type:string' yAxisLabel='type:string'/><Out frameId='type:attr' row='type:string' column='type:string' level='debug'>...</Out>", 667 "<Frame frameId='type:string' reuse='false' type='PieChart' title='type:string' /><Out frameId='type:attr' key='type:string' level='debug'/>", 668 "<Frame frameId='type:string' reuse='false' type='DialScale' title='type:string' label='type:string' lower='type:double' upper='type:double' increment='type:double' count='type:integer'/><Out frameId='type:attr' level='debug'/>" }) 669 public void runCommandFrame(final Node aCurrentAction) throws Throwable { 670 this.recipeListener.runCommandFrame(replaceAttributes(aCurrentAction)); 671 } 672 673 @CommandHotHepl("<html></html>") 674 @CommandExamples({ "<Formater name='type:property' type='enum:xml|http-get-request'/>" }) 675 public void runCommandFormater(final Node aCurrentAction) throws Throwable { 676 final String theNameAttribut = replaceProperties(aCurrentAction.getAttribute("name")); 677 final String theTypeAttribut = replaceProperties(aCurrentAction.getAttribute("type")); 678 Object theValue = getVariableValue(theNameAttribut); 679 if (theValue instanceof String) { 680 if ("json".equals(theTypeAttribut)) { 681 theValue = AEUtils.format(ObjectUtils.toString(theValue)); 682 } else { 683 theValue = new String[] { (String) theValue }; 684 } 685 686 setVariableValue(theNameAttribut, theValue); 687 } 688 if (theValue instanceof String[]) { 689 final String[] theValueArray = (String[]) theValue; 690 for (int i = 0; i < theValueArray.length; i++) { 691 if (isStopped()) { 692 break; 693 } 694 if ("xml".equals(theTypeAttribut)) { 695 final EasyParser theParser = new EasyParser(); 696 String theCurrentValue = theValueArray[i]; 697 theCurrentValue = prepareXml(theCurrentValue); 698 final Node object = theParser.getObject(theCurrentValue); 699 theValueArray[i] = object.getXMLText(); 700 } 701 } 702 if (theValueArray.length > 2) { 703 setVariableValue(theNameAttribut, theValueArray); 704 } else if (theValueArray.length == 1) { 705 setVariableValue(theNameAttribut, theValueArray[0]); 706 } else { 707 setVariableValue(theNameAttribut, null); 708 } 709 } 710 } 711 712 @CommandExamples({ "<Trim name='type:property'/>" }) 713 public void runCommandTrim(final Node aCurrentAction) throws Throwable { 714 String name = replaceProperties(aCurrentAction.getAttribute("name")); 715 Object value = getVariableValue(name); 716 if (value instanceof String) { 717 value = StringUtils.trimToNull(ObjectUtils.toString(value)); 718 } else if (value instanceof String[]) { 719 String[] array = (String[]) value; 720 if (array.length == 0) { 721 value = null; 722 } else { 723 List<String> list = new ArrayList<>(); 724 for (String object : array) { 725 String val = ObjectUtils.toString(object); 726 if (StringUtils.isNotBlank(val)) { 727 list.add(object); 728 } 729 } 730 value = list.toArray(new String[list.size()]); 731 } 732 } else if (value instanceof List) { 733 @SuppressWarnings("unchecked") 734 List<String> array = (List<String>) value; 735 if (array.size() == 0) { 736 value = null; 737 } else { 738 List<String> list = new ArrayList<>(); 739 for (String object : array) { 740 String val = ObjectUtils.toString(object); 741 if (StringUtils.isNotBlank(val)) { 742 list.add(object); 743 } 744 } 745 value = list.toArray(new String[list.size()]); 746 } 747 } 748 applyResult(aCurrentAction, name, value); 749 } 750 751 @CommandHotHepl("<html></html>") 752 @CommandExamples({ "<Xslt name='type:property' xml='type:string' xsl='type:string'/>" }) 753 public void runCommandXslt(final Node aCurrentAction) throws Throwable { 754 final String theNameAttribut = replaceProperties(aCurrentAction.getAttribute("name")); 755 final String theXmlAttribut = replaceProperties(aCurrentAction.getAttribute("xml")); 756 final String theXslAttribut = replaceProperties(aCurrentAction.getAttribute("xsl")); 757 final StringWriter theStringWriter = new StringWriter(); 758 759 if (theXmlAttribut == null || theXmlAttribut.trim().length() == 0 || "null".equals(theXmlAttribut)) { 760 debug("Xml document is empty, transform disable."); 761 return; 762 } 763 764 if (theXslAttribut == null || theXslAttribut.trim().length() == 0 || "null".equals(theXslAttribut)) { 765 debug("Xsl document is empty, transform disable."); 766 return; 767 } 768 769 try { 770 final Source xslSource = new StreamSource(new StringReader(theXslAttribut)); 771 final Transformer transformer = TransformerFactory.newInstance().newTransformer(xslSource); 772 final Source xmlSource = new StreamSource(new StringReader(theXmlAttribut)); 773 774 transformer.transform(xmlSource, new StreamResult(theStringWriter)); 775 776 } catch (final Throwable e) { 777 debug("XML Data to transformation:\n" + theXmlAttribut); 778 debug("XSL:\n" + theXslAttribut); 779 this.log.error("Xsl transformation is failed.", e); 780 throw e; 781 } 782 783 setVariableValue(theNameAttribut, theStringWriter.toString()); 784 } 785 786 @CommandHotHepl("<html></html>") 787 @CommandExamples({ "<Out name='type:property'/>", "<Out frameId='type:string'/>", 788 "<Out name='type:property' level='enum:info|debug|warn|error'/>", 789 "<Out name='type:property' level='enum:info|debug|warn|error'> ... </Out>", 790 "<Out level='enum:info|debug|warn|error'>... $var{...}</Out>", 791 "<Out file='type:path' append='enum:true|false' encoding='UTF-8'/>" }) 792 public void runCommandOut(final Node command) throws Throwable { 793 final String name = replaceProperties(command.getAttribute("name")); 794 final String description = replaceProperties(command.getAttribute("description")); 795 String theOutFileNameAttribut = replaceProperties(command.getAttribute("file")); 796 797 String logLevel = command.getAttribute("level"); 798 logLevel = replaceProperties(logLevel); 799 800 if (logLevel == null) { 801 logLevel = StringUtils.defaultIfBlank(getVariableString(DEFAULT_LOG_LEVEL_NAME), "info"); 802 } 803 804 String type = replaceProperties(command.getAttribute("type")); 805 806 FileOutputStream theFileOutputStream = null; 807 try { 808 if (theOutFileNameAttribut != null) { 809 String theAppendAttribut = replaceProperties(command.getAttribute("append")); 810 if (theAppendAttribut == null) { 811 theAppendAttribut = "true"; 812 } 813 theOutFileNameAttribut = replaceProperties(theOutFileNameAttribut); 814 final File file = getFile(theOutFileNameAttribut); 815 file.getParentFile().mkdirs(); 816 theFileOutputStream = new FileOutputStream(file, "true".equals(theAppendAttribut)); 817 } 818 String theEncoding = replaceProperties(command.getAttribute("encoding")); 819 if (theEncoding == null) { 820 theEncoding = "UTF-8"; 821 } 822 823 String theTextOut = null; 824 String varName = name; 825 final Node[] nodes = command.getTextNodes(); 826 827 if (nodes.length > 0) { 828 Node node = nodes[0]; 829 theTextOut = replaceProperties(node.getText()); 830 } else if (command.size() > 0) { 831 String innerXMLText = command.getInnerXMLText(); 832 Node node = new EasyParser().getObject(innerXMLText); 833 EasyUtils.removeTagId(node); 834 theTextOut = replaceProperties(node.toString()); 835 } 836 837 if (theTextOut != null) { 838 if (name != null) { 839 varName = theTextOut + ": " + varName; 840 } 841 if (theFileOutputStream != null) { 842 theFileOutputStream.write(theTextOut.getBytes(theEncoding)); 843 } 844 845 Properties attributes = replaceAttributes(command); 846 this.recipeListener.outToFrame(this, attributes, theTextOut); 847 } 848 849 if (name != null) { 850 Object theValue = getVariableValue(name); 851 852 if (theValue instanceof byte[]) { 853 if (theFileOutputStream != null) { 854 final byte[] value = (byte[]) theValue; 855 theFileOutputStream.write(value); 856 theFileOutputStream.close(); 857 return; 858 } else { 859 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, theValue, type); 860 return; 861 } 862 } 863 864 if (theValue == null) { 865 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, null, type); 866 867 } else if (theValue instanceof String) { 868 if (theFileOutputStream == null) { 869 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, theValue.toString(), 870 type); 871 } else { 872 theFileOutputStream.write(theValue.toString().getBytes(theEncoding)); 873 } 874 875 this.recipeListener.outToFrame(this, replaceAttributes(command), theValue); 876 877 } else if (theValue instanceof String[]) { 878 final StringBuffer theBuffer = new StringBuffer(); 879 880 final String[] theValueArray = (String[]) theValue; 881 for (int i = 0; i < theValueArray.length; i++) { 882 if (isStopped()) { 883 break; 884 } 885 886 if (theBuffer.length() > 0) { 887 theBuffer.append("\n"); 888 } 889 theBuffer.append(theValueArray[i]); 890 891 Properties params = replaceAttributes(command); 892 String msg = theValueArray[i]; 893 this.recipeListener.outToFrame(this, params, msg); 894 } 895 if (theFileOutputStream == null) { 896 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, theBuffer.toString(), 897 type); 898 } else { 899 theFileOutputStream.write(theBuffer.toString().getBytes(theEncoding)); 900 } 901 } else { 902 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, theValue, type); 903 this.recipeListener.outToFrame(this, replaceAttributes(command), theValue); 904 } 905 } else { 906 outputLog(StringUtils.defaultIfEmpty(description, varName), logLevel, theTextOut, type); 907 } 908 } finally { 909 if (theFileOutputStream != null) { 910 theFileOutputStream.flush(); 911 theFileOutputStream.close(); 912 } 913 } 914 } 915 916 @CommandHotHepl("<html></html>") 917 @CommandExamples({ "<About><description>...</description></About>", 918 "<About><attach><file name='' /></attach></About>", 919 "<About><author name='' email='' messager='' phone=''/><attach><file name='' width='' height=''/></attach></About>" }) 920 public void runCommandAbout(final Node aCurrentAction) throws Throwable { 921 } 922 923 @CommandExamples({ "<Exist name='type:property' text='' value=''/>", 924 "<Exist name='type:property' array='type:property' value=''/>" }) 925 public void runCommandExist(final Node aCurrentAction) throws Throwable { 926 final String theName = replaceProperties(aCurrentAction.getAttribute("name")); 927 final String theText = replaceProperties(aCurrentAction.getAttribute("text")); 928 final String theArrayName = replaceProperties(aCurrentAction.getAttribute("array")); 929 final String theValue = replaceProperties(aCurrentAction.getAttribute("value")); 930 931 if (theArrayName != null) { 932 final Object variableValue = getVariableValue(theArrayName); 933 if (variableValue instanceof String[]) { 934 final String[] variableValueArray = (String[]) variableValue; 935 for (int i = 0; i < variableValueArray.length; i++) { 936 if (theValue.equals(variableValueArray[i])) { 937 setVariableValue(theName, "true"); 938 return; 939 } 940 } 941 } 942 943 if (variableValue instanceof String) { 944 final String value = (String) variableValue; 945 if (theValue.equals(value)) { 946 setVariableValue(theName, "true"); 947 return; 948 } 949 } 950 setVariableValue(theName, "false"); 951 } else { 952 if (theText == null || theValue == null || theName == null) { 953 return; 954 } 955 final int indexOf = theText.indexOf(theValue); 956 setVariableValue(theName, indexOf >= 0 ? "true" : "false"); 957 } 958 } 959 960 @CommandExamples({ "<Load name='type:property' init='console'/>", 961 "<Load name='type:property' init='console'/>...</Load>", "<Load name='type:property' file='type:path'/>", 962 "<Load name='type:property' file='type:path' timeout='0' mode='enum:default|noreplace|escapeJS|bytes'/>", 963 "<Load name='type:property' url='' timeout='0' mode='enum:default|noreplace|escapeJS|bytes'/>", 964 "<Load name='type:property' xml='' timeout='0' mode='enum:default|noreplace|escapeJS|bytes|array'/>" }) 965 public void runCommandLoad(final Node action) throws Throwable { 966 final boolean noreplace = "noreplace".equals(action.getAttribute("mode")); 967 final boolean isArray = "array".equals(action.getAttribute("mode")); 968 final boolean defaultMode = "default".equals(action.getAttribute("mode")); 969 final boolean escapeJSValue = "escapeJS".equals(action.getAttribute("mode")); 970 final boolean bytes = "bytes".equals(action.getAttribute("mode")); 971 final boolean base64 = "base64".equals(action.getAttribute("mode")); 972 973 String theEncoding = replaceProperties(action.getAttribute("encoding")); 974 if (theEncoding == null) { 975 theEncoding = "UTF-8"; 976 } 977 978 final String name = replaceProperties(action.getAttribute("name")); 979 int timeout = Integer.parseInt(StringUtils.defaultIfBlank(attr(action, "timeout"), "0")); 980 981 final String theUrl = replaceProperties(action.getAttribute("url")); 982 if (theUrl != null) { 983 URL url = new URL(theUrl); 984 long startTime = System.currentTimeMillis(); 985 while (timeout == 0 || System.currentTimeMillis() < startTime + timeout) { 986 if (isStopped()) { 987 break; 988 } 989 try { 990 URLConnection openConnection = url.openConnection(); 991 openConnection.setReadTimeout(timeout); 992 byte[] byteArray = IOUtils.toByteArray(openConnection.getInputStream()); 993 if (escapeJSValue) { 994 String data = StringEscapeUtils.escapeJavaScript(new String(byteArray)); 995 setVariableValue(name, data); 996 } else { 997 setVariableValue(name, new String(byteArray, theEncoding)); 998 } 999 return; 1000 1001 } catch (IOException e) { 1002 if (timeout == 0) { 1003 throw e; 1004 } 1005 wait("200"); 1006 } 1007 } 1008 } 1009 1010 String filePath = (String) attr(action, "file"); 1011 final boolean theDialog = isActiveInitFor(action, "console"); 1012 1013 if (theDialog) { 1014 File theFile = null; 1015 if (filePath != null) { 1016 theFile = getFile(filePath); 1017 } 1018 filePath = this.recipeListener.getManager().inputFile(name, null, theFile, log, this); 1019 } 1020 1021 if (filePath != null) { 1022 if (base64 || bytes) { 1023 File file = getFile(filePath); 1024 debug("Loading file: " + file); 1025 if (file.exists()) { 1026 try (FileInputStream input = new FileInputStream(file)) { 1027 Object byteArray = IOUtils.toByteArray(input); 1028 if (base64) { 1029 byteArray = Base64.getEncoder().encodeToString((byte[]) byteArray); 1030 } 1031 setVariableValue(name, byteArray); 1032 } 1033 } else { 1034 throw new FileNotFoundException(file.getAbsolutePath()); 1035 } 1036 return; 1037 } 1038 1039 int iterations = timeout / 1000; 1040 if (iterations == 0) { 1041 iterations = 1; 1042 } 1043 for (int i = 0; i < iterations; i++) { 1044 if (isStopped()) { 1045 break; 1046 } 1047 try { 1048 1049 if (!action.isEmpty()) { 1050 File file = getFile(filePath); 1051 try (BufferedReader reader = new BufferedReader(new FileReader(file))) { 1052 String line; 1053 while ((line = reader.readLine()) != null) { 1054 if (this.breakFlag > 0) { 1055 break; 1056 } 1057 setVariableValue(name, line); 1058 taskNode(action, false); 1059 } 1060 } finally { 1061 if (this.breakFlag > 0) { 1062 breakFlag--; 1063 } 1064 } 1065 1066 } else { 1067 1068 String text = AEUtils.loadResource(filePath, getBaseDir(), theEncoding); 1069 if (!noreplace) { 1070 text = replaceProperties(text, defaultMode); 1071 } 1072 1073 if (escapeJSValue) { 1074 String data = StringEscapeUtils.escapeJavaScript(text); 1075 setVariableValue(name, data); 1076 } else { 1077 Object val = text; 1078 if (isArray) { 1079 val = StringUtils.split(text, "\n\r"); 1080 } 1081 1082 setVariableValue(name, val); 1083 } 1084 } 1085 1086 break; 1087 1088 } catch (final FileNotFoundException e) { 1089 if (timeout == 0) { 1090 throw e; 1091 } 1092 wait("1000"); 1093 } catch (final Exception e) { 1094 throw e; 1095 } 1096 } 1097 } else { 1098 if (isActiveInitFor(action, "mandatory")) { 1099 stop(); 1100 } 1101 } 1102 1103 } 1104 1105 @CommandExamples({ "<Remove name='type:property'/>", "<Remove file=''/>", 1106 "<Remove name='type:property' history='true'/>" }) 1107 public void runCommandRemove(final Node aCurrentAction) throws Throwable { 1108 String theFileName = aCurrentAction.getAttribute("file"); 1109 if (theFileName != null) { 1110 theFileName = replaceProperties(theFileName); 1111 final File theFile = getFile(theFileName); 1112 if (theFile.isDirectory()) { 1113 FileUtils.deleteDirectory(theFile); 1114 } else { 1115 if (theFile.delete() == false) { 1116 new Exception("File '" + theFile.getAbsolutePath() + "' is not deleted."); 1117 } 1118 } 1119 } 1120 String theVarName = aCurrentAction.getAttribute("name"); 1121 if (theVarName != null) { 1122 theVarName = replaceProperties(theVarName); 1123 setVariableValue(theVarName, null); 1124 if (Boolean.parseBoolean((attr(aCurrentAction, "history")))) { 1125 AEWorkspace.getInstance().setDefaultUserConfiguration(".inputValue." + theVarName, null); 1126 } 1127 } 1128 } 1129 1130 @CommandExamples({ 1131 "<Get name='type:property' url='type:string' auth='type:string' mediaType='type:string' retries='1' timeout='type:integer'/> " }) 1132 public void runCommandGet(final Node aCurrentAction) throws Throwable { 1133 1134 String mediaTypeStr = attr(aCurrentAction, "mediaType"); 1135 mediaTypeStr = StringUtils.defaultIfEmpty(mediaTypeStr, "application/json"); 1136 1137 String url = attr(aCurrentAction, "url"); 1138 String auth = attr(aCurrentAction, "auth"); 1139 int retries = Integer.parseInt(attr(aCurrentAction, "retries", "1")); 1140 1141 Builder builder = new okhttp3.Request.Builder().url(url).get(); 1142 1143 if (mediaTypeStr != null) { 1144 builder.addHeader("Content-Type", mediaTypeStr); 1145 } 1146 if (auth != null) { 1147 builder.addHeader("Authorization", auth); 1148 } 1149 1150 okhttp3.Request request = builder.build(); 1151 1152 for (int i = 0; i < retries; i++) { 1153 if (isStopped()) { 1154 break; 1155 } 1156 1157 try { 1158 okhttp3.OkHttpClient.Builder newBuilder = new OkHttpClient().newBuilder(); 1159 String timeoutStr = attr(aCurrentAction, "timeout"); 1160 if (timeoutStr != null) { 1161 long timeout = Long.parseLong(timeoutStr); 1162 newBuilder.connectTimeout(timeout, TimeUnit.MILLISECONDS); 1163 newBuilder.readTimeout(timeout, TimeUnit.MILLISECONDS); 1164 newBuilder.writeTimeout(timeout, TimeUnit.MILLISECONDS); 1165 } 1166 OkHttpClient client = newBuilder.build(); 1167 1168 try (Response response = client.newCall(request).execute()) { 1169 String value = new String(response.body().bytes(), "UTF-8"); 1170 String name = attr(aCurrentAction, "name"); 1171 if (name != null) { 1172 setVariableValue(name, value); 1173 } 1174 } 1175 1176 break; 1177 } catch (SocketTimeoutException e) { 1178 if (i == 2) { 1179 throw e; 1180 } 1181 } 1182 } 1183 } 1184 1185 @CommandExamples({ 1186 "<Post name='type:property' url='type:string' auth='type:string' body='type:string' mediaType='type:string' timeout='type:integer'/> " }) 1187 public void runCommandPost(final Node aCurrentAction) throws Throwable { 1188 String mediaTypeStr = attr(aCurrentAction, "mediaType"); 1189 mediaTypeStr = StringUtils.defaultIfEmpty(mediaTypeStr, "application/json"); 1190 1191 String url = attr(aCurrentAction, "url"); 1192 String auth = attr(aCurrentAction, "auth"); 1193 String bodyStr = StringUtils.defaultIfEmpty(replaceProperties(aCurrentAction.getAttribute("body")), ""); 1194 1195 MediaType mediaType = MediaType.parse(mediaTypeStr); 1196 okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, bodyStr); 1197 1198 Builder addHeader = new okhttp3.Request.Builder().url(url).method("POST", body).addHeader("Content-Type", 1199 mediaTypeStr); 1200 if (auth != null) { 1201 addHeader = addHeader.addHeader("Authorization", auth); 1202 } 1203 okhttp3.Request request = addHeader.addHeader("Accept", "*/*").build(); 1204 okhttp3.OkHttpClient.Builder newBuilder = new OkHttpClient().newBuilder(); 1205 1206 String timeoutStr = attr(aCurrentAction, "timeout"); 1207 if (timeoutStr != null) { 1208 long timeout = Long.parseLong(timeoutStr); 1209 newBuilder.connectTimeout(timeout, TimeUnit.MILLISECONDS); 1210 newBuilder.readTimeout(timeout, TimeUnit.MILLISECONDS); 1211 newBuilder.writeTimeout(timeout, TimeUnit.MILLISECONDS); 1212 } 1213 OkHttpClient client = newBuilder.build(); 1214 try (Response response = client.newCall(request).execute()) { 1215 String value = new String(response.body().bytes(), "UTF-8"); 1216 1217// if(response.code() == 404) { 1218// 1219// } 1220 1221 String name = attr(aCurrentAction, "name"); 1222 if (name != null) { 1223 setVariableValue(name, value); 1224 } 1225 } 1226 } 1227 1228 @CommandExamples({ 1229 "<Request method='value:get|post|[socket]' request='type:property[Map{header;body}]' response='type:property[Map{status;body}]' host='http://...' timeout='5'/>", 1230 "<Request method='get' response='type:property[Map{status;body}]' host='http://...' userName='' password=''><param name='' value=''/></Request>" }) 1231 public void runCommandRequest(final Node aCurrentAction) throws Throwable { 1232 Object request = attrValue(aCurrentAction, "request"); 1233 final String responseName = attr(aCurrentAction, "response"); 1234 final String method = StringUtils.defaultIfEmpty(attr(aCurrentAction, "method"), "socket"); 1235 String theUrl = replaceProperties(aCurrentAction.getAttribute("host")); 1236 1237 String userName = attr(aCurrentAction, "userName"); 1238 String password = attr(aCurrentAction, "password"); 1239 HttpClientContext localContext = null; 1240 if (userName != null && password != null) { 1241 CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 1242 credentialsProvider.setCredentials(AuthScope.ANY, 1243 new UsernamePasswordCredentials(userName + ":" + password)); 1244 localContext = HttpClientContext.create(); 1245 localContext.setCredentialsProvider(credentialsProvider); 1246 } 1247 1248 HttpRequestBase httpRequest = null; 1249 1250 final Node[] paramNodes = aCurrentAction.getNodes("param"); 1251 if (paramNodes != null && paramNodes.length > 0) { 1252 List<NameValuePairImplementation> parameters = new ArrayList<>(); 1253 for (Node node : paramNodes) { 1254 String name = attr(node, "name"); 1255 String value = attr(node, "value"); 1256 1257 NameValuePairImplementation nameValuePair = new NameValuePairImplementation(name, value); 1258 parameters.add(nameValuePair); 1259 } 1260 1261 String query = URLEncodedUtils.format(parameters, "UTF-8"); 1262 theUrl = theUrl + "?" + query; 1263 } 1264 1265 if (theUrl.toLowerCase().startsWith("http")) { 1266 if ("get".equalsIgnoreCase(method)) { 1267 httpRequest = new HttpGet(theUrl); 1268 1269 } else if ("post".equalsIgnoreCase(method)) { 1270 HttpPost httpPost = new HttpPost(theUrl); 1271 if (request != null) { 1272 @SuppressWarnings("unchecked") 1273 final Map<String, Object> requestMap = (Map<String, Object>) request; 1274 Object bodyObject = requestMap.get("body"); 1275 byte[] body = null; 1276 if (bodyObject instanceof byte[]) { 1277 body = (byte[]) bodyObject; 1278 } else if (bodyObject instanceof String) { 1279 body = ((String) bodyObject).getBytes(); 1280 } 1281 httpPost.setEntity(new ByteArrayEntity(body)); 1282 } 1283 httpRequest = httpPost; 1284 1285 } 1286 String timeoutStr = replaceProperties(aCurrentAction.getAttribute("timeout")); 1287 timeoutStr = StringUtils.defaultIfEmpty(timeoutStr, "5"); 1288 1289 int timeout = Integer.parseInt(timeoutStr); 1290 RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout * 1000) 1291 .setConnectionRequestTimeout(timeout * 1000).setSocketTimeout(timeout * 1000).build(); 1292 httpRequest.setConfig(config); 1293 if (request != null) { 1294 @SuppressWarnings("unchecked") 1295 Map<String, String> header = (Map<String, String>) ((Map<String, Object>) request).get("header"); 1296 if (header != null) { 1297 Set<Entry<String, String>> entrySet = header.entrySet(); 1298 for (Entry<String, String> entry : entrySet) { 1299 httpRequest.setHeader(entry.getKey(), entry.getValue()); 1300 } 1301 } 1302 } 1303 1304 CloseableHttpResponse response; 1305 CloseableHttpClient httpclient = HttpClients.createDefault(); 1306 1307 long duration = System.currentTimeMillis(); 1308 if (localContext == null) { 1309 response = httpclient.execute(httpRequest); 1310 } else { 1311 response = httpclient.execute(httpRequest, localContext); 1312 } 1313 ByteArrayOutputStream body = new ByteArrayOutputStream(); 1314 response.getEntity().writeTo(body); 1315 1316 HashMap<String, Object> aValue = new HashMap<String, Object>(); 1317 aValue.put("body", body.toByteArray()); 1318 aValue.put("status", response.getStatusLine().getStatusCode()); 1319 aValue.put("header", response.getAllHeaders()); 1320 aValue.put("duration", Long.toString(System.currentTimeMillis() - duration)); 1321 setVariableValue(responseName, aValue); 1322 1323 } else { 1324 1325 Socket socket = null; 1326 try { 1327 String host = StringUtils.substringBefore(theUrl, ":"); 1328 int port = Integer.parseInt(StringUtils.substringAfter(theUrl, ":")); 1329 socket = new Socket(host, port); 1330 OutputStream outputStream = socket.getOutputStream(); 1331 if (request instanceof byte[]) { 1332 IOUtils.write((byte[]) request, outputStream); 1333 } else if (request instanceof String) { 1334 IOUtils.write(((String) request).getBytes(), outputStream); 1335 } 1336 InputStream inputStream = socket.getInputStream(); 1337 byte[] response = IOUtils.toByteArray(inputStream); 1338 setVariableValue(responseName, response); 1339 } finally { 1340 if (socket != null) { 1341 socket.close(); 1342 } 1343 } 1344 1345 } 1346 1347 } 1348 1349 @CommandExamples({ "<Operation method='type:operation' />" }) 1350 @CommandHotHepl("<html>Custom operation method runner.</html>") 1351 public void runCommandOperation(final Node aCurrentAction) throws Throwable { 1352 String method = replaceProperties(aCurrentAction.getAttribute("method")); 1353 OperationHolder operationsMethod = AEWorkspace.getInstance().getOperationsMethod(method); 1354 1355 if (operationsMethod == null) { 1356 throw new IllegalArgumentException("Operation method is not found: " + method); 1357 } 1358 1359 Class<?>[] typeParameters = operationsMethod.getMethod().getParameterTypes(); 1360 1361 Object[] args = new Object[typeParameters.length]; 1362 for (int i = 0; i < args.length; i++) { 1363 String replaceProperties = aCurrentAction.getAttribute("arg" + (i + 1)); 1364 if (replaceProperties != null) { 1365 boolean varInjection = replaceProperties.startsWith("$var{") && replaceProperties.endsWith("}"); 1366 String varName = ""; 1367 if (varInjection) { 1368 varName = StringUtils.substring(replaceProperties, 5, replaceProperties.length() - 1); 1369 varInjection = !StringUtils.contains(varName, "{"); 1370 } 1371 1372 if (varInjection) { 1373 args[i] = ConvertUtils.convert(getVariableValue(varName), typeParameters[i]); 1374 } else { 1375 args[i] = ConvertUtils.convert(replaceProperties, typeParameters[i]); 1376 } 1377 } else { 1378 args[i] = null; 1379 } 1380 } 1381 1382 Class<?> operationClass = operationsMethod.getOperationClass(); 1383 Object operation = operationObjects.get(operationClass); 1384 if (operation == null) { 1385 operation = operationsMethod.newInstance(); 1386 operationObjects.put(operationClass, operation); 1387 } 1388 Object value = operationsMethod.invoke(operation, args); 1389 1390 String name = replaceProperties(aCurrentAction.getAttribute("name")); 1391 if (name != null) { 1392 setVariableValue(name, value); 1393 } 1394 } 1395 1396 @CommandExamples({ "<Table name='The table of variables'><var name='' value=''/></Table>", 1397 "<Table name='The table of variables' file='type:path'><var name='' value=''/></Table>" }) 1398 public void runCommandTable(final Node aCurrentVar) throws Throwable { 1399 AEManager manager = this.recipeListener.getManager(); 1400 boolean notifyMe = this.recipeListener.isNotifyMe(); 1401 1402 manager.inputDataTable(this, aCurrentVar, notifyMe); 1403 } 1404 1405 @SuppressWarnings({ "unchecked" }) 1406 @CommandExamples({ "<Loop name='type:property' source='type:property' numbers='type:integer'> ... </Loop>", 1407 "<Loop numbers='type:integer'> ... </Loop>", 1408 "<Loop name='type:property' query='select * from ...' maxCount='type:integer'> ... </Loop>" }) 1409 public void runCommandLoop(final Node aCurrentVar) throws Throwable { 1410 String theDescript = replaceProperties(aCurrentVar.getAttribute("description")); 1411 final String theNameAttribut = attr(aCurrentVar, "name"); 1412 boolean mainLoopCommand = false; 1413 1414 final String theNumbers = StringUtils.trimToNull(replaceProperties(aCurrentVar.getAttribute("numbers"))); 1415 if (theDescript == null) { 1416 theDescript = "Loop"; 1417 } 1418 String sourceAttribute = aCurrentVar.getAttribute("source"); 1419 final String theAttribut = replaceProperties(sourceAttribute); 1420 Object loopArrayVar = null; 1421 if (theAttribut != null) { 1422 loopArrayVar = getVariableValue(theAttribut); 1423 } 1424 List<Object> theLoopArray = new ArrayList<>(); 1425 if (loopArrayVar != null) { 1426 if (loopArrayVar instanceof String) { 1427 theLoopArray.add((String) loopArrayVar); 1428 } else if (loopArrayVar instanceof String[]) { 1429 List<String> asList = Arrays.asList((String[]) loopArrayVar); 1430 theLoopArray.addAll(asList); 1431 } else if (loopArrayVar instanceof List) { 1432 theLoopArray = (List<Object>) loopArrayVar; 1433 } else if (loopArrayVar instanceof Map) { 1434 Map map = (Map) loopArrayVar; 1435 theLoopArray.addAll(map.keySet()); 1436 } else if (loopArrayVar instanceof JSONArray) { 1437 JSONArray array = (JSONArray) loopArrayVar; 1438 theLoopArray = array.toList(); 1439 } else { 1440 return; 1441 } 1442 } 1443 int theCount = 0; 1444 boolean infinityLoop = false; 1445 if (StringUtils.isNotBlank(theNumbers)) { 1446 theCount = (int) Double.parseDouble(theNumbers); 1447 } else { 1448 if (!theLoopArray.isEmpty()) { 1449 theCount = theLoopArray.size(); 1450 } else { 1451 infinityLoop = sourceAttribute == null; 1452 } 1453 } 1454 if (isLoopActivated() == false) { 1455 this.mainLoopCommand = true; 1456 mainLoopCommand = true; 1457 } 1458 try { 1459 for (int i = 0; (i < theCount || infinityLoop) && isStopped() == false; i++) { 1460 if (isStopped()) { 1461 break; 1462 } 1463 if (this.breakFlag > 0) { 1464 break; 1465 } 1466 if ((mainLoopCommand && !infinityLoop) || theCount > 5) { 1467 this.recipeListener.setProgress(theDescript, theCount, i, false); 1468 } 1469 startCommandInformation(aCurrentVar); 1470 if (theLoopArray != null && theLoopArray.size() > 0) { 1471 if (i < theLoopArray.size()) { 1472 setVariableValue(theNameAttribut, theLoopArray.get(i)); 1473 } 1474 } else { 1475 setVariableValue(theNameAttribut, ObjectUtils.toString(i)); 1476 } 1477 taskNode(aCurrentVar, false); 1478 } 1479 } finally { 1480 if (this.breakFlag > 0) { 1481 breakFlag--; 1482 } 1483 if (mainLoopCommand) { 1484 this.mainLoopCommand = false; 1485 } 1486 } 1487 } 1488 1489 @CommandExamples({ "<Append name='type:property' value='' type='unique'/>", 1490 "<Append name='type:property'>...</Append>" }) 1491 public synchronized void runCommandAppend(final Node aCurrentVar) throws Throwable { 1492 final String name = aCurrentVar.getAttribute("name"); 1493 Object value = attr(aCurrentVar, "value"); 1494 if (value == null) { 1495 value = replaceProperties(aCurrentVar.getInnerText()); 1496 } 1497 1498 String source = aCurrentVar.getAttribute("source"); 1499 if (source != null) { 1500 value = getVariableValue(replaceProperties(source)); 1501 } 1502 1503 final Object theOldValue = getVariableValue(name, false); 1504 if (theOldValue == null) { 1505 return; 1506 } 1507 if (theOldValue instanceof String) { 1508 final String theValue1 = (String) theOldValue; 1509 value = theValue1 + value; 1510 setVariableValue(name, value); 1511 1512 } else if (theOldValue instanceof Object[]) { 1513 final boolean theUniqueTypeAttribut = "unique".equals(aCurrentVar.getAttribute("type")); 1514 1515 final String[] theValue1 = (String[]) theOldValue; 1516 String[] theValue2 = null; 1517 1518 if (theUniqueTypeAttribut) { 1519 Set<String> targetSet = new LinkedHashSet<>(Arrays.asList(theValue1)); 1520 if (value instanceof String) { 1521 targetSet.add((String) value); 1522 } else if (value instanceof String[]) { 1523 for (String val : (String[]) value) { 1524 targetSet.add(val); 1525 } 1526 } 1527 1528 String[] array = new String[targetSet.size()]; 1529 Iterator<String> iterator = targetSet.iterator(); 1530 int i = 0; 1531 while (iterator.hasNext()) { 1532 String object = (String) iterator.next(); 1533 array[i++] = object; 1534 } 1535 1536 theValue2 = array; 1537 1538 } else { 1539 List<String> targetList = new ArrayList<>(Arrays.asList(theValue1)); 1540 if (value instanceof String[]) { 1541 for (String val : (String[]) value) { 1542 targetList.add(val); 1543 } 1544 } else { 1545 targetList.add((String) value); 1546 } 1547 1548 String[] array = new String[targetList.size()]; 1549 int i = 0; 1550 for (Object val : targetList) { 1551 if (val instanceof String) { 1552 array[i++] = (String) val; 1553 } else { 1554 array[i++] = ObjectUtils.toString(val); 1555 } 1556 } 1557 1558 theValue2 = array; 1559 } 1560 1561 applyResult(aCurrentVar, name, theValue2); 1562 } 1563 } 1564 1565 @CommandExamples({ "<Rnd name='type:property' symbols='type:integer' type='enum:number|default'/>", 1566 "<Rnd name='type:property' type='uuid'/>", 1567 "<Rnd name='type:property' symbols='type:integer' startCode='type:integer' endCode='type:integer'/>", 1568 "<Rnd name='type:property' source='type:property'/>" }) 1569 public void runCommandRnd(final Node aCurrentVar) throws Throwable { 1570 final String theNameAttribut = replaceProperties(aCurrentVar.getAttribute("name")); 1571 String result = null; 1572 String type = replaceProperties(aCurrentVar.getAttribute("type")); 1573 1574 if ("uuid".equalsIgnoreCase(type)) { 1575 result = UUID.randomUUID().toString(); 1576 1577 } else { 1578 final String source = replaceProperties(aCurrentVar.getAttribute("source")); 1579 if (this.random == null) { 1580 this.random = SecureRandom.getInstance("SHA1PRNG"); 1581 } 1582 if (source != null) { 1583 Object value = getVariableValue(source); 1584 if (value instanceof String[]) { 1585 String[] strings = (String[]) value; 1586 int index = this.random.nextInt(strings.length); 1587 value = strings[index]; 1588 } 1589 setVariableValue(theNameAttribut, value); 1590 return; 1591 } 1592 1593 final String theSymbolsAttribut = replaceProperties(aCurrentVar.getAttribute("symbols")); 1594 1595 final long theBegNum = Long.parseLong(theSymbolsAttribut); 1596 int startCode = 0x41; 1597 final String startCodeStr = replaceProperties(aCurrentVar.getAttribute("startCode")); 1598 if (startCodeStr != null) { 1599 if (startCodeStr.indexOf('x') > 0) { 1600 startCode = Integer.parseInt(startCodeStr.substring(2), 16); 1601 } else { 1602 startCode = Integer.parseInt(startCodeStr); 1603 } 1604 type = "-number"; 1605 } 1606 1607 int endCode = 0x05A; 1608 final String endCodeStr = replaceProperties(aCurrentVar.getAttribute("endCode")); 1609 if (endCodeStr != null) { 1610 if (endCodeStr.indexOf('x') > 0) { 1611 endCode = Integer.parseInt(endCodeStr.substring(2), 16); 1612 } else { 1613 endCode = Integer.parseInt(endCodeStr); 1614 } 1615 type = "-number"; 1616 } 1617 1618 if ("number".equals(type) == false) { 1619 final StringBuffer theBuffer = new StringBuffer(); 1620 for (int i = 0; i < theBegNum; i++) { 1621 theBuffer.append((char) (this.random.nextInt(endCode - startCode) + startCode)); 1622 } 1623 result = theBuffer.toString(); 1624 } else { 1625 final StringBuffer theBuffer = new StringBuffer(); 1626 for (int i = 0; i < theBegNum; i++) { 1627 theBuffer.append(this.random.nextInt(9)); 1628 } 1629 result = theBuffer.toString(); 1630 } 1631 } 1632 1633 setVariableValue(theNameAttribut, result); 1634 } 1635 1636 @CommandExamples({ "<Inc name='type:property' increase=''/>" }) 1637 public void runCommandInc(final Node aCurrentVar) throws Throwable { 1638 String theValueAttribut = aCurrentVar.getAttribute("increase"); 1639 theValueAttribut = replaceProperties(theValueAttribut); 1640 long theIncLong = 1; 1641 if (theValueAttribut != null) { 1642 theIncLong = Long.parseLong(theValueAttribut); 1643 } 1644 final String theAttribut = aCurrentVar.getAttribute("name"); 1645 Object theOldValue = getVariableValue(theAttribut); 1646 1647 if (!(theOldValue instanceof Object[])) { 1648 theOldValue = ObjectUtils.toString(theOldValue, null); 1649 } 1650 1651 if (theOldValue instanceof String) { 1652 final long theLongValue = Long.parseLong((String) theOldValue) + theIncLong; 1653 setVariableValue(theAttribut, Long.toString(theLongValue)); 1654 } 1655 if (theOldValue instanceof String[] && ((String[]) theOldValue).length > 0) { 1656 final long theLongValue = Long.parseLong(((String[]) theOldValue)[0]) + theIncLong; 1657 setVariableValue(theAttribut, Long.toString(theLongValue)); 1658 } else { 1659 new ClassCastException("Tag <Inc> enabled only one number argument."); 1660 } 1661 } 1662 1663 @CommandExamples({ "<If name='' startsWith='' endsWith='' contains='' equals='' notEqual=''> ... </If>", 1664 "<If value='' startsWith='' endsWith='' contains='' equals='' notEqual=''> ... <Else> ... </Else></If>", 1665 "<If expression=''> ... </If>", "<If isNull=''> ... </If>", "<If isNotNull=''> ... </If>" }) 1666 public void runCommandIf(final Node action) throws Throwable { 1667 runIf(action); 1668 } 1669 1670 private boolean runIf(final Node action) throws CommandException, Throwable, ClassNotFoundException { 1671 String theExpressionAttribut = action.getAttribute("expression"); 1672 String isNull = action.getAttribute("isNull"); 1673 String isNotNull = action.getAttribute("isNotNull"); 1674 String nameAttr = attr(action, "name"); 1675 1676 String valueAttr = action.getAttribute("value"); 1677 1678 String theValue1Attribut = action.getAttribute("value1"); 1679 String theValue2Attribut = action.getAttribute("value2"); 1680 String theConditionAttribut = action.getAttribute("condition"); 1681 1682 boolean result = false; 1683 if (nameAttr != null || valueAttr != null) { 1684 Object variableValue = getVariableValue(nameAttr); 1685 String value; 1686 1687 if (variableValue == null) { 1688 value = replaceProperties(valueAttr); 1689 } else { 1690 if (variableValue instanceof String[]) { 1691 value = StringUtils.join((String[]) variableValue, "\n"); 1692 } else { 1693 value = ObjectUtils.toString(variableValue); 1694 } 1695 } 1696 1697 String startsWith = attr(action, "startsWith"); 1698 String endsWith = attr(action, "endsWith"); 1699 String contains = attr(action, "contains"); 1700 String equals = attr(action, "equals"); 1701 String regex = attr(action, "regex"); 1702 String notEqual = attr(action, "notEqual"); 1703 1704 boolean ignoreCase = Boolean.valueOf(attr(action, "ignoreCase", "false")); 1705 1706 boolean condition1 = startsWith == null || (ignoreCase ? StringUtils.startsWithIgnoreCase(value, startsWith) 1707 : StringUtils.startsWith(value, startsWith)); 1708 boolean condition2 = endsWith == null || (ignoreCase ? StringUtils.endsWithIgnoreCase(value, endsWith) 1709 : StringUtils.endsWith(value, endsWith)); 1710 boolean condition3 = contains == null || (ignoreCase ? StringUtils.containsIgnoreCase(value, contains) 1711 : StringUtils.contains(value, contains)); 1712 boolean condition4 = equals == null 1713 || (ignoreCase ? StringUtils.equalsIgnoreCase(value, equals) : StringUtils.equals(value, equals)); 1714 1715 boolean condition5 = true; 1716 if (regex != null) { 1717 final Pattern p = Pattern.compile(regex); 1718 final Matcher m = p.matcher(value); 1719 condition5 = m.find(); 1720 } 1721 1722 boolean condition6 = notEqual == null || (ignoreCase ? !StringUtils.equalsIgnoreCase(value, notEqual) 1723 : !StringUtils.equals(value, notEqual)); 1724 1725 result = condition1 && condition2 && condition3 && condition4 && condition5 && condition6; 1726 execIf(action, result); 1727 return result; 1728 } else if (isNull != null) { 1729 result = getVariableValue(replaceProperties(isNull)) == null; 1730 execIf(action, result); 1731 return result; 1732 } else if (isNotNull != null) { 1733 Object variableValue = getVariableValue(replaceProperties(isNotNull)); 1734 result = variableValue != null; 1735 execIf(action, result); 1736 return result; 1737 } else if (theExpressionAttribut != null) { 1738 theExpressionAttribut = replaceProperties(theExpressionAttribut); 1739 JexlEngine jexl = new JexlBuilder().create(); 1740 1741 JexlExpression expr_c = jexl.createExpression(theExpressionAttribut); 1742 JexlContext context = new MapContext(); 1743 1744 if (expr_c != null) { 1745 Object val = expr_c.evaluate(context); 1746 result = "true".equals(val.toString()); 1747 } 1748 1749 execIf(action, result); 1750 return result; 1751 } else if (theValue1Attribut != null || theValue2Attribut != null) { 1752 if (theConditionAttribut == null) { 1753 theConditionAttribut = "=="; 1754 } 1755 theValue1Attribut = replaceProperties(theValue1Attribut); 1756 theValue2Attribut = replaceProperties(theValue2Attribut); 1757 1758 if ("==".equals(theConditionAttribut) && theValue1Attribut.equals(theValue2Attribut)) { 1759 taskNode(action, false); 1760 result = true; 1761 } else if (("!=".equals(theConditionAttribut) || "unequal".equals(theConditionAttribut)) 1762 && (theValue1Attribut.equals(theValue2Attribut) == false)) { 1763 taskNode(action, false); 1764 result = true; 1765 } else if ("less".equals(theConditionAttribut) 1766 && (Long.parseLong(theValue1Attribut) < Long.parseLong(theValue2Attribut))) { 1767 taskNode(action, false); 1768 result = true; 1769 } else if ("bigger".equals(theConditionAttribut) 1770 && (Long.parseLong(theValue1Attribut) > Long.parseLong(theValue2Attribut))) { 1771 taskNode(action, false); 1772 result = true; 1773 } else { 1774 for (Node command : action.getNodes("Else")) { 1775 taskNode(command, false); 1776 } 1777 } 1778 } 1779 1780 return result; 1781 } 1782 1783 private void execIf(final Node action, boolean result) throws CommandException, Throwable { 1784 if (result) { 1785 taskNode(action, false); 1786 } else { 1787 for (Node command : action.getNodes("Else")) { 1788 if (command.getAttribute("name") == null && action.getAttribute("name") != null) { 1789 command.setAttribute("name", action.getAttribute("name")); 1790 } 1791 if (command.getAttribute("value") == null && action.getAttribute("value") != null) { 1792 command.setAttribute("value", action.getAttribute("value")); 1793 } 1794 if (command.getAttribute("name") != null || command.getAttribute("value") != null) { 1795 if (runIf(command)) { 1796 break; 1797 } 1798 } else { 1799 taskNode(command); 1800 } 1801 } 1802 } 1803 } 1804 1805 @CommandExamples({ "<While name='' startsWith='' endsWith='' contains='' equals='' notEqual=''> ... </While>", 1806 "<While value1='' value2='' condition='unequal'> ... <Else value1='' value2='' condition=''> ... </Else></While>", 1807 "<While expression=''> ... </While>", "<While isNull=''> ... </While>", 1808 "<While isNotNull=''> ... </While>" }) 1809 public void runCommandWhile(final Node aCurrentVar) throws Throwable { 1810 try { 1811 for (; runIf(aCurrentVar);) { 1812 if (this.breakFlag > 0) { 1813 break; 1814 } 1815 } 1816 } finally { 1817 if (this.breakFlag > 0) { 1818 breakFlag--; 1819 } 1820 } 1821 } 1822 1823 @CommandExamples({ "<Pragma event='console-input' action='default'/>", 1824 "<Pragma event='random-select' action='on'/>", "<Pragma event='log-window' action='single'/>" }) 1825 public void runCommandPragma(final Node aCurrentVar) throws Throwable { 1826 final String theEventAttribut = aCurrentVar.getAttribute("event"); 1827 final String theActionAttribut = aCurrentVar.getAttribute("action"); 1828 1829 if ("console-input".equals(theEventAttribut)) { 1830 boolean consoleDefaultInput = "default".equals(theActionAttribut); 1831 getListener().getManager().setConsoleDefaultInput(consoleDefaultInput); 1832 } else if ("random-select".equals(theEventAttribut)) { 1833 randomSelect = "on".equals(theActionAttribut); 1834 } else { 1835 this.log.error("Pragma ignored. Event: " + theEventAttribut); 1836 } 1837 } 1838 1839 @SuppressWarnings("unchecked") 1840 @CommandExamples({ 1841 "<Threads name='type:property' threadLog='true' numbers='type:integer' multi='enum:true|false' />", 1842 "<Threads numbers='type:integer' multi='enum:true|false' mode='enum:wait|nowait'><Out name='" 1843 + TaskProcessorThread.THREAD_ID + "'/></Threads>", 1844 "<Threads multi='enum:true|false'><Out name='" + TaskProcessorThread.THREAD_ID + "'/></Threads>" }) 1845 @CommandHotHepl("<html>Attribute name should be <b>List<Runnable><b/> type.<br/>In this case <Threads> commands don't have any tag inside.</html>") 1846 public void runCommandThreads(final Node aCurrentAction) throws InterruptedException, CommandException { 1847 1848 boolean threadLog = Boolean 1849 .parseBoolean(StringUtils.defaultIfBlank(attr(aCurrentAction, "threadLog"), "false")); 1850 int numbers = Integer.parseInt(StringUtils.defaultIfBlank(attr(aCurrentAction, "numbers"), "1")); 1851 boolean multi = Boolean.parseBoolean(StringUtils.defaultIfBlank(attr(aCurrentAction, "multi"), "true")); 1852 1853 ThreadPoolExecutor threadPool; 1854 if (multi) { 1855 if (numbers > 0) { 1856 threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(numbers); 1857 } else { 1858 threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 1859 } 1860 } else { 1861 threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(1); 1862 } 1863 1864 String callableListName = attr(aCurrentAction, "name"); 1865 if (callableListName == null) { 1866 final Iterator<?> theIterator = aCurrentAction.iterator(); 1867 1868 if (numbers == 0) { 1869 while (theIterator.hasNext()) { 1870 final Node theNode = (Node) theIterator.next(); 1871 1872 String theNameThreads = getTestName(theNode); 1873 if (theNameThreads == null) { 1874 theNameThreads = "Thread"; 1875 } 1876 1877 ILogger theLog = this.log; 1878 if (threadLog) { 1879 theLog = this.recipeListener.createLog(theNameThreads, false); 1880 } 1881 1882 final TaskProcessorThread runnable = new TaskProcessorThread(this, theNode, getBaseDir(), theLog); 1883 1884 threadPool.execute(runnable); 1885 1886 } 1887 } else { 1888 final Node theNode = (Node) aCurrentAction.clone(); 1889 theNode.setTag("Task"); 1890 theNode.removeAttribute(callableListName); 1891 1892 for (int i = 0; i < numbers; i++) { 1893 String theNameThreads = getTestName(theNode); 1894 String logName = "Thread #" + i; 1895 if (theNameThreads != null) { 1896 logName = theNameThreads + " #" + i; 1897 } 1898 1899 ILogger theLog = this.log; 1900 if (threadLog) { 1901 theLog = this.recipeListener.createLog(logName, false); 1902 } 1903 1904 final TaskProcessorThread runnable = new TaskProcessorThread(this, theNode, getBaseDir(), theLog); 1905 runnable.getVaribleValue(TaskProcessorThread.THREAD_ID, String.valueOf(i)); 1906 1907 threadPool.execute(runnable); 1908 } 1909 } 1910 1911 } else { 1912 Object callableList = getVariableValue(callableListName); 1913 if (callableList instanceof List) { 1914 for (Runnable runnable : (List<Runnable>) callableList) { 1915 threadPool.execute(runnable); 1916 } 1917 } else if (callableList instanceof Runnable) { 1918 for (int i = 0; i < numbers; i++) { 1919 if (callableList instanceof TaskProcessorThread) { 1920 threadPool.execute(((TaskProcessorThread) callableList).clone(i)); 1921 } else { 1922 threadPool.execute((Runnable) callableList); 1923 } 1924 } 1925 } else { 1926 throw new IllegalArgumentException( 1927 "Variable of type must be Runnable oa List<Runnable>, actually: " + callableList); 1928 } 1929 } 1930 1931 String description = replaceProperties(aCurrentAction.getAttribute("description")); 1932 1933 long completedTaskCount = 0; 1934 long size = threadPool.getTaskCount(); 1935 1936 threadPoolList.add(threadPool); 1937 do { 1938 completedTaskCount = threadPool.getCompletedTaskCount(); 1939 progress(size, completedTaskCount, description, false); 1940 Thread.sleep(200); 1941 1942 } while (completedTaskCount < size); 1943 threadPoolList.remove(threadPool); 1944 } 1945 1946 @CommandExamples({ "<Task name='type:task' />", "<Task name='type:task' mode='async' optional='optional'/>", 1947 "<Task> ... </Task>", "<Task file='type:path' />" }) 1948 public void runCommandTask(final Node action) throws Throwable { 1949 1950 final boolean optional = Boolean.valueOf(attr(action, "optional", "false")); 1951 1952 final String taskName = replaceProperties(action.getAttribute("name")); 1953 String taskFile = replaceProperties(action.getAttribute("file")); 1954 1955 if (taskFile == null) { 1956 if (taskName != null) { 1957 taskFile = getListener().getManager().getTestPath(taskName); 1958 1959 if (taskFile == null) { 1960 if (optional) { 1961 return; 1962 } else { 1963 throw new Exception("Task with name: '" + taskName + "' not found."); 1964 } 1965 } 1966 } 1967 } else { 1968 if (!(new File(taskFile)).exists()) { 1969 if (optional) { 1970 return; 1971 } else { 1972 throw new Exception("Task with name: '" + taskFile + "' not found."); 1973 } 1974 } 1975 } 1976 1977 final File theBaseDir = getBaseDir(); 1978 try { 1979 if (taskName != null) { 1980 String mode = replaceProperties(action.getAttribute("mode")); 1981 if ("async".equals(mode)) { 1982 getListener().getManager().runTask(taskName, true); 1983 1984 } else { 1985 Properties taskParameters = MapUtils.toProperties(action.getAttributes()); 1986 Set<Entry<Object, Object>> entrySet = taskParameters.entrySet(); 1987 1988 String currentLogLevel = (String) this.variables.get(DEFAULT_LOG_LEVEL_NAME); 1989 String level = (String) taskParameters.get("level"); 1990 1991 for (Entry<Object, Object> entry : entrySet) { 1992 String name = (String) entry.getKey(); 1993 if (!"$ID".equals(name) && !"name".equals(name) && !"file".equals(name) 1994 && !"level".equals(name)) { 1995 String value = replaceProperties((String) entry.getValue()); 1996 this.variables.put(toUpperCaseName(name), value); 1997 } 1998 } 1999 2000 this.variables.put(DEFAULT_LOG_LEVEL_NAME, level); 2001 this.variables = processTesting(taskFile, this.variables, getBaseDir()); 2002 this.variables.put(DEFAULT_LOG_LEVEL_NAME, currentLogLevel); 2003 } 2004 } else { 2005 taskNode(action, false); 2006 } 2007 } finally { 2008 setBaseDir(theBaseDir); 2009 } 2010 } 2011 2012 @CommandExamples({ "<IterationRules name='type:property'><Out name='Iteration'/></IterationRules>", 2013 "<IterationRules name='type:property' timeLimit='type:minutes' start='type:integer'> ... </IterationRules>", 2014 "<Var name='rules'>#\n[multiple]\na=1\nb $enum=1;2\nc $inc=0;10\nd $file=file_name\n[single]\n...\n[concurrently]\n...\n[independent]\n...\n#</Var><IterationRules name='rules'><Out name='Iteration'/></IterationRules>", }) 2015 public void runCommandIterationRules(final Node action) throws IOException, CommandException { 2016 final String name = (String) attrValue(action, "name"); 2017 String theTimeAttribut = action.getAttribute("timeLimit"); 2018 String theStartAttribut = action.getAttribute("start"); 2019 2020 if (theTimeAttribut == null) { 2021 theTimeAttribut = "3"; 2022 } 2023 final long theLimit = Long.parseLong(theTimeAttribut); 2024 2025 if (theStartAttribut == null) { 2026 theStartAttribut = "0"; 2027 } 2028 2029 final int theStart = Integer.parseInt(theStartAttribut); 2030 if (name == null) { 2031 throw new CommandException("In tag <IterationRules> variable rules is not defined.", this); 2032 } 2033 try { 2034 this.iteratorMode = true; 2035 final TestIterator theTestIterator = new TestIterator(this, name); 2036 final int theMax = theTestIterator.count(); 2037 progress(theMax, 0, "Iteration process", false); 2038 debug("Iteration block. Total count: " + theMax); 2039 final long theStertTime = System.currentTimeMillis(); 2040 for (int i = theStart; i < theMax; i++) { 2041 if (isStopped()) { 2042 break; 2043 } 2044 setVariableValue("Iteration", Integer.toString(i + 1)); 2045 theTestIterator.nextIteration(this); 2046 2047 taskNode(action, false); 2048 2049 progress(theMax, i, "Iteration process", false); 2050 if (i == 0) { 2051 long theTotalTime = ((System.currentTimeMillis() - theStertTime) * theMax) / 60000; 2052 debug("Total Iteration time: " + Long.toString(theTotalTime) + " min."); 2053 if (theTotalTime > theLimit) { 2054 int theConfirm = 0; 2055 if (this.recipeListener.getManager() != null) { 2056 if (this.recipeListener.getManager().isConsoleDefaultInput(attr(action, "name"), 2057 attr(action, "description")) == false) { 2058 if (theTotalTime < 60) { 2059 theConfirm = JOptionPane.showConfirmDialog( 2060 JOptionPane.getRootFrame(), "Total Iteration time: " 2061 + Long.toString(theTotalTime) + " min. \nContinue?", 2062 "Warning", JOptionPane.YES_NO_OPTION); 2063 } else { 2064 theTotalTime /= 60; 2065 theConfirm = JOptionPane.showConfirmDialog(JOptionPane.getRootFrame(), 2066 "Total Iteration time: " + Long.toString(theTotalTime) + " h. \nContinue?", 2067 "Warning", JOptionPane.YES_NO_OPTION); 2068 } 2069 } 2070 if (theConfirm != JOptionPane.YES_OPTION) { 2071 break; 2072 } 2073 } 2074 } 2075 } 2076 } 2077 } finally { 2078 this.iteratorMode = false; 2079 } 2080 } 2081 2082 @CommandExamples({ "<Listdir path='type:path' name='type:property'/>", 2083 "<Listdir path='type:path' name='type:property' tree='true'/>" }) 2084 public void runCommandListdir(final Node aCurrentVar) throws Throwable { 2085 final String thePathAttribut = replaceProperties(aCurrentVar.getAttribute("path")); 2086 final String theNameAttribut = replaceProperties(aCurrentVar.getAttribute("name")); 2087 File theFile = getFile(thePathAttribut); 2088 2089 if (isActiveInitFor(aCurrentVar, "console")) { 2090 String path = this.recipeListener.getManager().inputFile(theNameAttribut, null, theFile, log, this); 2091 if (path != null) { 2092 theFile = new File(path); 2093 } 2094 } 2095 2096 if (theFile != null) { 2097 debug("Listing of directory: " + theFile.getAbsolutePath()); 2098 2099 String[] theValue = null; 2100 if ("true".equals(attr(aCurrentVar, "tree"))) { 2101 @SuppressWarnings("unchecked") 2102 Collection<File> files = FileUtils.listFiles(theFile, TrueFileFilter.TRUE, TrueFileFilter.TRUE); 2103 if (files != null) { 2104 theValue = new String[files.size()]; 2105 int i = 0; 2106 for (File file : files) { 2107 theValue[i++] = file.getAbsolutePath(); 2108 } 2109 } 2110 } else { 2111 int i = 0; 2112 File[] listFiles = theFile.listFiles(); 2113 if (listFiles != null) { 2114 theValue = new String[listFiles.length]; 2115 for (File file : listFiles) { 2116 theValue[i++] = file.getAbsolutePath(); 2117 } 2118 } 2119 } 2120 2121 if (theValue != null) { 2122 Arrays.sort(theValue); 2123 setVariableValue(theNameAttribut, theValue); 2124 } 2125 } else { 2126 throw new TaskCancelingException(); 2127 } 2128 } 2129 2130 @CommandExamples({ "<Textparser text='' start='' end='' path='type:path' name='type:property'/>" }) 2131 public void runCommandTextparser(final Node aCurrentVar) throws Throwable { 2132 final String theTextAttribut = replaceProperties(aCurrentVar.getAttribute("text")); 2133 String theStartKey = replaceProperties(aCurrentVar.getAttribute("start")); 2134 String theEndKey = replaceProperties(aCurrentVar.getAttribute("end")); 2135 if (theStartKey == null) { 2136 theStartKey = "${"; 2137 } 2138 if (theEndKey == null) { 2139 theEndKey = "}$"; 2140 } 2141 int theBeginPos = 0; 2142 int theEndPos = 0; 2143 while (true) { 2144 theBeginPos = theTextAttribut.indexOf(theStartKey, theEndPos); 2145 if (theBeginPos < 0) { 2146 break; 2147 } 2148 theEndPos = theTextAttribut.indexOf(theEndKey, theBeginPos); 2149 if (theEndPos < 0) { 2150 throw new Exception("Source text is incorrect, absent symbol '" + theEndKey + "'."); 2151 } 2152 final String theLine = theTextAttribut.substring(theBeginPos + theStartKey.length(), theEndPos); 2153 final int thePbrk = theLine.indexOf('='); 2154 final String theName = replaceProperties(theLine.substring(0, thePbrk)); 2155 final String theValue = replaceProperties(theLine.substring(thePbrk + 1)); 2156 setVariableValue(theName, theValue); 2157 theEndPos += theEndKey.length(); 2158 } 2159 } 2160 2161 @CommandHotHepl("<html></html>") 2162 @CommandExamples({ "<NetworkInterfaces name='type:property' />", 2163 "<NetworkInterfaces name='type:property' host='' filterFor=''/>" }) 2164 public void runCommandNetworkInterfaces(final Node aCurrentAction) throws SocketException, UnknownHostException { 2165 final String name = replaceProperties(aCurrentAction.getAttribute("name")); 2166 String host = replaceProperties(aCurrentAction.getAttribute("host")); 2167 2168 if (host == null) { 2169 Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); 2170 Set<String> hostIps = new HashSet<>(); 2171 while (networkInterfaces.hasMoreElements()) { 2172 NetworkInterface nextElement = networkInterfaces.nextElement(); 2173 Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses(); 2174 while (inetAddresses.hasMoreElements()) { 2175 InetAddress nextElement2 = inetAddresses.nextElement(); 2176 if (nextElement2 instanceof Inet4Address) { 2177 Inet4Address address = (Inet4Address) nextElement2; 2178 String hostAddress = address.getHostAddress(); 2179 hostIps.add(hostAddress); 2180 } 2181 } 2182 } 2183 setVariableValue(name, new ArrayList<>(hostIps)); 2184 } else { 2185 try { 2186 URL url = new URL(host); 2187 host = url.getHost(); 2188 } catch (Exception e) { 2189 2190 } 2191 2192 InetAddress address1 = InetAddress.getByName(host); 2193 setVariableValue(name, address1.getHostAddress()); 2194 } 2195 } 2196 2197 @CommandExamples({ "<CheckProperties map='' type='' onErrorMsg='' caption='' columnsize='' mark=''/>" }) 2198 public void runCommandCheckProperties(final Node aCurrentVar) throws Throwable { 2199 final String theMapFileAttribut = replaceProperties(aCurrentVar.getAttribute("map")); 2200 final String theTypeAttribut = replaceProperties(aCurrentVar.getAttribute("type")); 2201 final String theErrorMsg = replaceProperties(aCurrentVar.getAttribute("onErrorMsg")); 2202 String theCommentAttribut = replaceProperties(aCurrentVar.getAttribute("caption")); 2203 if (theCommentAttribut == null) { 2204 theCommentAttribut = "Check;Left;Right;Left value;Right value;Rule"; 2205 } 2206 String theSizeAttribut = replaceProperties(aCurrentVar.getAttribute("columnsize")); 2207 if (theSizeAttribut == null) { 2208 theSizeAttribut = "6;24;24;20;64;40"; 2209 } 2210 String theMark = replaceProperties(aCurrentVar.getAttribute("mark")); 2211 if (theMark == null) { 2212 theMark = " "; 2213 } 2214 String theLine = null; 2215 final BufferedReader theFileReader = new BufferedReader( 2216 new FileReader(new File(getBaseDir(), theMapFileAttribut))); 2217 try { 2218 2219 final StringBuffer theBufferText = new StringBuffer(); 2220 theBufferText.append("Checking value of properties:\n"); 2221 boolean theResult = false; 2222 boolean theFirstIniResult = false; 2223 StringTokenizer theTokenizer = new StringTokenizer(theCommentAttribut, ";"); 2224 final int theNumberColumn = theTokenizer.countTokens(); 2225 final String[] theCaption = new String[theNumberColumn]; 2226 for (int i = 0; i < theNumberColumn; i++) { 2227 theCaption[i] = theTokenizer.nextToken(); 2228 } 2229 theTokenizer = new StringTokenizer(theSizeAttribut, ";"); 2230 final int theNumberColumnTable = theTokenizer.countTokens(); 2231 final int[] theSizeCaption = new int[theNumberColumnTable]; 2232 for (int i = 0; i < theNumberColumnTable; i++) { 2233 theSizeCaption[i] = Integer.parseInt(theTokenizer.nextToken()); 2234 } 2235 appendTableLine(theBufferText, theSizeCaption, theCaption, " "); 2236 Object theValue1 = null, theValue2 = null; 2237 2238 boolean theFailed = false; 2239 while ((theLine = theFileReader.readLine()) != null) { 2240 theLine = theLine.trim(); 2241 if (theLine.length() == 0) { 2242 continue; 2243 } 2244 if (theLine.charAt(0) == '#') { 2245 appendTableLine(theBufferText, theSizeCaption, new String[] { theLine.substring(1).trim() }, " "); 2246 continue; 2247 } 2248 final int thePbrk = theLine.indexOf('='); 2249 final String theRuleLitteral = "@rule:"; 2250 int thePbrkRule = theLine.indexOf(theRuleLitteral); 2251 String theRule = null; 2252 boolean theCasesensitive = false; 2253 String theOperationRule = null; 2254 String theParameterRule = null; 2255 if (thePbrkRule >= 0) { 2256 theRule = theLine.substring(thePbrkRule + theRuleLitteral.length()); 2257 final String theCasesensitiveLitteral = "casesensitive:"; 2258 final int thePbrkCasesensitive = theRule.indexOf(theCasesensitiveLitteral); 2259 String theRuleLine = theRule; 2260 if (thePbrkCasesensitive >= 0) { 2261 theRuleLine = theRule.substring(thePbrkCasesensitive + theCasesensitiveLitteral.length()); 2262 theCasesensitive = true; 2263 } 2264 final String theOperationRuleEndLitteral = ":"; 2265 final int thePbrkOperationRuleEnd = theRule.indexOf(theOperationRuleEndLitteral); 2266 if (thePbrkOperationRuleEnd >= 0) { 2267 theOperationRule = theRuleLine.substring(0, thePbrkOperationRuleEnd); 2268 theParameterRule = theRuleLine.substring(thePbrkOperationRuleEnd + 1); 2269 } 2270 } else { 2271 thePbrkRule = theLine.length(); 2272 } 2273 String theLeftLine = theLine.substring(0, thePbrk); 2274 final String thePropLeft = replaceProperties(theLeftLine); 2275 String theRightLine = theLine.substring(thePbrk + 1, thePbrkRule); 2276 final String thePropRight = replaceProperties(theRightLine); 2277 Object theValueLeftObject = thePropLeft; 2278 Object theValueRightObject = thePropRight; 2279 if ("name".equals(theTypeAttribut)) { 2280 String theData = thePropLeft.trim(); 2281 boolean theValueMode = thePropLeft != null && theData.length() >= 2 && theData.charAt(0) == '[' 2282 && theData.charAt(theData.length() - 1) == ']'; 2283 if (theValueMode == false) { 2284 theValueLeftObject = getVariableValue(theData); 2285 theLeftLine = thePropLeft; 2286 } else { 2287 theValueLeftObject = theData.substring(1, theData.length() - 1); 2288 } 2289 theData = thePropRight.trim(); 2290 theValueMode = thePropLeft != null && theData.length() >= 2 && theData.charAt(0) == '[' 2291 && theData.charAt(theData.length() - 1) == ']'; 2292 if (theValueMode == false) { 2293 theValueRightObject = getVariableValue(theData); 2294 theRightLine = thePropRight; 2295 } else { 2296 theValueRightObject = theData.substring(1, theData.length() - 1); 2297 } 2298 } 2299 if (theValueLeftObject == null) { 2300 theValueLeftObject = "null"; 2301 } 2302 if (theValueRightObject == null) { 2303 theValueRightObject = "null"; 2304 } 2305 if (theValueLeftObject instanceof String && theValueRightObject instanceof String) { 2306 // -- RULE -- 2307 theResult = ruleTranslate(theCasesensitive, (String) (theValueLeftObject), 2308 (String) theValueRightObject, theOperationRule, theParameterRule); 2309 if (theResult == false && theFirstIniResult == false) { 2310 theValue1 = theValueLeftObject; 2311 theValue2 = theValueRightObject; 2312 theFirstIniResult = true; 2313 } 2314 } else { 2315 throw new Exception("CheckProperties operation possible only String values."); 2316 } 2317 if (theResult == false) { 2318 theFailed = true; 2319 } 2320 appendTableLine(theBufferText, theSizeCaption, 2321 new Object[] { theResult ? "ok" : "failed", theLeftLine, theRightLine, theValueLeftObject, 2322 theValueRightObject, theRule != null ? theRule : new String() }, 2323 theMark); 2324 } 2325 debug(theBufferText); 2326 if (theFailed) { 2327 TestCase.assertEquals(theErrorMsg, theValue2, theValue1); 2328 throw new AssertionFailedError("Incorrect value:<" + theValue1 + ">"); 2329 } 2330 2331 } finally { 2332 theFileReader.close(); 2333 } 2334 2335 } 2336 2337 private boolean ruleTranslate(final boolean aCasesensitive, String aValue, final String aValueRightObject, 2338 final String aOperationRule, String aParameterRule) throws Exception { 2339 if ("date".equals(aOperationRule)) { 2340 final int thePbrk = aParameterRule.indexOf(';'); 2341 final String theLeft = aParameterRule.substring(0, thePbrk); 2342 final String theRight = aParameterRule.substring(thePbrk + 1); 2343 try { 2344 final DateFormat theLeftFormat = new SimpleDateFormat(theLeft); 2345 theLeftFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 2346 final DateFormat theRightFormat = new SimpleDateFormat(theRight); 2347 theRightFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 2348 ParsePosition theParsePosition = new ParsePosition(0); 2349 final Date theLeftDate = theLeftFormat.parse(aValue, theParsePosition); 2350 if (theParsePosition.getErrorIndex() > -1) { 2351 return false; 2352 } 2353 theParsePosition = new ParsePosition(0); 2354 final Date theRightDate = theRightFormat.parse(aValueRightObject, theParsePosition); 2355 if (theParsePosition.getErrorIndex() > -1) { 2356 return false; 2357 } 2358 if ((theLeftDate != null && theRightDate == null) || (theRightDate != null && theLeftDate == null)) { 2359 return true; 2360 } 2361 if (theRightDate == null || theLeftDate == null) { 2362 return false; 2363 } 2364 return theLeftDate.compareTo(theRightDate) <= 0; 2365 } catch (final Throwable e) { 2366 return false; 2367 } 2368 } 2369 if ("file".equals(aOperationRule)) { 2370 final Map<String, Object> theMapProperties = new HashMap<String, Object>(); 2371 loadProperties(getFile(aParameterRule), theMapProperties, aCasesensitive == false); 2372 if (aCasesensitive == false) { 2373 aValue = aValue.toUpperCase(); 2374 } 2375 aValue = (String) theMapProperties.get(aValue); 2376 if (aValue == null) { 2377 aValue = "null"; 2378 } 2379 } 2380 if ("map".equals(aOperationRule)) { 2381 if (aCasesensitive == false) { 2382 aParameterRule = aParameterRule.toUpperCase(); 2383 } 2384 final Map<String, Object> theMapProperties = new HashMap<String, Object>(); 2385 loadProperties(aParameterRule, ";", theMapProperties, aCasesensitive == false); 2386 if (aCasesensitive == false) { 2387 aValue = aValue.toUpperCase(); 2388 } 2389 aValue = (String) theMapProperties.get(aValue); 2390 if (aValue == null) { 2391 aValue = "null"; 2392 } 2393 } 2394 boolean theResult; 2395 if (aCasesensitive) { 2396 theResult = aValue.equals(aValueRightObject); 2397 } else { 2398 theResult = aValue.equalsIgnoreCase(aValueRightObject); 2399 } 2400 return theResult; 2401 } 2402 2403 private void appendTableLine(final StringBuffer aStringBuffer, final int[] aSizeCaption, final Object[] aStrings, 2404 final String theMark) { 2405 if (aSizeCaption.length != aStrings.length) { 2406 for (int i = 0; i < aStrings.length; i++) { 2407 aStringBuffer.append(aStrings[i]); 2408 } 2409 } else { 2410 for (int i = 0; i < aSizeCaption.length; i++) { 2411 String theString = new String("NULL"); 2412 if (aStrings[i] != null) { 2413 theString = aStrings[i].toString(); 2414 } 2415 if (theString.length() > aSizeCaption[i]) { 2416 aStringBuffer.append(theString.substring(0, aSizeCaption[i])); 2417 } else { 2418 aStringBuffer.append(theString); 2419 } 2420 final StringBuffer theSpaceBuffer = new StringBuffer(); 2421 for (int theSpace = aSizeCaption[i] - theString.length(); theSpace > 0; theSpace -= theMark.length()) { 2422 theSpaceBuffer.append(theMark); 2423 } 2424 if (aSizeCaption[i] - theString.length() > 0) { 2425 theSpaceBuffer.setLength(aSizeCaption[i] - theString.length()); 2426 aStringBuffer.append(theSpaceBuffer); 2427 } 2428 aStringBuffer.append('|'); 2429 } 2430 } 2431 aStringBuffer.append('\n'); 2432 } 2433 2434 @CommandExamples({ "<Command os=''>...</Command>", 2435 "<Command name='type:property' os='' exitValue='type:property' cmd='' noCommandLog='true' dir='~'/>", 2436 "<Command name='type:property' os='' exitValue='type:property' cmd='' noCommandLog='true' dir='~'/>...</Command>" }) 2437 public void runCommandCommand(final Node aCurrentNode) throws Throwable { 2438 2439 String command = replaceProperties(aCurrentNode.getAttribute("cmd")); 2440 final String name = replaceProperties(aCurrentNode.getAttribute("name")); 2441 final String dir = replaceProperties(aCurrentNode.getAttribute("dir")); 2442 final String os = replaceProperties(aCurrentNode.getAttribute("os")); 2443 2444 String osName = SystemUtils.OS_NAME; 2445 2446 if (os == null || Pattern.compile(os).matcher(osName).matches()) { 2447 if (command == null) { 2448 final Node[] theNodes = aCurrentNode.getTextNodes(); 2449 if (theNodes.length > 0) { 2450 command = replaceProperties(theNodes[0].getText()); 2451 } 2452 } 2453 2454 runSystemCommand(command, name, aCurrentNode, dir); 2455 } 2456 } 2457 2458 private void runSystemCommand(final String theCommandAttribut, final String theNameAttribut, 2459 final Node aCurrentNode, String dir) throws Throwable { 2460 final String prefix = "start "; 2461 if (theCommandAttribut.startsWith(prefix) == false) { 2462 2463 String regExp = "\"(\\\"|[^\"])*?\"|[^ ]+"; 2464 Pattern pattern = Pattern.compile(regExp, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); 2465 Matcher matcher = pattern.matcher(theCommandAttribut); 2466 List<String> matches = new ArrayList<String>(); 2467 while (matcher.find()) { 2468 matches.add(matcher.group()); 2469 } 2470 String[] parsedCommand = matches.toArray(new String[] {}); 2471 2472 ProcessBuilder builder = new ProcessBuilder(parsedCommand); 2473 2474 if (dir != null) { 2475 File directory; 2476 if (dir.startsWith("~/")) { 2477 dir = dir.substring(1); 2478 String recipeFile = this.recipeListener.getManager().getTestPath(testName); 2479 if (recipeFile != null) { 2480 directory = new File(new File(recipeFile).getParent(), dir); 2481 builder.directory(directory); 2482 } 2483 } else { 2484 directory = new File(dir); 2485 builder.directory(directory); 2486 } 2487 } 2488 2489 builder.redirectErrorStream(true); 2490 Process process = builder.start(); 2491 2492 final String stdin = replaceProperties(aCurrentNode.getAttribute("stdin")); 2493 if (stdin != null) { 2494 process.getOutputStream().write(stdin.getBytes()); 2495 process.getOutputStream().close(); 2496 } 2497 2498 processes.add(process); 2499 2500 final BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getInputStream())); 2501 boolean noCommandLog = Boolean.valueOf(attr(aCurrentNode, "noCommandLog")); 2502 if (!noCommandLog) { 2503 debug("Command: " + theCommandAttribut); 2504 } else { 2505 debug("Command: ****** **** *****"); 2506 } 2507 2508 try { 2509 final BufferedReader theOutputStream = new BufferedReader( 2510 new InputStreamReader(process.getInputStream())); 2511 String theLine; 2512 2513 boolean line_output = aCurrentNode.size() == 0; 2514 final StringBuffer theBuffer = new StringBuffer(); 2515 while ((theLine = theOutputStream.readLine()) != null && !isStoppedTest()) { 2516 if (breakFlag > 0) { 2517 break; 2518 } 2519 2520 if (line_output) { 2521 theBuffer.append(theLine); 2522 theBuffer.append('\n'); 2523 } else { 2524 setVariableValue(theNameAttribut, theLine); 2525 taskNode(aCurrentNode, false); 2526 } 2527 } 2528 2529 if (this.breakFlag > 0) { 2530 breakFlag--; 2531 } 2532 2533 String exitValueName = attr(aCurrentNode, "exitValue"); 2534 if (exitValueName != null) { 2535 int exitValue = 0; 2536 try { 2537 exitValue = process.exitValue(); 2538 if (exitValue > 0) { 2539 String error = IOUtils.toString(errorStream); 2540 if (StringUtils.isNotBlank(error)) { 2541 throw new RuntimeException(error); 2542 } 2543 } 2544 } catch (IllegalThreadStateException e) { 2545 // 2546 } 2547 setVariableValue(exitValueName, Integer.toString(exitValue)); 2548 } 2549 2550 if (line_output) { 2551 if (theNameAttribut == null) { 2552 debug("System output:" + theBuffer.toString()); 2553 } else { 2554 setVariableValue(theNameAttribut, theBuffer.toString()); 2555 } 2556 } 2557 } finally { 2558 processes.remove(process); 2559 process.destroyForcibly(); 2560 try { 2561 if (!process.waitFor(5, TimeUnit.SECONDS)) { 2562 process.destroyForcibly(); 2563 } 2564 } catch (InterruptedException e) { 2565 Thread.currentThread().interrupt(); 2566 process.destroyForcibly(); 2567 } 2568 } 2569 2570 } else { 2571 final Thread thread = new SystemCommandStart(theCommandAttribut.substring(prefix.length()), this.log); 2572 thread.start(); 2573 } 2574 } 2575 2576 public void runCommandParameters(final Node aCurrentVar) throws Throwable { 2577 if (RecipeRunner.RUN_MODE_WEB.equals(this.recipeListener.getRunMode())) { 2578 // todo: 2579 } 2580 } 2581 2582 @CommandExamples({ "<ArraySize name = '' array = ''/>" }) 2583 public void runCommandArraySize(final Node aCurrentVar) throws Throwable { 2584 final String theNameAttribut = replaceProperties(aCurrentVar.getAttribute("name")); 2585 final String theArrayNameAttribut = replaceProperties(aCurrentVar.getAttribute("array")); 2586 final Object theValue = getVariableValue(theArrayNameAttribut); 2587 2588 int theResult = 0; 2589 if (theValue instanceof String[]) { 2590 theResult = ((String[]) theValue).length; 2591 } else if (theValue instanceof List) { 2592 theResult = ((List<String>) theValue).size(); 2593 } else if (theValue instanceof byte[]) { 2594 theResult = ((byte[]) theValue).length; 2595 } else if (theValue instanceof String && StringUtils.isNotBlank((String) theValue)) { 2596 theResult = 1; 2597 } else { 2598 theResult = 0; 2599 } 2600 2601 setVariableValue(theNameAttribut, String.valueOf(theResult)); 2602 } 2603 2604 @CommandExamples({ "<Size name = '' source = ''/>" }) 2605 public void runCommandSize(final Node aCurrentVar) throws Throwable { 2606 final String theNameAttribut = replaceProperties(aCurrentVar.getAttribute("name")); 2607 final String theArrayNameAttribut = replaceProperties(aCurrentVar.getAttribute("source")); 2608 final Object theValue = getVariableValue(theArrayNameAttribut); 2609 2610 int theResult = 0; 2611 if (theValue instanceof String[]) { 2612 String[] theValue2 = (String[]) theValue; 2613 for (int i = 0; i < theValue2.length; i++) { 2614 theResult += theValue2[i].length(); 2615 } 2616 } else if (theValue instanceof byte[]) { 2617 theResult = ((byte[]) theValue).length; 2618 } else if (theValue instanceof Collection) { 2619 theResult = ((Collection) theValue).size(); 2620 } else if (theValue instanceof String && StringUtils.isNotBlank((String) theValue)) { 2621 theResult = ((String) theValue).length(); 2622 } else { 2623 theResult = 0; 2624 } 2625 2626 setVariableValue(theNameAttribut, String.valueOf(theResult)); 2627 } 2628 2629 @CommandExamples({ "<Time name = 'type:property' action = 'enum:start|continue|pause|stop'/>", 2630 "<Time name = 'type:property' action = 'format' format='mm:ss:SSS'/>", 2631 "<Time name = 'type:property' action = 'duration' >...</Time>" }) 2632 public void runCommandTime(final Node command) throws Throwable { 2633 final String theNameAttribut = replaceProperties(command.getAttribute("name")); 2634 final String format = replaceProperties(command.getAttribute("format")); 2635 final String theTimeCaption = "Time"; 2636 String action = replaceProperties(command.getAttribute("action")); 2637 2638 if ("duration".equals(action)) { 2639 long start = System.currentTimeMillis(); 2640 2641 taskNode(command, false); 2642 2643 long stop = System.currentTimeMillis(); 2644 final String[] variableValue = new String[] { theTimeCaption, String.valueOf(start), String.valueOf(stop), 2645 "" }; 2646 2647 String result = formatTime(format, variableValue); 2648 setVariableValue(theNameAttribut, result); 2649 return; 2650 } 2651 2652 if ("start".equals(action)) { 2653 final String[] theTime = new String[] { theTimeCaption, String.valueOf(System.currentTimeMillis()), "", 2654 "" }; 2655 setVariableValue(theNameAttribut, theTime); 2656 return; 2657 } 2658 2659 if ("continue".equals(action)) { 2660 String[] theTime = (String[]) getVariableValue(theNameAttribut); 2661 if (theTime == null) { 2662 theTime = new String[] { theTimeCaption, String.valueOf(System.currentTimeMillis()), "", 2663 String.valueOf(System.currentTimeMillis()) }; 2664 } 2665 2666 if (theTime == null || theTime[3] == null || theTime[3].length() == 0) { 2667 throw new Exception("Timer is not paused."); 2668 } 2669 2670 if (theTimeCaption.equals(theTime[0])) { 2671 final long theStart = Long.parseLong(theTime[1]); 2672 final long thePaused = Long.parseLong(theTime[3]); 2673 theTime[1] = String.valueOf(theStart - (System.currentTimeMillis() - thePaused)); 2674 theTime[3] = ""; 2675 setVariableValue(theNameAttribut, theTime); 2676 } else { 2677 throw new Exception("Incorrect type."); 2678 } 2679 return; 2680 } 2681 2682 if ("pause".equals(action)) { 2683 final String[] theTime = (String[]) getVariableValue(theNameAttribut); 2684 2685 if (theTime[3] != null && theTime[3].length() > 0) { 2686 throw new Exception("Timer is paused."); 2687 } 2688 if (theTimeCaption.equals(theTime[0])) { 2689 theTime[3] = String.valueOf(System.currentTimeMillis()); 2690 setVariableValue(theNameAttribut, theTime); 2691 } else { 2692 throw new Exception("Incorrect type."); 2693 } 2694 return; 2695 } 2696 2697 if ("stop".equals(action)) { 2698 final String[] theTime = (String[]) getVariableValue(theNameAttribut); 2699 2700 final long theStart = Long.parseLong(theTime[1]); 2701 2702 if (theTime[3] != null && theTime[3].length() > 0) { 2703 final long thePaused = Long.parseLong(theTime[3]); 2704 theTime[1] = String.valueOf(theStart + (System.currentTimeMillis() - thePaused)); 2705 theTime[3] = ""; 2706 } 2707 2708 if (theTimeCaption.equals(theTime[0])) { 2709 theTime[2] = String.valueOf(System.currentTimeMillis()); 2710 setVariableValue(theNameAttribut, theTime); 2711 } else { 2712 throw new Exception("Incorrect type."); 2713 } 2714 return; 2715 } 2716 2717 if ("format".equals(action)) { 2718 Object variableValue = getVariableValue(theNameAttribut); 2719 String theResult = formatTime(format, variableValue); 2720 setVariableValue(theNameAttribut, theResult); 2721 return; 2722 } 2723 } 2724 2725 private String formatTime(final String format, Object variableValue) throws Exception { 2726 final String[] theTime; 2727 if (variableValue instanceof String[]) { 2728 theTime = (String[]) variableValue; 2729 } else { 2730 theTime = new String[] { "", "0", (String) variableValue }; 2731 } 2732 2733 if (ArrayUtils.getLength(theTime) < 2) { 2734 throw new Exception("Timer is not defined."); 2735 } 2736 2737 if (ArrayUtils.getLength(theTime) < 3) { 2738 throw new Exception("Timer is not stoped."); 2739 } 2740 2741 String theResult = null; 2742 if (format == null) { 2743 theResult = String.valueOf(Long.parseLong(theTime[2]) - Long.parseLong(theTime[1])); 2744 } else { 2745 final DateFormat dateFormat = new SimpleDateFormat(format); 2746 dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 2747 long date = Long.parseLong(theTime[2]) - Long.parseLong(theTime[1]); 2748 theResult = dateFormat.format(new Date(date)); 2749 } 2750 return theResult; 2751 } 2752 2753 @CommandExamples({ "<ArrayElement name='type:property' array='' elementId=''/>" }) 2754 public void runCommandArrayElement(final Node aCurrentVar) throws Throwable { 2755 final String theNameAttribut = replaceProperties(aCurrentVar.getAttribute("name")); 2756 final String theArrayNameAttribut = replaceProperties(aCurrentVar.getAttribute("array")); 2757 final String theElementAttribut = replaceProperties(aCurrentVar.getAttribute("elementId")); 2758 final String type = replaceProperties(aCurrentVar.getAttribute("type")); 2759 Object theValue = getVariableValue(theArrayNameAttribut); 2760 2761 final int theElementId = Integer.parseInt(theElementAttribut); 2762 2763 theValue = convert(theValue, type); 2764 2765 Object theResult = null; 2766 if (theValue instanceof JSONArray) { 2767 JSONArray jsonArray = (JSONArray) theValue; 2768 theResult = jsonArray.get(theElementId); 2769 } else if (theValue instanceof String[]) { 2770 theResult = ((String[]) theValue)[theElementId]; 2771 } else if (theValue instanceof String) { 2772 if ("string".equalsIgnoreCase(type)) { 2773 theResult = new String(new char[] { ((String) theValue).charAt(theElementId) }); 2774 } else if (theElementId == 0) { 2775 theResult = theValue; 2776 } 2777 } else if (theElementId == 0) { 2778 theResult = theValue; 2779 } 2780 2781 setVariableValue(theNameAttribut, theResult); 2782 } 2783 2784 @CommandHotHepl("<html>Evaluates the expressions, representing result as a string.</html>") 2785 @CommandExamples({ "<Calculate name='type:property' expressions='type:string'/>", 2786 "<Calculate name='type:property'>...</Calculate>" }) 2787 public void runCommandCalculate(final Node command) throws Throwable { 2788 final String name = replaceProperties(command.getAttribute("name")); 2789 String expressions = replaceProperties(command.getAttribute("expressions")); 2790 if (expressions == null) { 2791 expressions = replaceProperties(command.getInnerText()); 2792 } 2793 2794 JexlEngine jexl = new JexlBuilder().create(); 2795 2796 JexlExpression expr_c = jexl.createExpression(expressions); 2797 JexlContext context = new MapContext(); 2798 2799 Map<String, String> attributes = command.getAttributes(); 2800 for (Map.Entry<String, String> entry : attributes.entrySet()) { 2801 String key = entry.getKey(); 2802 String val = entry.getValue(); 2803 2804 Object variableValue = getVariableValue(val); 2805 if (variableValue instanceof String) { 2806 try { 2807 variableValue = Double.parseDouble((String) variableValue); 2808 } catch (NumberFormatException e) { 2809 // DO NOTHING 2810 } 2811 } 2812 2813 context.set(key, variableValue); 2814 } 2815 2816 if (expr_c != null) { 2817 Object result = expr_c.evaluate(context); 2818 2819 if (result != null) { 2820 setVariableValue(name, result); 2821 } else { 2822 setVariableValue(name, null); 2823 } 2824 } 2825 } 2826 2827 @CommandExamples({ 2828 "<Parse name='type:property' source='type:property' type='enum:array|json|csv|fixed-length-line'/>", 2829 "<Parse name='type:property' source='type:property' type='fixed-length-line' length='type:integer'/>" }) 2830 public void runCommandParse(final Node command) throws Throwable { 2831 Object source = attrValue(command, "source"); 2832 final String theNameAttribut = replaceProperties(command.getAttribute("name")); 2833 final String type = replaceProperties(command.getAttribute("type")); 2834 2835 if ("json".equalsIgnoreCase(type)) { 2836 String theValue = ObjectUtils.toString(source); 2837 2838 Object obj = new JSONObject(theValue); 2839 if (obj instanceof JSONObject) { 2840 JSONObject result = new JSONObject(theValue); 2841 setVariableValue(theNameAttribut, result); 2842 } else if (obj instanceof JSONArray) { 2843 JSONArray result = new JSONArray(theValue); 2844 String[] array = new String[result.length()]; 2845 for (int i = 0; i < result.length(); i++) { 2846 array[i] = ObjectUtils.toString(result.get(i)); 2847 } 2848 setVariableValue(theNameAttribut, array); 2849 } 2850 } else if ("array".equalsIgnoreCase(type)) { 2851 String theValue = ObjectUtils.toString(source); 2852 2853 String[] array = StringUtils.split(theValue, "\r\n"); 2854 setVariableValue(theNameAttribut, array); 2855 } else if ("csv".equalsIgnoreCase(type)) { 2856 String theValue = ObjectUtils.toString(source); 2857 2858 CSVReader reader = new CSVReader(new StringReader(theValue)); 2859 List<String[]> r = reader.readAll(); 2860 2861 setVariableValue(theNameAttribut, r); 2862 } else if ("fixed-length-line".equalsIgnoreCase(type)) { 2863 if (source instanceof String) { 2864 String input = (String) source; 2865 int lineLength = Integer.parseInt(attr(command, "length")); 2866 List<Object> result = IntStream.range(0, (input.length() + lineLength - 1) / lineLength) 2867 .mapToObj(i -> input.substring(i * lineLength, Math.min((i + 1) * lineLength, input.length()))) 2868 .collect(Collectors.toList()); 2869 setVariableValue(theNameAttribut, result); 2870 } 2871 } 2872 } 2873 2874 @CommandExamples({ "<FindObject name='type:property' source='type:property' withValue=''/>" }) 2875 public void runCommandFindObject(final Node aCurrentNode) throws Throwable { 2876 Object json = getVariableValue(replaceProperties(aCurrentNode.getAttribute("source"))); 2877 String withValue = replaceProperties(aCurrentNode.getAttribute("withValue")); 2878 2879 if (json instanceof String) { 2880 String jsonStr = (String) json; 2881 if (StringUtils.startsWith(jsonStr, "{")) { 2882 json = new JSONObject(jsonStr); 2883 } else if (StringUtils.startsWith(jsonStr, "[")) { 2884 json = new JSONArray(jsonStr); 2885 } 2886 } else if (json instanceof String[]) { 2887 String[] jsonStrArray = (String[]) json; 2888 JSONArray array = new JSONArray(); 2889 for (int i = 0; i < jsonStrArray.length; i++) { 2890 String jsonStr = jsonStrArray[i]; 2891 array.put(new JSONObject(jsonStr)); 2892 } 2893 json = array; 2894 } 2895 2896 Object value = find(json, withValue); 2897 2898 final String name = replaceProperties(aCurrentNode.getAttribute("name")); 2899 applyResult(aCurrentNode, name, value); 2900 } 2901 2902 private JSONObject find(Object obj, String withValue) throws JSONException { 2903 if (obj instanceof JSONObject) { 2904 JSONObject json = (JSONObject) obj; 2905 2906 JSONArray names = json.names(); 2907 if (names != null) { 2908 for (int i = 0; i < names.length(); i++) { 2909 String name = names.getString(i); 2910 Object object = json.get(name); 2911 if (object instanceof String) { 2912 if (ObjectUtils.equals(object, withValue)) { 2913 return json; 2914 } 2915 } else { 2916 JSONObject find = find(object, withValue); 2917 if (find != null) { 2918 return find; 2919 } 2920 } 2921 } 2922 } 2923 } else if (obj instanceof JSONArray) { 2924 JSONArray array = (JSONArray) obj; 2925 2926 for (int j = 0; j < array.length(); j++) { 2927 Object item = array.get(j); 2928 2929 JSONObject find = find(item, withValue); 2930 if (find != null) { 2931 return find; 2932 } 2933 } 2934 } 2935 return null; 2936 } 2937 2938 @CommandExamples({ 2939 "<Var name='type:property' init='enum:console|mandatory|default' type='enum:text|password|path'/>", 2940 "<Var name='type:property' type='enum:array|number|map|json|string' />", 2941 "<Var name='type:property' source='type:property' start='' end=''/>", 2942 "<Var name='type:property' value='type:string' description='' init='enum:console|mandatory|default'/>", 2943 "<Var name='type:property'><item>...</item></Var>", 2944 "<Var name='type:property' type='map'><item ke='type:string'>...</item></Var>", 2945 "<Var name='type:property' type='enum:array|number' file='type:path'/>", 2946 "<Var name='type:property' source='type:property' />" }) 2947 public void runCommandVar(final Node aCurrentVar) throws Throwable { 2948 final String name = replaceProperties(aCurrentVar.getAttribute("name")); 2949 String description = replaceProperties(aCurrentVar.getAttribute("description")); 2950 String theInit = replaceProperties(aCurrentVar.getAttribute("init")); 2951 2952 Object theOldValue = getVariableValue(name); 2953 if ("default".equals(theInit) && theOldValue != null) { 2954 if (theOldValue instanceof String) { 2955 if (StringUtils.isNotBlank((String) theOldValue)) { 2956 return; 2957 } 2958 } else if (theOldValue instanceof String[] && ((String[]) theOldValue).length > 0) { 2959 return; 2960 } 2961 } 2962 2963 if ("file".equals(theInit)) { 2964 loadProperties(getFile(name), this.variables, false); 2965 return; 2966 } 2967 String source = replaceProperties(aCurrentVar.getAttribute("source"), true); 2968 Object theValue = getVariableValue(name); 2969 if (source != null) { 2970 String sourceVarName = replaceProperties(source); 2971 theValue = getVariableValue(sourceVarName); 2972 theOldValue = theValue; 2973 setVariableValue(name, theValue); 2974 } 2975 2976 String value = aCurrentVar.getAttribute("value"); 2977 if (value != null) { 2978 theValue = replaceProperties(value); 2979 } 2980 2981 // Item setting 2982 String type = StringUtils.defaultIfEmpty(aCurrentVar.getAttribute("type"), ""); 2983 if (aCurrentVar.size() > 0) { 2984 if (Node.TEXT_TEAG_NAME.equals(aCurrentVar.getNode(0).getTag())) { 2985 final Node theTextNode = aCurrentVar.getNode(0); 2986 theValue = replaceProperties(theTextNode.getText()); 2987 2988 } else { 2989 switch (type) { 2990 case "map": 2991 Node[] nodes = aCurrentVar.getNodes("item"); 2992 theValue = new LinkedHashMap<String, String>(); 2993 for (Node node : nodes) { 2994 ((Map) theValue).put(node.getAttribute("key"), replaceProperties(node.getInnerText())); 2995 } 2996 break; 2997 2998 default: 2999 List<Object> theItemArray = new ArrayList<>(); 3000 for (int i = 0; i < aCurrentVar.size(); i++) { 3001 final Node theCurrentAction = (Node) aCurrentVar.get(i); 3002 Node[] theItemNodes = theCurrentAction.getTextNodes(); 3003 if (theItemNodes != null && theItemNodes.length == 1) { 3004 final String replaceProperties = replaceProperties(theItemNodes[0].getText(), true); 3005 theItemArray.add(replaceProperties); 3006 } else { 3007 if (theCurrentAction.size() == 1) { 3008 Node node = theCurrentAction.get(0); 3009 EasyUtils.removeAllAttributes(node, Node.TAG_ID); 3010 theItemArray.add(replaceProperties(node.getXMLText(), true)); 3011 } else { 3012 theItemArray = null; 3013 } 3014 break; 3015 } 3016 } 3017 theValue = theItemArray; 3018 } 3019 } 3020 } 3021 3022 boolean contains = StringUtils.contains(theInit, "mandatory"); 3023 boolean isConsoleInput = StringUtils.contains(theInit, "console"); 3024 boolean mandatory = StringUtils.contains(theInit, "mandatory"); 3025 if (mandatory) { 3026 if (!isEmpty(theOldValue)) { 3027 setVariableValue(name, theValue); 3028 } else { 3029 isConsoleInput = true; 3030 } 3031 } 3032 3033 final boolean theInregerType = "number".equals(type); 3034 if (theInregerType) { 3035 String string = ObjectUtils.toString(theValue); 3036 if (!NumberUtils.isNumber(string)) { 3037 setVariableValue(name, null); 3038 throw new NumberFormatException(string); 3039 } 3040 } 3041 3042 final boolean theArrayType = "array".equals(type); 3043 if (name != null && !(theValue == null && theArrayType == false)) { 3044 if (theArrayType) { 3045 char separatorChar = ','; 3046 if (theValue instanceof String) { 3047 String[] split = StringUtils.split((String) theValue, separatorChar); 3048 theValue = split != null ? Arrays.asList(split) : null; 3049 } 3050 } 3051 if (theArrayType && theValue == null) { 3052 theValue = new String[0]; 3053 } 3054 3055 String file = replaceProperties(aCurrentVar.getAttribute("file")); 3056 if (theArrayType && file != null) { 3057 ArrayList<String> buffer = new ArrayList<String>(); 3058 3059 if (theValue instanceof String[]) { 3060 for (String string : (String[]) theValue) { 3061 buffer.add(string); 3062 } 3063 } else if (theValue instanceof Collection) { 3064 buffer = new ArrayList((Collection) theValue); 3065 } 3066 3067 InputStream inputStream = AEUtils.getInputStream(file, getBaseDir()); 3068 String encoding = replaceProperties(aCurrentVar.getAttribute("charset")); 3069 if (encoding == null) { 3070 encoding = "UTF-8"; 3071 } 3072 final BufferedReader theFileReader = new BufferedReader(new InputStreamReader(inputStream, encoding)); 3073 try { 3074 String readLine; 3075 while ((readLine = theFileReader.readLine()) != null) { 3076 buffer.add(readLine); 3077 } 3078 } finally { 3079 theFileReader.close(); 3080 } 3081 theValue = buffer; 3082 } 3083 3084 theValue = convert(theValue, type); 3085 setVariableValue(name, theValue); 3086 } 3087 3088 if (isConsoleInput) { 3089 3090 if (theOldValue instanceof List && CollectionUtils.size(theOldValue) == 1) { 3091 theOldValue = ((List) theOldValue).get(0); 3092 } 3093 3094 if ((aCurrentVar.size() == 0 || !aCurrentVar.getInnerText().isEmpty()) 3095 && (isEmpty(theOldValue) || theOldValue instanceof String)) { 3096 Object theInitialSelectionValue = null; 3097 final Object o = getVariableValue(name); 3098 if (o instanceof String) { 3099 theInitialSelectionValue = o; 3100 } 3101 if (o instanceof String[] && ((String[]) o).length > 0) { 3102 if (this.random == null) { 3103 this.random = SecureRandom.getInstance("SHA1PRNG"); 3104 } 3105 theInitialSelectionValue = ((String[]) o)[this.random.nextInt(((String[]) o).length)]; 3106 } 3107 3108 String defaultValue = AEWorkspace.getInstance().getDefaultUserConfiguration(".inputValue." + name, 3109 (String) theInitialSelectionValue); 3110 if (this.recipeListener.getManager().isConsoleDefaultInput(name, description) 3111 && !(mandatory && defaultValue == null)) { 3112 3113 if ((o instanceof String[] && ArrayUtils.contains((String[]) o, defaultValue)) || o == null) { 3114 theInitialSelectionValue = defaultValue; 3115 } 3116 3117 setVariableValue(name, theInitialSelectionValue); 3118 } else { 3119 boolean notifyMe = this.recipeListener.isNotifyMe(); 3120 Object inputValue; 3121 3122 inputValue = this.recipeListener.getManager().inputValue(name, description, defaultValue, log, type, 3123 notifyMe, this); 3124 3125 setVariableValue(name, inputValue); 3126 } 3127 3128 } else { 3129 List possibleValues = null; 3130 if (theOldValue instanceof List) { 3131 final List theStringArray = (List) theOldValue; 3132 possibleValues = theStringArray; 3133 } else if (theOldValue instanceof String[]) { 3134 possibleValues = new ArrayList(); 3135 String[] array = (String[]) theOldValue; 3136 for (String item : array) { 3137 possibleValues.add(item); 3138 } 3139 } else { 3140 possibleValues = new ArrayList(); 3141 for (int i = 0; i < aCurrentVar.size(); i++) { 3142 final Node theCurrentAction = (Node) aCurrentVar.get(i); 3143 possibleValues.add(theCurrentAction.getInnerText()); 3144 } 3145 } 3146 3147 if (this.recipeListener.getManager().isConsoleDefaultInput(name, null)) { 3148 String theInitialSelectionValue = randomSelect(possibleValues); 3149 if (!randomSelect) { 3150 theInitialSelectionValue = AEWorkspace.getInstance() 3151 .getDefaultUserConfiguration(".choiceValue." + name, theInitialSelectionValue); 3152 3153 } 3154 setVariableValue(name, theInitialSelectionValue); 3155 } else { 3156 boolean notifyMe = this.recipeListener.isNotifyMe(); 3157 final Object theValueOut = this.recipeListener.getManager().choiceValue(name, description, 3158 possibleValues.toArray(), log, notifyMe, this); 3159 setVariableValue(name, theValueOut); 3160 } 3161 } 3162 } 3163 3164 theValue = getVariableValue(name); 3165 3166 String start = replaceProperties(aCurrentVar.getAttribute("start")); 3167 String end = replaceProperties(aCurrentVar.getAttribute("end")); 3168 3169 if (StringUtils.isNotEmpty(start)) { 3170 if (theValue instanceof byte[]) { 3171 theValue = new String((byte[]) theValue); 3172 } 3173 theValue = StringUtils.substringAfter(ObjectUtils.toString(theValue), start); 3174 if (StringUtils.isBlank((String) theValue)) { 3175 theValue = null; 3176 } 3177 } 3178 if (StringUtils.isNotEmpty(end)) { 3179 theValue = StringUtils.substringBefore((String) theValue, end); 3180 if (StringUtils.isBlank((String) theValue)) { 3181 theValue = null; 3182 } 3183 } 3184 3185 applyResult(aCurrentVar, name, theValue); 3186 3187 if (contains && theValue == null) { 3188 stop(); 3189 } 3190 } 3191 3192 private Object convert(Object theValue, String type) throws JSONException { 3193 if ("json".equals(type)) { 3194 Object parse = theValue; 3195 if (theValue instanceof String[]) { 3196 String[] array = (String[]) theValue; 3197 List<String> asList = Arrays.asList(array); 3198 theValue = new JSONArray(asList); 3199 } else if (theValue instanceof String) { 3200 if (StringUtils.startsWith((String) theValue, "{")) { 3201 parse = new JSONObject(theValue.toString()); 3202 } else if (StringUtils.startsWith((String) theValue, "[")) { 3203 parse = new JSONArray(theValue.toString()); 3204 } 3205 } 3206 theValue = parse; 3207 } else if ("string".equals(type) && theValue instanceof String[]) { 3208 theValue = StringUtils.join((String[]) theValue); 3209 } 3210 3211 return theValue; 3212 } 3213 3214 private String randomSelect(List possibleValues) throws NoSuchAlgorithmException { 3215 final String theInitialSelectionValue; 3216 if (this.random == null) { 3217 this.random = SecureRandom.getInstance("SHA1PRNG"); 3218 } 3219 theInitialSelectionValue = (String) possibleValues.get(this.random.nextInt(possibleValues.size())); 3220 return theInitialSelectionValue; 3221 } 3222 3223 public void runCommandNote(final Node aCurrentAction) throws Throwable { 3224 } 3225 3226 public void runCommandComment(final Node aCurrentAction) throws Throwable { 3227 } 3228 3229 @CommandExamples({ "<Extern plugin='type:path'>...</Extern>", "<Extern class=''>...</Extern>", 3230 "<Extern class='' plugin='type:path'>...</Extern>" }) 3231 public void runCommandExtern(final Node command) throws Throwable { 3232 final Processor newInstance = makeProcessor(command); 3233 boolean success = false; 3234 try { 3235 this.externProcessor = newInstance; 3236 externProcessor.setTestName(getTestName()); 3237 newInstance.init(this, command); 3238 boolean rootRecipe = isRootRecipe(); 3239 newInstance.setRootContext(rootRecipe); 3240 newInstance.stackTask.addAll(this.stackTask); 3241 newInstance.taskNode(command, false); 3242 3243 this.variables = newInstance.variables; 3244 success = true; 3245 } finally { 3246 externProcessor.complete(success); 3247 externProcessor = null; 3248 } 3249 } 3250 3251 @CommandExamples({ "<Confirm message='type:string' name='type:string'/>", 3252 "<Confirm message='type:string' name='type:string'>...</Confirm>" }) 3253 public void runCommandConfirm(final Node aCurrentAction) throws Throwable { 3254 final String message = attr(aCurrentAction, "message"); 3255 final String name = attr(aCurrentAction, "name"); 3256 final Object nameVar = getVariableValue(name); 3257 3258 boolean confirmed = false; 3259 if (nameVar != null && nameVar instanceof String) { 3260 confirmed = BooleanUtils.toBoolean((String) nameVar); 3261 } else { 3262 AEManager manager = this.recipeListener.getManager(); 3263 confirmed = manager.confirmation(name, message, this, this.recipeListener.isNotifyMe()); 3264 } 3265 3266 if (aCurrentAction.size() > 0) { 3267 if (confirmed) { 3268 taskNode(aCurrentAction, false); 3269 } 3270 } else { 3271 if (!confirmed) { 3272 stop(); 3273 } 3274 } 3275 } 3276 3277 @CommandExamples({ "<WhileRun name='type:string' message='type:string'>...</WhileRun>" }) 3278 public void runCommandWhileRun(final Node aCurrentAction) throws Throwable { 3279 final String message = replaceProperties(aCurrentAction.getAttribute("message")); 3280 final String name = replaceProperties(aCurrentAction.getAttribute("name")); 3281 final Object nameVar = getVariableValue(name); 3282 3283 if (!(nameVar instanceof String) || BooleanUtils.toBoolean((String) nameVar)) { 3284 AEManager manager = this.recipeListener.getManager(); 3285 MessageHandler handler = manager.message(this, name, message, this.recipeListener.isNotifyMe()); 3286 taskNode(aCurrentAction, false); 3287 handler.close(); 3288 } 3289 }; 3290 3291 @CommandExamples({ "<Server port='type:integer' request='type:property' response='type:property' > ... </Server>", 3292 "<Server port='type:integer' numbers='type:integer' request='type:property' response='type:property' > ... </Server>" }) 3293 public void runCommandServer(final Node aCurrentAction) throws Throwable { 3294 3295 String encoding = replaceProperties(aCurrentAction.getAttribute("charset")); 3296 if (encoding == null) { 3297 encoding = "UTF-8"; 3298 } 3299 3300 final int thePort = Integer.parseInt(replaceProperties(aCurrentAction.getAttribute("port"))); 3301 int maxNumber = 0; 3302 3303 final String theMaxNumbers = replaceProperties(aCurrentAction.getAttribute("numbers")); 3304 if (theMaxNumbers != null) { 3305 maxNumber = Integer.parseInt(theMaxNumbers); 3306 } 3307 final String request = attr(aCurrentAction, "request"); 3308 final String response = attr(aCurrentAction, "response"); 3309 3310 ServerAction server = new ServerAction(this, aCurrentAction, thePort, request, response, encoding, maxNumber); 3311 server.perform(); 3312 } 3313 3314 @CommandHotHepl("<html></html>") 3315 @CommandExamples({ "<Restore/>", "<Restore name='type:property'> ... </Restore>", 3316 "<Restore except='type:property'> ... </Restore>" }) 3317 public void runCommandRestore(final Node command) throws Throwable { 3318 String name = attr(command, "name"); 3319 String except = attr(command, "except"); 3320 3321 if (CollectionUtils.isEmpty(command)) { 3322 final Map<String, Object> systemVariables = getListener().getManager().getSystemVariables(); 3323 this.variables.clear(); 3324 this.variables.putAll(systemVariables); 3325 debug("Task variables has been restored."); 3326 } else if (name != null) { 3327 Object savedVariable = getVariableValue(name); 3328 taskNode(command, false); 3329 setVariableValue(name, savedVariable); 3330 3331 } else if (except != null) { 3332 Map<String, Object> savedVariables = this.variables; 3333 this.variables = new HashMap<String, Object>(this.variables); 3334 3335 taskNode(command, false); 3336 3337 Object object = getVariableValue(except); 3338 this.variables.clear(); 3339 this.variables = savedVariables; 3340 setVariableValue(except, object); 3341 } 3342 3343 } 3344 3345 @CommandHotHepl("<html></html>") 3346 @CommandExamples({ "<Finally> ... </Finally>" }) 3347 public void runCommandFinally(final Node aCurrentAction) throws Throwable { 3348 } 3349 3350 @CommandHotHepl("<html></html>") 3351 @CommandExamples({ "<Break/>" }) 3352 public void runCommandBreak(final Node aCurrentAction) throws Throwable { 3353 } 3354 3355 @CommandHotHepl("<html></html>") 3356 @CommandExamples({ "<Stop/>", "<Stop ifNull='type:property'/>" }) 3357 public void runCommandStop(final Node aCurrentAction) throws Throwable { 3358 } 3359 3360 private boolean isEmpty(Object theOldValue) { 3361 boolean result = false; 3362 if (theOldValue == null) { 3363 result = true; 3364 } else if (theOldValue instanceof String[] && ((String[]) theOldValue).length == 0) { 3365 result = true; 3366 } else if (theOldValue instanceof Map && ((Map) theOldValue).size() == 0) { 3367 result = true; 3368 } 3369 return result; 3370 } 3371 3372 public void setVariableValue(String name, final Object value) { 3373 if (name != null) { 3374 super.setVariableValue(name, value); 3375 if (this.recipeListener != null && name.startsWith("!") == false) { 3376 this.recipeListener.changeVariable(name, value); 3377 } 3378 } 3379 } 3380 3381}