001package com.ganteater.ae;
002
003import java.awt.Color;
004import java.awt.Toolkit;
005import java.io.BufferedReader;
006import java.io.Console;
007import java.io.File;
008import java.io.FileInputStream;
009import java.io.FileOutputStream;
010import java.io.IOException;
011import java.io.InputStream;
012import java.io.InputStreamReader;
013import java.io.UnsupportedEncodingException;
014import java.lang.reflect.Method;
015import java.lang.reflect.Modifier;
016import java.net.Authenticator;
017import java.net.Inet4Address;
018import java.net.InetAddress;
019import java.net.NetworkInterface;
020import java.net.PasswordAuthentication;
021import java.net.SocketException;
022import java.net.URL;
023import java.nio.file.Files;
024import java.nio.file.NoSuchFileException;
025import java.nio.file.Path;
026import java.nio.file.Paths;
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.Base64;
030import java.util.Enumeration;
031import java.util.HashMap;
032import java.util.HashSet;
033import java.util.Iterator;
034import java.util.LinkedHashMap;
035import java.util.List;
036import java.util.Locale;
037import java.util.Map;
038import java.util.Properties;
039import java.util.Set;
040import java.util.regex.Pattern;
041import java.util.stream.Stream;
042
043import org.apache.commons.collections.CollectionUtils;
044import org.apache.commons.collections.MapUtils;
045import org.apache.commons.io.IOUtils;
046import org.apache.commons.lang.ArrayUtils;
047import org.apache.commons.lang.BooleanUtils;
048import org.apache.commons.lang.ObjectUtils;
049import org.apache.commons.lang.StringUtils;
050import org.apache.commons.lang.SystemUtils;
051import org.apache.log4j.PropertyConfigurator;
052import org.apache.maven.shared.invoker.DefaultInvocationRequest;
053import org.apache.maven.shared.invoker.DefaultInvoker;
054import org.apache.maven.shared.invoker.InvocationRequest;
055import org.apache.maven.shared.invoker.InvocationResult;
056import org.apache.maven.shared.invoker.Invoker;
057import org.apache.maven.shared.invoker.MavenInvocationException;
058
059import com.ganteater.ae.processor.BaseProcessor;
060import com.ganteater.ae.processor.MessageHandler;
061import com.ganteater.ae.processor.Processor;
062import com.ganteater.ae.processor.SpecialCommands;
063import com.ganteater.ae.util.AEUtils;
064import com.ganteater.ae.util.Encryptor;
065import com.ganteater.ae.util.xml.easyparser.EasyParser;
066import com.ganteater.ae.util.xml.easyparser.Node;
067import com.ganteater.ae.util.xml.easyparser.ParserException;
068
069public class AEWorkspace implements AEManager {
070
071        public static final String CONFIGURATION_TITLE = "Configuration";
072
073        public static final String ENVIRONMENT_FILE_TITLE = "Environment file";
074
075        public static final String MESSAGE_PASSWORD_REQUIRED = "This configuration requires encryption for user preferences data.\nEnter the encryption password: ";
076
077        public static final String CONFIG_SUFIX_PROP_NAME = ".config";
078
079        private static ILogger log = new Logger("AEWorkspace");
080
081        private static String fUser = System.getProperty("user.name");
082
083        private static Properties fUserPreferences;
084
085        private long startTime = System.currentTimeMillis();
086
087        private Node allConfigNode;
088
089        private Map<String, Object> fSystemVariables = new HashMap<>();
090
091        private Node fConfigNode;
092
093        private Properties fTestsDescList = new Properties();
094
095        protected boolean defaultMode;
096
097        private String fConfigurationName;
098
099        private Set<RecipeRunner> runners = new HashSet<RecipeRunner>();
100
101        private File baseDir = SystemUtils.getUserDir();
102
103        private static AEWorkspace instance;
104
105        private Set<Class<?>> operationsClasses;
106
107        private Map<String, OperationHolder> opsMethods = new HashMap<String, OperationHolder>();
108
109        private Encryptor cryptoUtilAesGcm;
110
111        private List<Runnable> closeHooks = new ArrayList<>();
112
113        private RecipesScanner recipesScaner;
114
115        public AEWorkspace() {
116                this(new File(System.getProperty("user.dir")));
117        }
118
119        public AEWorkspace(File startDir) {
120                instance = this;
121                System.out.println("Start dir: " + startDir);
122                recipesScaner = new RecipesScanner(this, startDir);
123        }
124
125        public String loadConfiguration(String confName, boolean refreshTaskPath) {
126                getHomeConfigurationsDir().mkdirs();
127                File homeConfiguration = new File(getHomeConfigurationsDir(), ConfigConstants.AE_CONFIG_XML);
128
129                if (homeConfiguration.exists()) {
130                        System.out.println("User home configuration file: " + homeConfiguration.getAbsolutePath() + " - found");
131                }
132
133                Node configNodes;
134                try {
135                        configNodes = getConfiguration();
136
137                        String config = selectConfiguration(confName, configNodes, refreshTaskPath);
138                        TemplateProcessor tp = new TemplateProcessor(fSystemVariables, fConfigNode, getStartDir());
139                        recipesScaner.loadTaskPath(fConfigNode, tp);
140
141                        String password = System.getProperty("configEncriptKey");
142                        initUserPreferencesEncryption(password);
143                        return config;
144
145                } catch (TaskCancelingException | ConfigurationException e) {
146                        throw e;
147                } catch (Exception e) {
148                        throw new ConfigurationException("Configuration loading failed.", e);
149                }
150
151        }
152
153        protected Node getConfiguration() throws IOException {
154
155                File configFile = getConfigurationFile();
156
157                String errorMessage = AEWorkspace.ENVIRONMENT_FILE_TITLE + " (" + ConfigConstants.AE_CONFIG_XML
158                                + ") must be defined in " + getHomeWorkingDir() + " or " + getStartDir()
159                                + ".\n Please ensure that the file is available in one of the locations above. "
160                                + "If the file is missing or incorrectly defined, refer to the configuration documentation for guidance: "
161                                + "<a href=\"https://ganteater.com/configuration.html\">Configuration</a>";
162
163                if (configFile == null) {
164                        throw new ConfigurationException(errorMessage);
165                }
166
167                setBaseDir(configFile.getParentFile());
168                Node object = null;
169
170                if (configFile.exists() || configFile.toString().contains(".jar!")) {
171                        try (InputStream inputStream = AEUtils.getInputStream(configFile.toString(), getBaseDir())) {
172                                object = new EasyParser().getObject(inputStream);
173                        } catch (ParserException e) {
174                                throw new ConfigurationException(errorMessage, e);
175                        }
176                } else {
177                        try {
178                                URL resource = new URL(configFile.toString());
179                                try (InputStream openStream = resource.openStream()) {
180                                        String recipeXml = IOUtils.toString(openStream);
181                                        object = new EasyParser().getObject(recipeXml);
182                                }
183                        } catch (Exception e) {
184                                throw new ConfigurationException(errorMessage, e);
185                        }
186                }
187
188                return object;
189        }
190
191        protected File getConfigurationFile() {
192                File confFile;
193                loadCustomProperties();
194
195                String theConfigurationFile = System.getProperty(ConfigConstants.AE_CONFIG_SYS_PROPERTY_NAME);
196                if (theConfigurationFile == null) {
197                        confFile = new File(SystemUtils.getUserDir(), ConfigConstants.AE_CONFIG_XML);
198                        if (!confFile.exists()) {
199                                confFile = new File(getHomeWorkingDir(), ConfigConstants.AE_CONFIG_XML);
200                                if (!confFile.exists()) {
201                                        confFile = new File(getStartDir(), ConfigConstants.AE_CONFIG_XML);
202                                }
203                        }
204                } else {
205                        confFile = new File(theConfigurationFile);
206                }
207
208                if (!confFile.exists()) {
209                        String name = "/" + ConfigConstants.AE_CONFIG_XML;
210                        URL resource = AEWorkspace.class.getResource(name);
211                        if (resource != null) {
212                                confFile = new File(resource.toString());
213                        } else {
214                                confFile = findAlternativeConfiguration("");
215                        }
216                }
217
218                return confFile;
219        }
220
221        protected File findAlternativeConfiguration(String aeDir) {
222                File confFile = null;
223                File userDir = getBaseDir();
224                List<String> confFiles = findAEconfigs(userDir);
225
226                if (!confFiles.isEmpty()) {
227
228                        String confPropName = userDir.getPath() + CONFIG_SUFIX_PROP_NAME;
229                        String defaultValue = AEWorkspace.getInstance().getDefaultUserConfiguration(confPropName, null);
230
231                        String aeConfFileName = inputChoice("Projects", null, confFiles.toArray(new String[confFiles.size()]),
232                                        defaultValue, null, false);
233
234                        AEWorkspace.getInstance().setDefaultUserConfiguration(confPropName, aeConfFileName);
235
236                        File pomFile = getPomLocation(aeConfFileName, aeDir);
237
238                        if (pomFile != null) {
239                                System.err.println("[ERROR] For the configuration: " + aeConfFileName + " found pom.xml file: "
240                                                + pomFile + ". This Anteter version does not support ae:do, please run it manually.");
241                                System.exit(1);
242
243                        } else {
244                                confFile = new File(aeConfFileName);
245                        }
246                        return confFile;
247                }
248
249                if (confFile == null) {
250                        confFile = selectConfiguration();
251                }
252
253                return confFile;
254        }
255
256        protected File selectConfiguration() {
257                File userDir = getBaseDir();
258                String confPropName = userDir.getPath() + CONFIG_SUFIX_PROP_NAME;
259                String config = AEWorkspace.getInstance().getDefaultUserConfiguration(confPropName, "");
260
261                config = inputValue(ENVIRONMENT_FILE_TITLE, null, config, null, null);
262
263                AEWorkspace.getInstance().setDefaultUserConfiguration(confPropName, config);
264                return new File(config);
265        }
266
267        public File getHomeWorkingDir() {
268                return new File(System.getProperty("user.home"), "anteater");
269        }
270
271        private void configuration() {
272                if (fConfigNode != null) {
273                        Node[] theLogNodes = fConfigNode.getNodes("Logger");
274                        if (!ArrayUtils.isEmpty(theLogNodes)) {
275                                Node logNode = theLogNodes[theLogNodes.length - 1];
276                                initLogger(logNode);
277                        }
278                }
279
280                final String username = (String) fSystemVariables.get("HTTP_USERNAME");
281                final String password = (String) fSystemVariables.get("HTTP_PASSWORD");
282                if (username != null && password != null) {
283                        Authenticator.setDefault(new Authenticator() {
284                                protected PasswordAuthentication getPasswordAuthentication() {
285                                        return new PasswordAuthentication(username, password.toCharArray());
286                                }
287                        });
288                }
289        }
290
291        protected String choicePriorityRecipeFolder(String text, String[] possibleValues) {
292                String result = inputChoice(text, null, possibleValues, possibleValues[0], null, false);
293                return result;
294        }
295
296        public void runSetupNodes() throws Exception {
297                if (!Boolean.valueOf(System.getProperty("skip.startup"))) {
298                        Node[] theNodes = fConfigNode.getNodes(SpecialCommands.STARTUP);
299                        TemplateProcessor tp = new TemplateProcessor(fSystemVariables, fConfigNode, getStartDir());
300                        if (theNodes != null) {
301                                for (Node node : theNodes) {
302                                        final String theAttribut = tp.replaceProperties(node.getAttribute("task"));
303                                        boolean async = false;
304                                        String asyncValue = tp.replaceProperties(node.getAttribute("async"));
305                                        if (asyncValue != null) {
306                                                async = Boolean.valueOf(asyncValue);
307                                        }
308                                        if (theAttribut != null) {
309                                                runTask(theAttribut, async);
310                                        } else {
311                                                RecipeRunner taskEditor = createTestRunner(null);
312                                                taskEditor.runTest(new Node[] { node });
313                                        }
314                                }
315                        }
316                }
317        }
318
319        protected void loadCustomProperties() {
320                if (fUserPreferences == null) {
321                        fUserPreferences = new Properties();
322
323                        // loading users preferences
324                        File preferencesFile = getPreferencesFile();
325                        try {
326                                FileInputStream fileInputStream = new FileInputStream(preferencesFile);
327                                fUserPreferences.load(fileInputStream);
328                                fileInputStream.close();
329
330                        } catch (IOException e) {
331                                // System.out.println("User preferences configuration file is not found: " +
332                                // preferencesFile);
333                        }
334                }
335        }
336
337        protected File getPreferencesFile() {
338                String configurationName = getConfigurationName();
339                String fileName;
340                if (configurationName != null) {
341                        fileName = configurationName + ".properties";
342                } else {
343                        fileName = ".properties";
344                }
345                File preferencesDir = new File(getHomeWorkingDir(), "preferences");
346                if (preferencesDir.exists() == false) {
347                        preferencesDir.mkdirs();
348                }
349                return new File(preferencesDir, fileName);
350        }
351
352        public String getCustomConfPropFileName(String configurationName) {
353                return getHomeConfigurationsDir() + "/" + fUser + "." + configurationName + ".properties";
354        }
355
356        public File getHomeConfigurationsDir() {
357                File file = new File(getHomeWorkingDir(), "configuration");
358                return file;
359        }
360
361        public void refreshTaskPath() throws IOException {
362                fTestsDescList.clear();
363                TemplateProcessor tp = new TemplateProcessor(fSystemVariables, fConfigNode, getStartDir());
364                getRecipesScaner().loadTaskPath(getConfigNode(), tp);
365        }
366
367        public void progressValue(int i, int length, boolean success) {
368
369        }
370
371        public void progressText(String name) {
372
373        }
374
375        public File getFile(String filePath) {
376                File file = null;
377                if (!StringUtils.startsWithAny(filePath, new String[] { "https:", "http:" })) {
378                        if (filePath != null) {
379                                if (filePath.startsWith("classpath:") || filePath.startsWith("jar:") || filePath.startsWith("file:")
380                                                || '/' == filePath.charAt(0) || '\\' == filePath.charAt(0) || filePath.indexOf(":\\") > 0
381                                                || '/' == filePath.charAt(0)) {
382                                        file = new File(filePath);
383                                } else {
384                                        file = new File(baseDir, filePath);
385                                }
386                        }
387                }
388
389                return file;
390        }
391
392        public String inputValue(String aName, String description, String aValue, ILogger log, String type,
393                        boolean notifyMe, Processor processor) {
394                System.out.print("Input ");
395                String line = inputValue(aName, description, null, type, null);
396                return line;
397        }
398
399        public String inputValue(String name, String description, String defaultValue, String type, Processor processor) {
400                if (defaultValue == null) {
401                        defaultValue = AEWorkspace.getInstance().getDefaultUserConfiguration(".inputValue." + name, defaultValue);
402                }
403
404                boolean password = "password".equalsIgnoreCase(type);
405
406                String showValue = !password ? defaultValue
407                                : (defaultValue != null ? StringUtils.repeat("*", defaultValue.length()) : "");
408                String message = "\"" + StringUtils.defaultIfEmpty(description, name) + "\""
409                                + (StringUtils.isEmpty(defaultValue) ? "" : " [" + showValue + "]") + ": ";
410                System.out.print(message);
411
412                String line = null;
413                if (!Processor.isSilentMode(processor)) {
414                        line = readLine(password);
415                        if (StringUtils.isEmpty(line)) {
416                                line = defaultValue;
417                        } else {
418                                AEWorkspace.getInstance().setDefaultUserConfiguration(".inputValue." + name, line);
419                        }
420                } else {
421                        line = defaultValue;
422                        System.out.println(defaultValue);
423                }
424                return line;
425        }
426
427        @Override
428        public boolean confirmation(String name, String message, Processor unit, boolean notifyMe) throws Exception {
429                if (StringUtils.isBlank(name)) {
430                        System.out.print(message + ", (yes/no): ");
431                } else {
432                        System.out.print(name + " [" + message + "], (yes/no): ");
433                }
434                boolean result = false;
435                String line = readLine(false);
436                result = BooleanUtils.toBoolean(line);
437                return result;
438        }
439
440        public void inputDataTable(Processor unit, Node aTableNode, boolean notifyMe) throws IOException {
441                Node[] theVariablesNodes = aTableNode.getNodes("var");
442                String theLine = null;
443
444                String theFileAttribut = aTableNode.getAttribute("file");
445                if (unit != null)
446                        theFileAttribut = unit.replaceProperties(aTableNode.getAttribute("file"));
447
448                if (theFileAttribut != null) {
449                        File file = unit.getFile(theFileAttribut);
450                        if (file.exists()) {
451                                while ((theLine = readLine(false)) != null) {
452                                        theLine = theLine.trim();
453                                        if (theLine.length() == 0) {
454                                                continue;
455                                        }
456                                        if (theLine.charAt(0) == '#') {
457                                                continue;
458                                        }
459                                        int thePbrk = theLine.indexOf('=');
460
461                                        String theName = StringUtils.upperCase(theLine.substring(0, thePbrk));
462                                        String theValue = theLine.substring(thePbrk + 1);
463
464                                        Node theNode = new Node("var");
465                                        theNode.setAttribute("name", theName);
466                                        theNode.setAttribute("value", theValue);
467
468                                        for (Node node : theVariablesNodes) {
469                                                if (node.getAttribute("name").equalsIgnoreCase(theName)) {
470                                                        node.setAttribute("value", theValue);
471                                                }
472                                        }
473
474                                }
475                        }
476                } else {
477                        String title = aTableNode.getAttribute("name");
478
479                        for (Node node : theVariablesNodes) {
480                                String name = node.getAttribute("name");
481                                String value = node.getAttribute("value");
482
483                                String defaultValue = value;
484
485                                String savedVarName = ".inputValue." + title + "." + StringUtils.upperCase(name);
486                                if (defaultValue == null) {
487                                        defaultValue = AEWorkspace.getInstance().getDefaultUserConfiguration(savedVarName, null);
488                                }
489                                if (defaultValue == null) {
490                                        defaultValue = node.getAttribute("default");
491                                }
492
493                                if (Processor.isSilentMode(unit)) {
494                                        value = defaultValue;
495                                } else {
496                                        value = inputValue(name, null, defaultValue, null, unit);
497                                        AEWorkspace.getInstance().setDefaultUserConfiguration(savedVarName, value);
498                                }
499
500                                unit.setVariableValue(name, value);
501                        }
502                }
503        }
504
505        public void loadConfProperties() throws IOException {
506
507                fSystemVariables.clear();
508
509                Properties properties = new Properties();
510                File theConfFile = new File(getCustomConfPropFileName(getConfigurationName()));
511                if (theConfFile.exists()) {
512                        FileInputStream theFile = new FileInputStream(theConfFile);
513                        properties.load(theFile);
514                        theFile.close();
515                }
516
517                Node[] theVarConfs = fConfigNode.getNodes("Var");
518                for (int i = 0; i < theVarConfs.length; i++) {
519                        Node varNode = theVarConfs[i];
520                        String name = StringUtils.upperCase(varNode.getAttribute("name"));
521
522                        if (name != null) {
523                                Map<String, String> variableDefinition = parseVariableDefinition(varNode);
524                                fSystemVariables.putAll(variableDefinition);
525
526                        } else {
527                                Processor templateProcessor = new BaseProcessor(fSystemVariables, fConfigNode, getStartDir());
528                                String filePath = templateProcessor.replaceProperties(varNode.getAttribute("file"));
529                                File file = getFile(filePath);
530                                templateProcessor.loadProperties(file, fSystemVariables, true);
531                        }
532                }
533
534                for (String key : properties.stringPropertyNames()) {
535                        fSystemVariables.put(key, properties.getProperty(key));
536                }
537
538                fSystemVariables.put("ENV", System.getenv());
539                fSystemVariables.put("SYSTEM", System.getProperties());
540
541                fSystemVariables.put("WORKINGDIR", getStartDir().getAbsolutePath());
542                fSystemVariables.put("HOME_WORKINGDIR", getHomeWorkingDir().getAbsolutePath());
543                fSystemVariables.put("START_TIME", Long.toString(startTime));
544                fSystemVariables.put("USER_NAME", fUser);
545
546                Node[] theTableVarConfs = fConfigNode.getNodes("Table");
547                Processor unit = new BaseProcessor(this, log, getStartDir());
548                Processor.setSilentMode(unit, true);
549
550                for (int i = 0; i < theTableVarConfs.length; i++) {
551                        inputDataTable(unit, theTableVarConfs[i], false);
552                        fSystemVariables.putAll(unit.getVariables());
553                }
554
555                boolean stopped = unit.isStopped();
556                if (stopped) {
557                        throw new TaskCancelingException();
558                }
559
560        }
561
562        private Map<String, String> parseVariableDefinition(Node varNode) {
563                Map<String, String> properties = new HashMap<>();
564
565                String name = StringUtils.upperCase(varNode.getAttribute("name"));
566
567                String attribute = varNode.getAttribute("init");
568                String type = varNode.getAttribute("type");
569
570                Object inputValue;
571                String typeValue = StringUtils.defaultIfBlank(type, "string");
572                switch (typeValue) {
573                case "array":
574                        Node[] nodes = varNode.getNodes("item");
575                        inputValue = new ArrayList<String>();
576                        for (Node node : nodes) {
577                                String text = node.getInnerText();
578                                @SuppressWarnings("unchecked")
579                                List<String> valueList = (List<String>) inputValue;
580                                valueList.add(text);
581                        }
582                        break;
583                case "map":
584                        inputValue = getMap(varNode);
585                        break;
586
587                default:
588                        inputValue = varNode.getAttribute("value");
589                        if (inputValue == null) {
590                                inputValue = varNode.getInnerText();
591                                if (StringUtils.isEmpty((String) inputValue)) {
592                                        inputValue = getMap(varNode);
593                                }
594                        }
595                        break;
596                }
597
598                if ("mandatory".equals(attribute) && properties.get(name) == null) {
599                        attribute = "console";
600                }
601
602                if ("console".equals(attribute)) {
603                        inputValue = inputValue(name, null, ObjectUtils.toString(inputValue, null), log, type, false, null);
604
605                        switch (StringUtils.defaultIfBlank(type, "string")) {
606                        case "array":
607                                break;
608                        case "map":
609                                inputValue = AEUtils.convertStringToMap((String) inputValue);
610                                break;
611
612                        default:
613                                break;
614                        }
615                }
616
617                if (inputValue != null)
618                        fSystemVariables.put(StringUtils.upperCase(name), inputValue);
619                else
620                        fSystemVariables.remove(name);
621
622                String savedValue = (String) properties.get(name);
623                Object value = null;
624                if (savedValue != null) {
625                        switch (StringUtils.defaultIfBlank(type, "string")) {
626                        case "array":
627                                @SuppressWarnings("unchecked")
628                                List<String> list = (List<String>) inputValue;
629                                list.remove(savedValue);
630
631                                List<String> arrayList = new ArrayList<>();
632                                arrayList.add(savedValue);
633                                arrayList.addAll(list);
634                                value = arrayList;
635                                break;
636                        case "map":
637                                value = AEUtils.convertStringToMap(savedValue);
638                                break;
639
640                        default:
641                                value = savedValue;
642                                break;
643                        }
644
645                        fSystemVariables.put(StringUtils.upperCase(name), value);
646                }
647
648                return properties;
649        }
650
651        private Object getMap(Node varNode) {
652                Object result = null;
653                Node[] nodes = varNode.getNodes("item");
654                if (nodes.length > 0) {
655                        result = new LinkedHashMap<String, String>();
656                        for (Node node : nodes) {
657                                @SuppressWarnings("unchecked")
658                                Map<String, String> valueMap = (Map<String, String>) result;
659                                String value = node.getAttribute("value");
660                                if (value == null) {
661                                        value = node.getInnerText();
662                                }
663                                valueMap.put(node.getAttribute("key"), value);
664                        }
665                }
666                return result;
667        }
668
669        public String selectConfiguration(String confName, Node configNodes, boolean refreshTaskPath) throws IOException {
670
671                allConfigNode = configNodes;
672
673                String configurationName = System.getProperty(ConfigConstants.CONFIG_NAME_SYS_PRPERTY_NAME);
674                if (confName != null) {
675                        configurationName = confName;
676                }
677
678                fConfigNode = getCurrentConfig(allConfigNode, configurationName);
679
680                if (fConfigNode == null) {
681                        System.out.println("Configuration '" + configurationName + "' not found in " + ConfigConstants.AE_CONFIG_XML
682                                        + " file.");
683                        return configurationName;
684
685                } else {
686                        setConfigurationName(fConfigNode.getAttribute("name"));
687
688                        if (configurationName == null) {
689                                configurationName = fConfigNode.getAttribute("name");
690                                if (configurationName == null)
691                                        configurationName = fConfigNode.getAttribute("description");
692                        }
693
694                        loadConfProperties();
695
696                        Node[] theLocations = fConfigNode.getNodes("Locale");
697                        if (theLocations != null && theLocations.length > 0) {
698                                Node theLocation = theLocations[0];
699                                String theISO3Language = theLocation.getAttribute("ISO3Language");
700                                String theDisplayName = theLocation.getAttribute("DisplayName");
701                                Locale[] availableLocales = Locale.getAvailableLocales();
702
703                                boolean theFound = false;
704                                for (int l = 0; l < availableLocales.length; l++) {
705                                        if (availableLocales[l].getISO3Language().equals(theISO3Language)) {
706                                                Locale.setDefault(availableLocales[l]);
707                                                System.out.println("Set location ISO3Language: " + theISO3Language);
708                                                theFound = true;
709                                                break;
710                                        }
711                                        if (availableLocales[l].getDisplayName().equals(theDisplayName)) {
712                                                Locale.setDefault(availableLocales[l]);
713                                                System.out.println("Set location DisplayName: " + theDisplayName);
714                                                theFound = true;
715                                                break;
716                                        }
717                                }
718
719                                if (theFound == false) {
720                                        for (int j = 0; j < availableLocales.length; j++) {
721                                                System.out.println(j + ". " + availableLocales[j].getDisplayName());
722                                        }
723                                }
724                        }
725
726                        configuration();
727
728                        return fConfigurationName;
729                }
730
731        }
732
733        public void setDefaultUserConfiguration(String propertyName, String value) {
734
735                propertyName = getFullConfPropertyName(propertyName);
736
737                if (value != null) {
738                        if (cryptoUtilAesGcm != null) {
739                                value = cryptoUtilAesGcm.encrypt(value);
740                        }
741
742                        fUserPreferences.setProperty(propertyName, value);
743
744                        try {
745                                File preferencesFile = getPreferencesFile();
746                                FileOutputStream fileInputStream = new FileOutputStream(preferencesFile);
747
748                                fUserPreferences.store(fileInputStream, null);
749                                fileInputStream.close();
750
751                        } catch (IOException e) {
752                                System.out.println("Write default user setting is failed. Error: " + e.getMessage());
753                        }
754                } else {
755                        if (fUserPreferences.get(propertyName) != null) {
756                                fUserPreferences.remove(propertyName);
757                        }
758                }
759
760        }
761
762        private String getFullConfPropertyName(String propertyName) {
763                return propertyName;
764        }
765
766        public String getDefaultUserConfiguration(String aName, String theDefaultConfiguration) {
767                aName = getFullConfPropertyName(aName);
768
769                loadCustomProperties();
770                String theProperty = fUserPreferences.getProperty(aName);
771
772                if (theProperty != null) {
773                        if (cryptoUtilAesGcm != null) {
774                                theDefaultConfiguration = cryptoUtilAesGcm.decrypt(theProperty);
775                        } else {
776                                theDefaultConfiguration = theProperty;
777                        }
778                }
779
780                return theDefaultConfiguration;
781        }
782
783        public Node getCurrentConfig(Node configs, String aNameConfiguration) {
784                Node[] configNodes = configs.getNodes(CONFIGURATION_TITLE);
785
786                ArrayList<String> possibleValues = new ArrayList<>();
787
788                for (int i = 0; i < configNodes.length; i++) {
789                        Node node = configNodes[i];
790                        String name = node.getAttribute("name");
791                        String ip = node.getAttribute("ip");
792                        if (ip == null || isEnableIp(ip)) {
793
794                                if (possibleValues.contains(name)) {
795                                        throw new IllegalArgumentException("Duplication name configuration: " + name);
796                                }
797
798                                if (!name.startsWith("#")) {
799                                        possibleValues.add(name);
800                                }
801                        }
802                }
803
804                if (CollectionUtils.isNotEmpty(possibleValues)) {
805                        String configName = possibleValues.get(0);
806                        if (aNameConfiguration != null) {
807                                configName = aNameConfiguration;
808                        }
809
810                        if (possibleValues.size() > 1 && aNameConfiguration == null) {
811                                configName = selectConfiguration(possibleValues.toArray(new String[possibleValues.size()]));
812                        }
813
814                        Node theConfigNode = prepareConfigurationNode(configs, configName);
815                        return theConfigNode;
816                }
817
818                return null;
819        }
820
821        private boolean isEnableIp(String ip) {
822                Enumeration<NetworkInterface> networkInterfaces;
823                Pattern compile = Pattern.compile(ip);
824                try {
825                        networkInterfaces = NetworkInterface.getNetworkInterfaces();
826                        while (networkInterfaces.hasMoreElements()) {
827                                NetworkInterface nextElement = networkInterfaces.nextElement();
828                                Enumeration<InetAddress> inetAddresses = nextElement.getInetAddresses();
829                                while (inetAddresses.hasMoreElements()) {
830                                        InetAddress nextElement2 = inetAddresses.nextElement();
831                                        if (nextElement2 instanceof Inet4Address) {
832                                                Inet4Address address = (Inet4Address) nextElement2;
833                                                String hostAddress = address.getHostAddress();
834                                                if (compile.matcher(hostAddress).matches()) {
835                                                        return true;
836                                                }
837                                        }
838                                }
839                        }
840                } catch (SocketException e) {
841                        e.printStackTrace();
842                }
843                return false;
844        }
845
846        private Node prepareConfigurationNode(Node configs, String configName) {
847
848                Node configNode = configs.findNode(CONFIGURATION_TITLE, "name", configName);
849                Node baseNode = null;
850
851                if (configNode != null) {
852                        String baseConfig = configNode.getAttribute("base");
853
854                        if (baseConfig != null) {
855                                baseNode = prepareConfigurationNode(configs, baseConfig);
856
857                                if (baseNode != null) {
858                                        baseNode = (Node) baseNode.clone();
859                                        baseNode.setAttributes(configNode.getAttributes());
860
861                                        for (Iterator<Node> theIterator = configNode.iterator(); theIterator.hasNext();) {
862                                                Node theNode = theIterator.next();
863
864                                                String theTagName = theNode.getTag();
865                                                Node[] theNodeArray = baseNode.getNodes(theTagName);
866
867                                                if (theNodeArray.length > 1) {
868                                                        String theName = theNode.getAttribute("name");
869
870                                                        Node theBaseTag = baseNode.findNode(theTagName, "name", theName);
871
872                                                        if (theBaseTag != null) {
873                                                                System.out.println(
874                                                                                "Change node: " + theTagName + " name=" + theName + " Value: " + theNode);
875                                                                int indexOf = baseNode.indexOf(theBaseTag);
876                                                                Node object = baseNode.get(indexOf);
877                                                                if (object.getTag() == theTagName)
878                                                                        baseNode.remove(indexOf);
879                                                        }
880                                                }
881                                                baseNode.add(theNode);
882                                        }
883
884                                } else {
885                                        System.out.println("Base configuration is not found. Name: " + baseConfig);
886                                        baseNode = configNode;
887                                }
888                        } else
889                                baseNode = configNode;
890
891                } else
892                        baseNode = configNode;
893
894                return baseNode;
895        }
896
897        public File getStartDir() {
898                return getRecipesScaner().getStartDir();
899        }
900
901        public String inputChoice(String name, String description, String[] values, String defaultValue,
902                        Processor taskProcessor, boolean notifyMe) {
903                if (defaultValue == null && values.length > 0) {
904                        String value = getDefaultUserConfiguration(".choice." + name, null);
905                        if (value != null) {
906                                defaultValue = value;
907                        }
908                }
909
910                System.out.println("List of values for [" + name + "]:");
911                if (!Processor.isSilentMode(taskProcessor)) {
912                        int i = 1;
913                        for (String val : values) {
914                                println(String.format("%3s: ", i++) + val, Color.green);
915                        }
916                        defaultValue = inputInteger(name, values, defaultValue);
917                } else {
918                        System.out.println("Saved selection applied: " + defaultValue);
919                }
920
921                return defaultValue;
922        }
923
924        public String[] inputMultiChoice(String name, String[] values, String defaultValue, Processor taskProcessor) {
925                String[] result = null;
926
927                if (defaultValue == null && values.length > 0) {
928                        String value = getDefaultUserConfiguration("MultiTaskRunDialog:" + name, null);
929                        if (value != null) {
930                                defaultValue = value;
931                        }
932                }
933                boolean silent = taskProcessor != null && Processor.isSilentMode(taskProcessor);
934
935                boolean isDone = false;
936                do {
937                        try {
938                                System.out.println("List of values for [" + name + "]:");
939                                if (!silent) {
940                                        int i = 1;
941
942                                        for (String val : values) {
943                                                println(String.format("%3s: ", i++) + val, Color.green);
944                                        }
945                                        String preset = null;
946                                        System.out.print("Please select ");
947                                        defaultValue = inputValue(name, preset, defaultValue, null, taskProcessor);
948                                        result = getValue(values, defaultValue);
949                                        isDone = true;
950
951                                        AEWorkspace.getInstance().setDefaultUserConfiguration("MultiTaskRunDialog:" + name, defaultValue);
952                                } else {
953                                        if (defaultValue != null) {
954                                                result = getValue(values, defaultValue);
955                                                System.out.println("Saved selection applied: [" + StringUtils.join(result, ",") + "]");
956                                        }
957                                }
958                        } catch (ArrayIndexOutOfBoundsException e) {
959                                System.out.println(defaultValue + " - invalid value.");
960                                isDone = false;
961                        }
962                } while (!isDone && !silent);
963
964                return result;
965        }
966
967        private void println(String text, Color color) {
968                System.out.println(text);
969        }
970
971        protected String[] getValue(String[] values, String defaultValue) {
972                String[] result = null;
973                if (defaultValue != null) {
974                        String[] split = StringUtils.split(defaultValue, ";");
975
976                        try {
977                                result = new String[split.length];
978                                for (int j = 0; j < split.length; j++) {
979                                        result[j] = values[Integer.parseInt(split[j]) - 1];
980                                }
981                        } catch (NumberFormatException e) {
982                                result = split;
983                        }
984                }
985                return result;
986        }
987
988        public String inputInteger(String name, String[] values, String defaultValue) {
989
990                boolean isDone = false;
991                do {
992                        System.out.print(
993                                        "Please select" + (StringUtils.isEmpty(defaultValue) ? "" : " [" + defaultValue + "]") + ": ");
994
995                        int inputValue;
996                        String readLine = null;
997                        try {
998                                readLine = readLine(false);
999                                if (!StringUtils.isEmpty(readLine)) {
1000                                        inputValue = Integer.parseInt(readLine) - 1;
1001                                        defaultValue = values[inputValue];
1002                                        setDefaultUserConfiguration(".choice." + name, defaultValue);
1003                                }
1004
1005                                isDone = true;
1006
1007                        } catch (Exception e) {
1008                                System.out.println(readLine + " - invalid value.");
1009                                defaultValue = null;
1010                        }
1011                } while (!isDone);
1012
1013                return defaultValue;
1014        }
1015
1016        public String inputFile(String name, String description, File aDefaultFile, ILogger log, Processor taskProcessor) {
1017                String theResult = getDefaultUserConfiguration(".inputFile" + name,
1018                                aDefaultFile == null ? null : aDefaultFile.getAbsolutePath());
1019                return theResult;
1020        }
1021
1022        public void executeAnteaterMaven(File aeConfigFile, String action) {
1023
1024                String mavenHome = System.getProperty("maven.home");
1025
1026                if (mavenHome == null) {
1027                        mavenHome = getDefaultUserConfiguration(".inputFile.maven.home", null);
1028                        if(mavenHome == null) {
1029                                mavenHome = inputFile("Set Maven Home Path", null, null, log, null);
1030                                setDefaultUserConfiguration(".inputFile.maven.home", mavenHome);
1031                        }
1032                        System.setProperty("maven.home", mavenHome);
1033                }
1034
1035                Invoker invoker = new DefaultInvoker();
1036                InvocationRequest request = new DefaultInvocationRequest();
1037                request.setPomFile(aeConfigFile);
1038                Properties properties = new Properties();
1039                String recipes = System.getProperty(ConfigConstants.RECIPES_PARAM_NAME);
1040                if (recipes != null) {
1041                        properties.setProperty(ConfigConstants.RECIPES_PARAM_NAME, recipes);
1042                }
1043                request.setProperties(properties);
1044                request.addArg("ae:" + action);
1045                request.setDebug(Boolean.parseBoolean(System.getProperty("debug", "false")));
1046                request.setBaseDirectory(aeConfigFile.getParentFile());
1047                request.setInputStream(System.in);
1048                InvocationResult result;
1049                try {
1050                        result = invoker.execute(request);
1051                        if (result.getExitCode() == 0) {
1052                                System.out.println("Maven build completed successfully!");
1053
1054                        } else {
1055                                System.err.println("Maven build failed with exit code: " + result.getExitCode());
1056                                if (result.getExecutionException() != null) {
1057                                        result.getExecutionException().printStackTrace();
1058                                }
1059                        }
1060
1061                        System.exit(result.getExitCode());
1062                } catch (MavenInvocationException e) {
1063                        e.printStackTrace();
1064                        System.exit(1);
1065                }
1066        }
1067
1068        public File getPomLocation(String confFileName, String aeDir) {
1069                aeDir = StringUtils.defaultIfBlank(aeDir, "");
1070                confFileName = confFileName.replace('\\', '/');
1071                String pomFilePath = null;
1072                if (StringUtils.isEmpty(aeDir)) {
1073                        pomFilePath = StringUtils.substringBeforeLast(confFileName, "/src/");
1074                } else {
1075                        String relativePath = aeDir + "/" + ConfigConstants.AE_CONFIG_XML;
1076                        if (StringUtils.endsWith(confFileName, relativePath)) {
1077                                pomFilePath = StringUtils.replace(confFileName, relativePath, "");
1078                        }
1079                }
1080
1081                File pomFile = null;
1082                if (pomFilePath != null) {
1083                        pomFile = new File(pomFilePath, "pom.xml");
1084                        if (!pomFile.exists()) {
1085                                System.out.println("POM file not found: " + pomFilePath);
1086                                pomFile = null;
1087                        }
1088                }
1089                return pomFile;
1090        }
1091
1092        public List<String> findAEconfigs(File path) {
1093                if (path == null) {
1094                        path = SystemUtils.getUserDir();
1095                }
1096
1097                List<String> confFiles = new ArrayList<>();
1098                try (Stream<Path> stream = Files.walk(Paths.get(path.getAbsolutePath()), 10)) {
1099                        stream.filter(f -> f.endsWith(ConfigConstants.AE_CONFIG_XML)).forEach(f -> confFiles.add(f.toString()));
1100                } catch (NoSuchFileException e) {
1101                        // do nothing.
1102                } catch (IOException e) {
1103                        e.printStackTrace();
1104                }
1105                return confFiles;
1106        }
1107
1108        protected String selectConfiguration(String[] configNames) {
1109                String configName = choiceValue(CONFIGURATION_TITLE, null, configNames, null, true, null);
1110                return configName;
1111        }
1112
1113        public String getTestPath(String name) {
1114                String recipePath = null;
1115                if (name != null) {
1116                        recipePath = fTestsDescList.getProperty(name);
1117                }
1118                return recipePath;
1119        }
1120
1121        public RecipeRunner runTask(String name, boolean async) {
1122                RecipeRunner runner = null;
1123                if (name != null) {
1124                        runner = createTestRunner(name);
1125                        String testPath = getTestPath(name);
1126                        if (testPath != null) {
1127                                if (async) {
1128                                        TaskThread theThread = new TaskThread(runner, testPath);
1129                                        theThread.start();
1130
1131                                } else {
1132                                        try {
1133                                                runner.makeRecipe(testPath);
1134                                        } catch (CommandException e) {
1135                                                log.error("Task failed.", e);
1136                                        }
1137                                }
1138                        }
1139                }
1140
1141                return runner;
1142        }
1143
1144        protected RecipeRunner createTestRunner(String name) {
1145                RecipeRunner runner = new RecipeRunner(this);
1146                Processor processor = new BaseProcessor(this, log, getStartDir());
1147                processor.setTestListener(runner);
1148                runner.setProcessor(processor);
1149                runner.setLog(log);
1150                return runner;
1151        }
1152
1153        public void removeTestPath(String name) {
1154                if (fTestsDescList.get(name) != null)
1155                        fTestsDescList.remove(name);
1156        }
1157
1158        public void setTestPath(String name, String path) {
1159                fTestsDescList.put(name, path);
1160        }
1161
1162        public String getWorkingDir() {
1163                return getStartDir().getAbsolutePath();
1164        }
1165
1166        public MultiTaskRunDialog tasksChoice(MultiTaskRunDialog dialog, String[] list, boolean exceptionIgnoreFlag,
1167                        Object setup, Processor taskProcessor, boolean visible) {
1168
1169                if (setup == null) {
1170                        boolean consoleDefaultInput = isConsoleDefaultInput(dialog.getName(), null);
1171                        setup = inputMultiChoice(dialog.getName(), list, null, taskProcessor);
1172                        dialog.select((String[]) setup, consoleDefaultInput);
1173                }
1174
1175                dialog.setExceptionIgnore(exceptionIgnoreFlag);
1176                dialog.setVisible(visible);
1177                dialog.showDialog(dialog.getName(), list, taskProcessor.getListener().isNotifyMe());
1178
1179                return dialog;
1180        }
1181
1182        public Map<String, Object> getSystemVariables() {
1183                return fSystemVariables;
1184        }
1185
1186        public void setConsoleDefaultInput(boolean defaultMode) {
1187                this.defaultMode = defaultMode;
1188        }
1189
1190        public boolean isConsoleDefaultInput(String varName, String description) {
1191                return defaultMode;
1192        }
1193
1194        public Node getConfigNode() {
1195                return fConfigNode;
1196        }
1197
1198        public Node getAllConfigNode() {
1199                return allConfigNode;
1200        }
1201
1202        public Properties getTasksMap() {
1203                return fTestsDescList;
1204        }
1205
1206        public Properties getTestsDescList() {
1207                return fTestsDescList;
1208        }
1209
1210        public Object[] getPublicTestsList() {
1211                Enumeration<Object> keys = fTestsDescList.keys();
1212                List<String> result = new ArrayList<String>();
1213                while (keys.hasMoreElements()) {
1214                        String key = (String) keys.nextElement();
1215                        if (!key.startsWith("#")) {
1216                                result.add(key);
1217                        }
1218                }
1219                String[] a = result.toArray(new String[result.size()]);
1220                Arrays.sort(a);
1221                return a;
1222        }
1223
1224        public void startTaskNotify(RecipeRunner task) {
1225
1226        }
1227
1228        public String choiceValue(String name, String description, Object[] possibleValues, ILogger log, boolean notifyMe,
1229                        Processor processor) {
1230                String result = null;
1231                description = StringUtils.defaultString(description, name);
1232
1233                if (possibleValues != null && possibleValues.length > 0) {
1234                        result = getDefaultUserConfiguration(".choiceValue." + name, null);
1235
1236                        String[] values = Arrays.copyOf(possibleValues, possibleValues.length, String[].class);
1237                        result = inputChoice(description, null, values, result, processor, notifyMe);
1238
1239                        AEWorkspace.getInstance().setDefaultUserConfiguration(".choiceValue." + name, result);
1240                } else {
1241                        result = (String) possibleValues[0];
1242                }
1243
1244                return result;
1245        }
1246
1247        public static AEWorkspace getInstance() {
1248                return instance;
1249        }
1250
1251        public void resetConfiguration() {
1252                fConfigNode = null;
1253        }
1254
1255        public void resetConfigurationName() {
1256                setConfigurationName(null);
1257        }
1258
1259        public String getConfigurationName() {
1260                return this.fConfigurationName;
1261        }
1262
1263        public void loadConfiguration(boolean refreshTaskMap) {
1264                loadConfiguration(null, refreshTaskMap);
1265        }
1266
1267        public void addRunner(RecipeRunner testRunner) {
1268                runners.add(testRunner);
1269        }
1270
1271        public void removeRunner(RecipeRunner testRunner) {
1272                runners.remove(testRunner);
1273        }
1274
1275        public void stopAllRunners() {
1276                RecipeRunner[] array = runners.toArray(new RecipeRunner[runners.size()]);
1277                for (RecipeRunner runner : array) {
1278                        runner.stopTest();
1279                }
1280        }
1281
1282        public void setBaseDir(File baseDir) {
1283                this.baseDir = baseDir;
1284        }
1285
1286        public File getBaseDir() {
1287                return this.baseDir;
1288        }
1289
1290        public Set<Class<?>> getOperationsClasses() {
1291                return operationsClasses;
1292        }
1293
1294        public void setOperationsClasses(@SuppressWarnings("rawtypes") Set<Class> operationsClasses) {
1295                if (operationsClasses != null) {
1296                        opsMethods = new HashMap<String, OperationHolder>();
1297                        try {
1298                                Method[] methods = Object.class.getMethods();
1299                                String exclude[] = new String[methods.length];
1300                                for (int i = 0; i < exclude.length; i++) {
1301                                        exclude[i] = methods[i].getName();
1302                                }
1303                                Arrays.sort(exclude);
1304
1305                                for (Class<?> operationClass : operationsClasses) {
1306                                        methods = operationClass.getMethods();
1307                                        for (Method method : methods) {
1308                                                if (Arrays.binarySearch(exclude, method.getName()) < 0
1309                                                                && method.getModifiers() == Modifier.PUBLIC) {
1310                                                        String shortClassName = operationClass.getName();
1311                                                        opsMethods.put(shortClassName + "." + method.getName(),
1312                                                                        new OperationHolder(operationClass, method));
1313                                                }
1314                                        }
1315                                }
1316                        } catch (Exception e) {
1317                                throw new IllegalArgumentException(e);
1318                        }
1319                }
1320        }
1321
1322        public OperationHolder getOperationsMethod(String name) {
1323                return opsMethods.get(name);
1324        }
1325
1326        public Map<String, OperationHolder> getOperationsMethods() {
1327                return opsMethods;
1328        }
1329
1330        public Set<RecipeRunner> getRunners() {
1331                return runners;
1332        }
1333
1334        @Override
1335        public void finished(String aTestFile) {
1336        }
1337
1338        public static Properties getUserPreferences() {
1339                return fUserPreferences;
1340        }
1341
1342        public String[] getTestsList() {
1343                String[] array = fTestsDescList.keySet().toArray(new String[fTestsDescList.size()]);
1344                Arrays.sort(array);
1345                return array;
1346        }
1347
1348        @Override
1349        public MessageHandler message(Processor taskProcessor, String description, String message, boolean notifyMe) {
1350                return new MessageHandler();
1351        }
1352
1353        public void setConfigurationName(String fConfigurationName) {
1354                this.fConfigurationName = fConfigurationName;
1355                fUserPreferences = null;
1356                loadCustomProperties();
1357        }
1358
1359        public void initUserPreferencesEncryption(String password) {
1360                Node configNode = getConfigNode();
1361                boolean userPreferencesEncryption = Boolean.parseBoolean(configNode.getAttribute("userPreferencesEncryption"));
1362
1363                if (userPreferencesEncryption) {
1364                        if (password == null) {
1365                                System.out.print(MESSAGE_PASSWORD_REQUIRED);
1366
1367                                Console console = System.console();
1368                                if (console == null) {
1369                                        password = readLine(true);
1370                                } else {
1371                                        char[] pwd = console.readPassword();
1372                                        password = new String(pwd);
1373                                }
1374                        }
1375
1376                        byte[] pwdBytes;
1377                        try {
1378                                pwdBytes = new String(password).getBytes("UTF-8");
1379                        } catch (UnsupportedEncodingException e) {
1380                                throw new IllegalArgumentException(e);
1381                        }
1382                        password = Base64.getEncoder().encodeToString(pwdBytes);
1383                        cryptoUtilAesGcm = new Encryptor(password);
1384                        Enumeration<Object> keys = fUserPreferences.keys();
1385                        while (keys.hasMoreElements()) {
1386                                String name = (String) keys.nextElement();
1387                                getDefaultUserConfiguration(name, name);
1388                                break;
1389                        }
1390                }
1391        }
1392
1393        public void close() {
1394                closeHooks.forEach(e -> e.run());
1395        }
1396
1397        public void addCloseHook(Runnable shutdownHook) {
1398                closeHooks.add(shutdownHook);
1399        }
1400
1401        public RecipesScanner getRecipesScaner() {
1402                return recipesScaner;
1403        }
1404
1405        public void setStartDir(File startDir) {
1406                recipesScaner.setStartDir(startDir);
1407        }
1408
1409        private String readLine(boolean password) {
1410                try {
1411                        Console console = System.console();
1412                        String line;
1413                        Toolkit.getDefaultToolkit().beep();
1414                        if (console != null) {
1415                                if (password) {
1416                                        line = new String(console.readPassword());
1417                                } else {
1418                                        line = console.readLine();
1419                                }
1420                        } else {
1421                                InputStreamReader inputStreamReader = new InputStreamReader(System.in);
1422                                BufferedReader reader = new BufferedReader(inputStreamReader);
1423                                try {
1424                                        line = reader.readLine();
1425                                } catch (IOException e) {
1426                                        line = null;
1427                                }
1428                        }
1429
1430                        return line;
1431
1432                } catch (RuntimeException e) {
1433                        throw new TaskCancelingException();
1434                }
1435        }
1436
1437        protected void initLogger(Node configNode) {
1438                Properties logProperties = fillLogProperties(configNode);
1439                PropertyConfigurator.configure(logProperties);
1440                log = new Logger("AEWorkspace");
1441        }
1442
1443        protected Properties fillLogProperties(Node configNode) {
1444                Properties logProperties = new Properties();
1445                if (configNode != null) {
1446                        logProperties = MapUtils.toProperties(configNode.getAttributes());
1447                }
1448                Node[] theLoggerNodes = fConfigNode.getNodes("Logger");
1449                Node node = theLoggerNodes[0];
1450                boolean consoleOn = false;
1451                if (theLoggerNodes != null && theLoggerNodes.length > 0) {
1452                        node = theLoggerNodes[0];
1453                        logProperties.putAll(node.getAttributes());
1454                }
1455
1456                TemplateProcessor templateProcessor = new TemplateProcessor(fSystemVariables, fConfigNode, getStartDir());
1457
1458                if (logProperties.getProperty("rootLogger") != null) {
1459                        String rootLogger = templateProcessor.replaceProperties(logProperties.getProperty("rootLogger"));
1460
1461                        consoleOn = rootLogger.indexOf("CONSOLE") >= 0;
1462
1463                        logProperties.setProperty("log4j.rootLogger", rootLogger);
1464                        logProperties.remove("rootLogger");
1465                }
1466                if (logProperties.getProperty("File") != null) {
1467                        String lofFileName = templateProcessor.replaceProperties(logProperties.getProperty("File"));
1468                        File file = new File(lofFileName);
1469                        if (file != null && file.getParentFile() != null && file.getParentFile().exists() == false)
1470                                file.getParentFile().mkdirs();
1471                        logProperties.setProperty("log4j.appender.LOGFILE.File", lofFileName);
1472                }
1473                if (logProperties.getProperty("Threshold") != null) {
1474                        logProperties.setProperty("log4j.appender.LOGFILE.Threshold",
1475                                        templateProcessor.replaceProperties(logProperties.getProperty("Threshold")));
1476                        if (consoleOn)
1477                                logProperties.setProperty("log4j.appender.CONSOLE.Threshold",
1478                                                templateProcessor.replaceProperties(logProperties.getProperty("Threshold")));
1479                        logProperties.remove("Threshold");
1480                }
1481                if (logProperties.getProperty("ConversionPattern") != null) {
1482                        logProperties.setProperty("log4j.appender.LOGFILE.layout.ConversionPattern",
1483                                        templateProcessor.replaceProperties(logProperties.getProperty("ConversionPattern")));
1484                        if (consoleOn)
1485                                logProperties.setProperty("log4j.appender.CONSOLE.layout.ConversionPattern",
1486                                                templateProcessor.replaceProperties(logProperties.getProperty("ConversionPattern")));
1487                        logProperties.remove("ConversionPattern");
1488                } else {
1489                        logProperties.setProperty("log4j.appender.LOGFILE.layout.ConversionPattern",
1490                                        "%d{dd.MM.yyyy HH:mm:ss} %-5p %m %n");
1491                        if (consoleOn)
1492                                logProperties.setProperty("log4j.appender.CONSOLE.layout.ConversionPattern",
1493                                                "%d{dd.MM.yyyy HH:mm:ss} %-5p %m %n");
1494                }
1495                logProperties.setProperty("log4j.appender.logfile.DatePattern", "'.'yyyy-MM-dd");
1496                logProperties.setProperty("log4j.appender.LOGFILE", "org.apache.log4j.DailyRollingFileAppender");
1497                if (consoleOn)
1498                        logProperties.setProperty("log4j.appender.CONSOLE", "org.apache.log4j.ConsoleAppender");
1499                logProperties.setProperty("log4j.appender.LOGFILE.layout", "org.apache.log4j.PatternLayout");
1500                if (consoleOn)
1501                        logProperties.setProperty("log4j.appender.CONSOLE.layout", "org.apache.log4j.PatternLayout");
1502
1503                logProperties.setProperty("log4j.logger.java.desktop", "ERROR");
1504                return logProperties;
1505        }
1506
1507}