diff --git a/Hal.iml b/Hal.iml
index d611eaaf..2a2619c3 100755
--- a/Hal.iml
+++ b/Hal.iml
@@ -26,23 +26,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -73,5 +57,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build.xml b/build.xml
index 4d2982d3..e059d4e4 100755
--- a/build.xml
+++ b/build.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/hal-default.db b/hal-default.db
index cbdd384b..4aee4afc 100755
Binary files a/hal-default.db and b/hal-default.db differ
diff --git a/resource/web/plugin_config.tmpl b/resource/web/plugin_config.tmpl
index a0d11cf1..c8179ac8 100644
--- a/resource/web/plugin_config.tmpl
+++ b/resource/web/plugin_config.tmpl
@@ -7,16 +7,37 @@
- | Name |
+ Name |
Version |
+ Actions |
{{#plugins}}
| {{.getName()}} |
{{.getVersion()}} |
+
+
+ |
{{/plugins}}
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/src/se/hal/HalContext.java b/src/se/hal/HalContext.java
index 717d70e0..0e65ef11 100755
--- a/src/se/hal/HalContext.java
+++ b/src/se/hal/HalContext.java
@@ -76,8 +76,9 @@ public class HalContext {
Integer.parseInt(dbConf.getProperty(PROPERTY_DB_VERSION)) :
-1);
logger.info("DB version: "+ dbVersion);
+
if(defaultDBVersion > dbVersion ) {
- logger.info("Starting DB upgrade...");
+ logger.info("Starting DB upgrade from v" + dbVersion + " to v" + defaultDBVersion + "...");
if(dbFile != null){
File backupDB = FileUtil.getNextFile(dbFile);
logger.fine("Backing up DB to: "+ backupDB);
@@ -91,6 +92,7 @@ public class HalContext {
handler.setTargetDB(db);
logger.fine("Performing pre-upgrade activities");
+
//read upgrade path preferences from the reference database
referenceDB.exec("SELECT * FROM db_version_history"
+ " WHERE db_version <= " + defaultDBVersion
@@ -111,6 +113,7 @@ public class HalContext {
handler.upgrade();
logger.fine("Performing post-upgrade activities");
+
//read upgrade path preferences from the reference database
referenceDB.exec("SELECT * FROM db_version_history"
+ " WHERE db_version <= " + defaultDBVersion
@@ -225,7 +228,6 @@ public class HalContext {
/**
* For testing purposes.
- * @param db
*/
public static void setDB(DBConnection db){
HalContext.db = db;
diff --git a/src/se/hal/HalServer.java b/src/se/hal/HalServer.java
index f35065aa..9e2b58e9 100755
--- a/src/se/hal/HalServer.java
+++ b/src/se/hal/HalServer.java
@@ -6,6 +6,7 @@ import se.hal.intf.HalWebPage;
import se.hal.intf.HalJsonPage;
import se.hal.page.*;
import se.hal.struct.Event;
+import se.hal.struct.PluginConfig;
import se.hal.struct.Sensor;
import se.hal.struct.TriggerFlow;
import zutil.db.DBConnection;
@@ -14,16 +15,20 @@ import zutil.log.LogUtil;
import zutil.net.http.HttpServer;
import zutil.net.http.page.HttpFilePage;
import zutil.net.http.page.HttpRedirectPage;
+import zutil.plugin.PluginData;
import zutil.plugin.PluginManager;
+import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.logging.Logger;
/**
* Main class for Hal
*/
public class HalServer {
+ private static final Logger logger = LogUtil.getLogger();
private static ScheduledExecutorService daemonExecutor;
private static List daemons = new ArrayList<>();
@@ -42,15 +47,40 @@ public class HalServer {
// init DB and other configurations
HalContext.initialize();
DBConnection db = HalContext.getDB();
- pluginManager = new PluginManager("./");
- // init Managers
+ // ------------------------------------
+ // Init Plugins
+ // ------------------------------------
+
+ logger.info("Looking for plugins.");
+ pluginManager = new PluginManager();
+
+ // Disable plugins based on settings
+ for (PluginData plugin : getPlugins()) {
+ PluginConfig pluginConfig = PluginConfig.getPluginConfig(db, plugin.getName());
+
+ if (pluginConfig != null && !pluginConfig.isEnabled()){
+ logger.info("Disabling plugin '" + plugin.getName() + "'.");
+ plugin.setEnabled(false);
+ }
+ }
+
+ // ------------------------------------
+ // Init Managers
+ // ------------------------------------
+
+ logger.info("Initializing managers.");
+
HalAlertManager.initialize();
ControllerManager.initialize(pluginManager);
TriggerManager.initialize(pluginManager);
-
+ // ------------------------------------
// Import sensors,events and triggers
+ // ------------------------------------
+
+ logger.info("Initializing Sensors and Events.");
+
for(Sensor sensor : Sensor.getLocalSensors(db)){
ControllerManager.getInstance().register(sensor);
}
@@ -63,14 +93,23 @@ public class HalServer {
}
+ // ------------------------------------
// Init daemons
+ // ------------------------------------
+
+ logger.info("Initializing daemons.");
+
// We set only one thread for easier troubleshooting
daemonExecutor = Executors.newScheduledThreadPool(1);
- for (Iterator it=pluginManager.getObjectIterator(HalDaemon.class); it.hasNext(); )
+ for (Iterator it = pluginManager.getSingletonIterator(HalDaemon.class); it.hasNext(); )
registerDaemon(it.next());
-
+ // ------------------------------------
// Init http server
+ // ------------------------------------
+
+ logger.info("Initializing HTTP Server.");
+
HalWebPage.getRootNav().createSubNav("Sensors");
HalWebPage.getRootNav().createSubNav("Events").setWeight(100);
HalWebPage.getRootNav().createSubNav("Settings").setWeight(200);
@@ -79,22 +118,38 @@ public class HalServer {
http.setDefaultPage(new HttpFilePage(FileUtil.find("resource/web/")));
http.setPage("/", new HttpRedirectPage("/map"));
http.setPage(HalAlertManager.getInstance().getUrl(), HalAlertManager.getInstance());
- for (Iterator it = pluginManager.getObjectIterator(HalJsonPage.class); it.hasNext(); )
+ for (Iterator it = pluginManager.getSingletonIterator(HalJsonPage.class); it.hasNext(); )
registerPage(it.next());
- for (Iterator it = pluginManager.getObjectIterator(HalWebPage.class); it.hasNext(); )
+ for (Iterator it = pluginManager.getSingletonIterator(HalWebPage.class); it.hasNext(); )
registerPage(it.next());
http.start();
}
- public static PluginManager getPluginManager() {
- return pluginManager;
+ public static void setPluginEnabled(String name, boolean enabled) throws SQLException {
+ DBConnection db = HalContext.getDB();
+ PluginConfig pluginConfig = PluginConfig.getPluginConfig(db, name);
+
+ if (pluginConfig == null)
+ pluginConfig = new PluginConfig(name);
+
+ logger.info("Plugin '" + name + "' has been " + (enabled ? "enabled" : "disabled") + ", change will take affect after restart.");
+ pluginManager.getPluginData(name).setEnabled(enabled);
+
+ pluginConfig.setEnabled(enabled);
+ pluginConfig.save(db);
}
+ public static List getPlugins() {
+ return pluginManager.toArray();
+ }
+
+
public static void registerDaemon(HalDaemon daemon){
daemons.add(daemon);
daemon.initiate(daemonExecutor);
}
+
public static void registerPage(HalWebPage page){
pages.add(page);
http.setPage(page.getId(), page);
diff --git a/src/se/hal/page/PluginConfigWebPage.java b/src/se/hal/page/PluginConfigWebPage.java
index 8cc01e10..bbc58b1d 100644
--- a/src/se/hal/page/PluginConfigWebPage.java
+++ b/src/se/hal/page/PluginConfigWebPage.java
@@ -3,6 +3,11 @@ package se.hal.page;
import se.hal.HalContext;
import se.hal.HalServer;
import se.hal.intf.HalWebPage;
+import se.hal.page.HalAlertManager.AlertLevel;
+import se.hal.page.HalAlertManager.AlertTTL;
+import se.hal.page.HalAlertManager.HalAlert;
+import se.hal.struct.devicedata.SwitchEventData;
+import zutil.ObjectUtil;
import zutil.db.DBConnection;
import zutil.io.file.FileUtil;
import zutil.parser.Templator;
@@ -27,12 +32,17 @@ public class PluginConfigWebPage extends HalWebPage {
Map request)
throws Exception{
- DBConnection db = HalContext.getDB();
+ if (request.containsKey("action")) {
+ String name = request.get("action_id");
+ HalServer.setPluginEnabled(name,
+ (request.containsKey("enabled") && "on".equals(request.get("enabled"))));
- PluginManager pluginManager = HalServer.getPluginManager();
+ HalAlertManager.getInstance().addAlert(new HalAlert(
+ AlertLevel.SUCCESS, "Successfully updated plugin " + name + ", change will take affect after restart.", AlertTTL.ONE_VIEW));
+ }
Templator tmpl = new Templator(FileUtil.find(TEMPLATE));
- tmpl.set("plugins", pluginManager.toArray());
+ tmpl.set("plugins", HalServer.getPlugins());
return tmpl;
}
diff --git a/src/se/hal/struct/PluginConfig.java b/src/se/hal/struct/PluginConfig.java
new file mode 100644
index 00000000..a9ea97c5
--- /dev/null
+++ b/src/se/hal/struct/PluginConfig.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Ziver Koc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package se.hal.struct;
+
+import zutil.db.DBConnection;
+import zutil.db.bean.DBBean;
+import zutil.db.bean.DBBeanSQLResultHandler;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+
+@DBBean.DBTable(value="plugin")
+public class PluginConfig extends DBBean {
+ private String name;
+ private boolean enabled;
+
+
+ /**
+ * @return a PluginConfig bean for the specific plugin name.
+ */
+ public static PluginConfig getPluginConfig(DBConnection db, String name) throws SQLException {
+ PreparedStatement stmt = db.getPreparedStatement( "SELECT plugin.* FROM plugin WHERE name == ?" );
+ stmt.setString(1, name);
+ return DBConnection.exec(stmt, DBBeanSQLResultHandler.create(PluginConfig.class, db) );
+ }
+
+
+ public PluginConfig() {}
+ public PluginConfig(String name) {
+ this.name = name;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+}