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