/** * SPINdle (version 2.2.2) * Copyright (C) 2009-2012 NICTA Ltd. * * This file is part of SPINdle project. * * SPINdle is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SPINdle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SPINdle. If not, see <http://www.gnu.org/licenses/>. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory */ package spindle.sys; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Hashtable; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import java.util.TreeMap; import java.util.logging.Level; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import com.app.utils.DateTime; import com.app.utils.FileManager; import com.app.utils.Properties; import com.app.utils.ResourcesUtils; import com.app.utils.Utilities; import spindle.ReasonerMain; import spindle.core.ReasonerUtilities; import spindle.io.IOManager; import spindle.sys.message.SystemMessage; /** * System configuration class. * <p> * Used to configure the system environment and the type of reasoning parameters. * </p> * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @since version 1.0.0 */ public class Conf { private static final Map<String, String> DEFAULT_ARGUMENT_VALUE_CHANGE = new TreeMap<String, String>() { private static final long serialVersionUID = 1L; { put(ConfTag.LOG_LEVEL, "INFO"); put(ConfTag.IS_SHOW_PROGRESS, "true"); put(ConfTag.IS_SHOW_RESULT, "true"); put(ConfTag.IS_SAVE_RESULT, "true"); put(ConfTag.IS_CONSOLE_MODE, "true"); put(ConfTag.IS_GARBAGE_COLLECTION, "true"); put(ConfTag.IS_MULTI_THREAD_MODE, "true"); put(ConfTag.IS_SEARCH_IO_CLASSES, "true"); put(ConfTag.IS_SHOW_STATISTICS, "true"); put(ConfTag.IS_LOG_INFERENCE_PROCESS, "true"); put(ConfTag.REASONER_AMBIGUOUS_PROPAGATION, "true"); put(ConfTag.REASONER_WELL_FOUNDED_SEMANTICS, "true"); } }; private static boolean isInitialized = false; // system properties protected static Properties props = null; protected static Map<String, WeakReference<AppLogger>> loggers = null; protected static Level logLevel = Level.INFO; private static ScriptEngine scriptEvaluationEngine = null; public static synchronized void initializeApplicationContext(Map<String, String> _args) { if (isInitialized) return; isInitialized = true; String libPath = System.getProperty("java.library.path") + ":."; System.setProperty("java.library.path", libPath); if (null == props) { if (null == System.getProperty(AppConst.SYSTEM_CONFIG_SHUTDOWN_HOOK)) { Runtime.getRuntime().addShutdownHook(new AppShutdownIntercepter()); } System.setProperty(AppConst.SYSTEM_CONFIG_SHUTDOWN_HOOK, AppConst.SHUTDOWN_HOOK_ADDED); System.out.println(AppConst.APP_START_MESSAGE); System.out.println(Messages.getSystemMessage(SystemMessage.APPLICATION_CONTEXT_INITIALIZE_START)); try { Messages.getLocale(); _loadConf(AppConst.CONF_FILE, _args); IOManager.initialize(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } // initialize the loggers loggers = new Hashtable<String, WeakReference<AppLogger>>(); // do something System.out.println(Messages.getSystemMessage(SystemMessage.APPLICATION_CONTEXT_INITIALIZE_END)); } } public static void terminateApplicationContext() { ReasonerUtilities.printPerformanceStatistics(ReasonerMain.performanceStatistics); System.out.println(Messages.getSystemMessage(SystemMessage.APPLICATION_CONTEXT_TERMINATE_START)); if (null != props) props.clear(); props = null; if (loggers != null) loggers.clear(); loggers = null; isInitialized = false; System.out.println(Messages.getSystemMessage(SystemMessage.APPLICATION_CONTEXT_TERMINATE_END)); } public static Properties getSystemProperties() { return props; } public static String getLicense() throws IOException { return ResourcesUtils.loadResourceFileAsString(AppConst.APP_LICENSE_FILE); } public static boolean isInitialized() { return isInitialized; } public static ScriptEngine getScriptEngine() { if (!isInitialized) initializeApplicationContext(null); if (null == scriptEvaluationEngine) { ScriptEngineManager evaluationEngineManager = new ScriptEngineManager(); String engineName = props.getProperty(ConfTag.THEORY_VARIABLE_BOOLEAN_EVALUATOR_ENGINE_NAME); scriptEvaluationEngine = evaluationEngineManager.getEngineByName(engineName); } return scriptEvaluationEngine; } public static String getConclusionExt() { if (!isInitialized) initializeApplicationContext(null); return props.getProperty(ConfTag.REASONER_CONCLUSION_DEFAULT_EXTENSION); } public static void setConclusionExt(final String defaultExtension) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.REASONER_CONCLUSION_DEFAULT_EXTENSION, defaultExtension); } public static boolean isShowProgress() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_SHOW_PROGRESS); } public static void setShowProgress(final boolean showProgress) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_SHOW_PROGRESS, Boolean.toString(showProgress)); } public static boolean isShowStatistics() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_SHOW_STATISTICS); } public static void setShowStatistics(final boolean showStatistics) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_SHOW_STATISTICS, Boolean.toString(showStatistics)); } public static boolean isShowResult() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_SHOW_RESULT); } public static void setShowResult(final boolean showResult) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_SHOW_RESULT, Boolean.toString(showResult)); } public static boolean isSaveResult() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_SAVE_RESULT); } public static void setSaveResult(final boolean saveResult) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_SAVE_RESULT, Boolean.toString(saveResult)); } public static boolean isConsoleMode() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_CONSOLE_MODE); } public static void setConsoleMode(final boolean consoleMode) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_CONSOLE_MODE, Boolean.toString(consoleMode)); } public static long getMemoryMonitorTimeInterval() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsLong(ConfTag.APP_MEMORY_MONITOR_TIME_INTERVAL); } public static void setMemoryMonitorTimeInterval(final long memoryMonitorTimeInterval) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.APP_MEMORY_MONITOR_TIME_INTERVAL, Long.toString(memoryMonitorTimeInterval)); } public static long getShowProgressTimeInterval() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsLong(ConfTag.APP_PROGRESS_TIME_INTERVAL); } public static void setShowProgressTimeInterval(final long showProgressTimeInterval) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.APP_PROGRESS_TIME_INTERVAL, Long.toString(showProgressTimeInterval)); } public static boolean isReasoningWithAmbiguityPropagation() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.REASONER_AMBIGUOUS_PROPAGATION); } public static void setReasoningWithAmbiguityPropagation(boolean reasoningWithAmbiguityPropagation) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.REASONER_AMBIGUOUS_PROPAGATION, Boolean.toString(reasoningWithAmbiguityPropagation)); } public static boolean isReasoningWithMixedTemporalLiterals() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.REASONER_CONTINUES_WITH_MIXED_TEMPORAL_LITERAL); } public static void setReasoningWithMixedTemporalLiterals(boolean reasoningWithMixedTemporalLiterals) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.REASONER_CONTINUES_WITH_MIXED_TEMPORAL_LITERAL, Boolean.toString(reasoningWithMixedTemporalLiterals)); } public static boolean isLogInferenceProcess() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_LOG_INFERENCE_PROCESS); } public static void setLogInferenceProcess(boolean logInferenceProcess) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_LOG_INFERENCE_PROCESS, Boolean.toString(logInferenceProcess)); } public static boolean isReasoningWithWellFoundedSemantics() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.REASONER_WELL_FOUNDED_SEMANTICS); } public static void setReasoningWithWellFoundedSemantics(final boolean reasoningWithWellFoundedSemantics) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.REASONER_WELL_FOUNDED_SEMANTICS, Boolean.toString(reasoningWithWellFoundedSemantics)); } public static String getTdlConclusionUpdaterClassName() { if (!isInitialized) initializeApplicationContext(null); return props.getProperty(ConfTag.REASONER_TDL_CONCLUSION_UPDATER); } public static String getTheoryAnalyser_stronglyConnectedComponentClassName() { if (!isInitialized) initializeApplicationContext(null); return props.getProperty(ConfTag.THEORY_ANALYSER_STRONGLY_COMPONENT_IMPL); } public static int getReasonerVersion() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsInteger(ConfTag.REASONER_VERSION); } public static void setReasonerVersion(int reasonerVersion) throws ConfigurationException { if (reasonerVersion < 0 || reasonerVersion > 2) throw new ConfigurationException("incorrect reasoner version"); props.setProperty(ConfTag.REASONER_VERSION, "" + reasonerVersion); } public static void setReasonerVersion(final String reasonerVersion) throws ConfigurationException { int loc = reasonerVersion.indexOf("."); String ver = ((loc >= 0) ? reasonerVersion.substring(0, loc) : reasonerVersion).trim(); if ("".equals(ver)) ver = "2"; try { setReasonerVersion(Integer.parseInt(ver)); } catch (Exception e) { throw new ConfigurationException(e); } } public static long getReasoningFileSleeptime() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsLong(ConfTag.APP_REASONING_SLEEPTIME); } /** * check for if SPINdle is running in multi-thread mode. * * @return True if SPINdle is running in multi-thread mode; false otherwise */ public static boolean isMultiThreadMode() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_MULTI_THREAD_MODE); } /** * The SPINdle ReasoningEngineFactory will generate a new reasoning engine for every request if this is set to true. * * @param isMultiThreadMode * @see spindle.engine.ReasoningEngineFactory */ public static void setMultiThreadMode(boolean isMultiThreadMode) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_MULTI_THREAD_MODE, Boolean.toString(isMultiThreadMode)); } // public static int getNoOfParallelReasoningThreads() { // if (!isInitialized) initializeApplicationContext(null); // return props.getPropertyAsInteger(ConfTag.REASONER_PARALLEL_REASONING_THREADS); // } // // public static void setNoOfParallelReasoningThreads(int noOfParallelReasoningThreads) { // if (!isInitialized) initializeApplicationContext(null); // props.setProperty(ConfTag.REASONER_PARALLEL_REASONING_THREADS, "" + noOfParallelReasoningThreads); // } public static boolean isReasonerGarbageCollection() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_GARBAGE_COLLECTION); } public static void setReasonerGarbageCollection(boolean isGarbageCollection) { if (!isInitialized) initializeApplicationContext(null); props.setProperty(ConfTag.IS_GARBAGE_COLLECTION, Boolean.toString(isGarbageCollection)); } public static long getGarbageCollectionTimeInterval() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsLong(ConfTag.REASONER_GARBAGE_COLLECTION_TIME_INTERVAL); } public static boolean isSearchIOclasses() { if (!isInitialized) initializeApplicationContext(null); return props.getPropertyAsBoolean(ConfTag.IS_SEARCH_IO_CLASSES); } public static void setLogLevel(final Level newLogLevel) { if (!isInitialized) initializeApplicationContext(null); logLevel = newLogLevel; } public static Level getLogLevel() { if (!isInitialized) initializeApplicationContext(null); return logLevel; } public static String getLogFolder() { if (!isInitialized) initializeApplicationContext(null); return props.getProperty(ConfTag.LOG_FOLDER); } public static String getLogFilePrefix() { if (!isInitialized) initializeApplicationContext(null); return props.getProperty(ConfTag.REASONER_LOG_FILE_PREFIX) + "_"; } public static String getLogFileExtension() { if (!isInitialized) initializeApplicationContext(null); String ext = props.getProperty(ConfTag.LOG_FILE_EXTENSION); return (ext.startsWith(".") ? ext : "." + ext); } public static AppLogger getLogger(String filename) { if (!isInitialized) initializeApplicationContext(null); if (null == filename || "".equals(filename.trim())) filename = "dummy.dfl"; File f = new File(filename); String logFilename = f.getName(); String fileExtension = FileManager.getFileExtension(logFilename); if (!"".equals(fileExtension)) logFilename = logFilename.substring(0, logFilename.length() - fileExtension.length() - 1); String modifiedLogFilename = getLogFilePrefix() + "[" + logFilename + "]" + DateTime.getCurrentTimeAsFileTimestamp() + getLogFileExtension(); File logFile = new File(getLogFolder(), modifiedLogFilename); AppLogger logger = new AppLoggerImpl(logFile); logger.setLogLevel(getLogLevel()); loggers.put(logger.getLoggerName(), new WeakReference<AppLogger>(logger)); return logger; } public static String getResultFolder() { if (!isInitialized) initializeApplicationContext(null); String folder = props.getProperty(ConfTag.APP_RESULT_FOLDER); return (folder.endsWith(FileManager.separator) ? folder : folder + FileManager.separator); } public static void addNewProperty(String propertyName, String propertyValue) throws ConfigurationException { if (null == propertyName || "".equals(propertyName.trim())) throw new ConfigurationException("property name is null"); String value = (null == propertyValue) ? "" : propertyValue; props.setProperty(propertyName.trim(), value); } private static <E> Map<String, String> updateProperties(Set<Entry<E, E>> updatedProperties) { Map<String, String> modifiedProperties = new TreeMap<String, String>(); if (null == updatedProperties || updatedProperties.size() == 0) return modifiedProperties; for (Entry<E, E> entry : updatedProperties) { String key = entry.getKey().toString().trim(); if (!props.containsKey(key)) continue; String value = null == entry.getValue() ? "" : entry.getValue().toString().trim(); if ("".equals(value) && DEFAULT_ARGUMENT_VALUE_CHANGE.containsKey(key)) { value = DEFAULT_ARGUMENT_VALUE_CHANGE.get(key); } props.setProperty(key, value); modifiedProperties.put(key, value); } return modifiedProperties; } private static void _loadConf(String confFilename, Map<String, String> args) throws ConfigurationException { System.out.println(AppConst.IDENTATOR + "load application configuration - start"); Map<String, String> modifiedProperties = new TreeMap<String, String>(); try { props = new Properties(ResourcesUtils.loadPropertiesFile(confFilename)); // update the properties values using system properties and user arguments modifiedProperties.putAll(updateProperties(System.getProperties().entrySet())); if (null != args) modifiedProperties.putAll(updateProperties(args.entrySet())); if (modifiedProperties.size() > 0) { for (Entry<String, String> entry : modifiedProperties.entrySet()) { System.out.println(AppConst.IDENTATOR + AppConst.IDENTATOR + entry.getKey() + "=" + entry.getValue()); } } setReasonerVersion(props.getProperty(ConfTag.REASONER_VERSION)); String logLevelStr = props.getProperty(ConfTag.LOG_LEVEL); if (logLevelStr == null) { logLevelStr = props.getProperty(ConfTag.LOG_LEVEL, "INFO"); } Level l = Utilities.getLogLevel(logLevelStr); if (l != null) logLevel = l; System.out.println(AppConst.IDENTATOR + "load application configuration - end"); } catch (Exception e) { e.printStackTrace(); throw new ConfigurationException("exception throw while configurating application context", e); } } }