001package org.dllearner.cli;
002
003import org.apache.commons.lang.exception.ExceptionUtils;
004import org.dllearner.configuration.IConfiguration;
005import org.dllearner.configuration.spring.ApplicationContextBuilder;
006import org.dllearner.configuration.spring.DefaultApplicationContextBuilder;
007import org.dllearner.confparser.ConfParserConfiguration;
008import org.dllearner.core.AbstractReasonerComponent;
009import org.dllearner.core.ComponentInitException;
010import org.dllearner.core.config.ConfigOption;
011import org.dllearner.reasoning.ClosedWorldReasoner;
012import org.slf4j.Logger;
013import org.slf4j.LoggerFactory;
014import org.springframework.context.ApplicationContext;
015import org.springframework.core.io.FileSystemResource;
016import org.springframework.core.io.Resource;
017
018import java.io.File;
019import java.io.IOException;
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023
024/**
025 * Base CLI class.
026 */
027public abstract class CLIBase2 {
028        static {
029                if (System.getProperty("log4j.configuration") == null)
030                        System.setProperty("log4j.configuration", "log4j.properties");
031        }
032
033        private static Logger logger = LoggerFactory.getLogger(CLIBase2.class);
034
035        protected ApplicationContext context;
036        protected File confFile;
037        protected IConfiguration configuration;
038        @ConfigOption(defaultValue = "INFO", description = "Configure logger log level from conf file. Available levels: \"FATAL\", \"ERROR\", \"WARN\", \"INFO\", \"DEBUG\", \"TRACE\". "
039                        + "Note, to see results, at least \"INFO\" is required.")
040        protected String logLevel = "INFO";
041
042        protected static boolean createIfNotExists(File f) {
043            if (f.exists()) return true;
044
045            File p = f.getParentFile();
046            if (p != null && !p.exists()) p.mkdirs();
047
048            try {
049                f.createNewFile();
050            } catch (IOException e) {
051                e.printStackTrace();
052                return false;
053            }
054            return true;
055        }
056
057        /**
058         * Find the primary cause of the specified exception.
059         *
060         * @param e The exception to analyze
061         * @return The primary cause of the exception.
062         */
063        protected static Throwable findPrimaryCause(Exception e) {
064            // The throwables from the stack of the exception
065            Throwable[] throwables = ExceptionUtils.getThrowables(e);
066
067            //Look For a Component Init Exception and use that as the primary cause of failure, if we find it
068            int componentInitExceptionIndex = ExceptionUtils.indexOfThrowable(e, ComponentInitException.class);
069
070            Throwable primaryCause;
071            if(componentInitExceptionIndex > -1) {
072                primaryCause = throwables[componentInitExceptionIndex];
073            }else {
074                //No Component Init Exception on the Stack Trace, so we'll use the root as the primary cause.
075                primaryCause = ExceptionUtils.getRootCause(e);
076            }
077            return primaryCause;
078        }
079
080        // separate init methods, because some scripts may want to just get the application
081        // context from a conf file without actually running it
082        public void init() throws IOException {
083                Resource confFileR = new FileSystemResource(confFile);
084                List<Resource> springConfigResources = new ArrayList<>();
085                configuration = new ConfParserConfiguration(confFileR);
086
087                ApplicationContextBuilder builder = new DefaultApplicationContextBuilder();
088                context = builder.buildApplicationContext(configuration, springConfigResources);
089        }
090
091        public abstract void run();
092
093        public void setContext(ApplicationContext context) {
094                this.context = context;
095        }
096
097        public ApplicationContext getContext() {
098                return context;
099        }
100
101        public File getConfFile() {
102                return confFile;
103        }
104
105        public void setConfFile(File confFile) {
106                this.confFile = confFile;
107        }
108
109        public void setLogLevel(String logLevel) {
110                this.logLevel = logLevel;
111        }
112
113        public String getLogLevel() {
114                return logLevel;
115        }
116
117        protected AbstractReasonerComponent getMainReasonerComponent() {
118                AbstractReasonerComponent rc = null;
119                // there can be 2 reasoner beans
120                        Map<String, AbstractReasonerComponent> reasonerBeans = context.getBeansOfType(AbstractReasonerComponent.class);
121
122                        if (reasonerBeans.size() > 1) {
123                                for (Map.Entry<String, AbstractReasonerComponent> entry : reasonerBeans.entrySet()) {
124                                        String key = entry.getKey();
125                                        AbstractReasonerComponent value = entry.getValue();
126
127                                        if (value instanceof ClosedWorldReasoner) {
128                                                rc = value;
129                                        }
130
131                                }
132                        } else {
133                                rc = context.getBean(AbstractReasonerComponent.class);
134                        }
135
136                        return rc;
137        }
138}