diff --git a/resources/WebContent/css/magic-bootstrap.css b/resources/WebContent/css/magic-bootstrap.css
old mode 100644
new mode 100755
index adc8bf4..ff1e2e8
--- a/resources/WebContent/css/magic-bootstrap.css
+++ b/resources/WebContent/css/magic-bootstrap.css
@@ -4296,7 +4296,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
display: inline-block;
}
.breadcrumb > li + li:before {
- content: "\00a0";
+ content: "/\00a0";
padding: 0 5px;
color: #cccccc;
}
diff --git a/resources/WebContent/page/Log.tmpl b/resources/WebContent/page/Log.tmpl
new file mode 100755
index 0000000..cd24e1f
--- /dev/null
+++ b/resources/WebContent/page/Log.tmpl
@@ -0,0 +1,13 @@
+
+
Log
+
+
+
+ | Timestamp |
+ Level |
+ Log |
+
+
+
+
+
diff --git a/src/wa/server/WAAbstractPage.java b/src/wa/server/WAAbstractPage.java
index ba10e40..3690dc0 100755
--- a/src/wa/server/WAAbstractPage.java
+++ b/src/wa/server/WAAbstractPage.java
@@ -48,7 +48,7 @@ import java.util.logging.Logger;
*/
public class WAAbstractPage implements HttpPage{
private static final Logger log = LogUtil.getLogger();
- private static final String TMPL_FILE = "WebContent/page/index.tmpl";
+ private static final String TMPL_FILE = "WebContent/page/Index.tmpl";
private List pages;
private Templator tmpl;
diff --git a/src/wa/server/WAConstants.java b/src/wa/server/WAConstants.java
index 772d76c..2e9d548 100755
--- a/src/wa/server/WAConstants.java
+++ b/src/wa/server/WAConstants.java
@@ -8,9 +8,9 @@ import java.io.File;
public class WAConstants {
- public static final String DB_FILE_NAME = "webadmin.db";
+ public static final String DB_FILE = "webadmin.db";
+ public static final String DB_DEFAULT_FILE = "webadmin_default.db";
public static final String DB_TABLE_PREFIX = "wa";
- public static DBConnection db;
public static final String WA_ROOT_PATH_LINUX = "/";
public static final String WA_ROOT_PATH_WINDOWS = "C:\\webadmin\\";
@@ -35,15 +35,6 @@ public class WAConstants {
else {
configPath = null;
}
-
- if(configPath != null){
- try {
- db = new DBConnection(DBConnection.DBMS.SQLite, configPath.getAbsolutePath() + DB_FILE_NAME);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
}
@@ -51,7 +42,4 @@ public class WAConstants {
return new File(configPath, name);
}
- public static DBConnection getDB(){
- return db;
- }
}
diff --git a/src/wa/server/WAContext.java b/src/wa/server/WAContext.java
index cf8bf1c..cda8b35 100755
--- a/src/wa/server/WAContext.java
+++ b/src/wa/server/WAContext.java
@@ -22,20 +22,36 @@
package wa.server;
+import com.sun.beans.editors.IntegerEditor;
import wa.server.page.struct.WAAlert;
import wa.server.page.struct.WANavigation;
+import zutil.db.DBConnection;
+import zutil.db.DBUpgradeHandler;
+import zutil.db.SQLResultHandler;
+import zutil.db.handler.SimpleSQLResult;
+import zutil.io.file.FileUtil;
+import zutil.log.LogUtil;
+import java.io.File;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* Created by Ziver on 2015-04-06.
*/
public class WAContext {
- private static WANavigation rootNav = WANavigation.createRootNav();
+ private static final Logger logger = LogUtil.getLogger();
+ private static WANavigation rootNav;
+ public static DBConnection db;
private ArrayList alerts;
+ // Navigation
private WANavigation.NavInstance navInstance;
private List breadcrumb;
@@ -43,7 +59,6 @@ public class WAContext {
public WAContext(Map request){
// Navigation
navInstance = rootNav.createNavInstance(request);
-
// Breadcrumb
breadcrumb = WANavigation.getBreadcrumb(request);
if(!breadcrumb.isEmpty())
@@ -63,7 +78,50 @@ public class WAContext {
+
+ protected static void initialize(){
+ try {
+ rootNav = WANavigation.createRootNav();
+
+
+ // Setup DB
+ File dbFile = WAConstants.getConfigFile(WAConstants.DB_FILE);
+ File defDbFile = WAConstants.getConfigFile(WAConstants.DB_DEFAULT_FILE);
+ db = new DBConnection(DBConnection.DBMS.SQLite, dbFile.getAbsolutePath());
+ DBConnection defaultDB = new DBConnection(DBConnection.DBMS.SQLite, defDbFile.getAbsolutePath());
+ int defaultDBVersion = Integer.parseInt(defaultDB.exec(
+ "SELECT value FROM "+WAConstants.DB_TABLE_PREFIX+"_config WHERE key=='db_version'",
+ new SimpleSQLResult()));
+ int dbVersion = Integer.parseInt(db.exec(
+ "SELECT value FROM "+WAConstants.DB_TABLE_PREFIX+"_config WHERE key=='db_version'",
+ new SimpleSQLResult()));
+ logger.info("DB version: "+ dbVersion);
+ if(defaultDBVersion > dbVersion ) {
+ logger.info("Starting DB upgrade...");
+ if (dbFile != null) {
+ File backupDB = FileUtil.getNextFile(dbFile);
+ logger.fine("Backing up DB to: " + backupDB);
+ FileUtil.copy(dbFile, backupDB);
+ }
+
+ logger.fine(String.format("Upgrading DB (from: v%s, to: v%s)...", dbVersion, defaultDBVersion));
+ DBUpgradeHandler handler = new DBUpgradeHandler(defaultDB);
+ handler.addIgnoredTable("sqlite_sequence"); //sqlite internal
+ handler.setTargetDB(db);
+ handler.upgrade();
+ }
+
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, null, e);
+ System.exit(1);
+ }
+ }
+
+ public static DBConnection getDB(){
+ return db;
+ }
public static WANavigation getRootNav(){
return rootNav;
}
+
}
diff --git a/src/wa/server/WebAdminServer.java b/src/wa/server/WebAdminServer.java
index 5ce913f..812091d 100755
--- a/src/wa/server/WebAdminServer.java
+++ b/src/wa/server/WebAdminServer.java
@@ -25,6 +25,7 @@ public class WebAdminServer {
public WebAdminServer(){
try {
+ WAContext.initialize();
pluginManager = new PluginManager();
HttpServer http = new HttpServer(80);
diff --git a/src/wa/server/page/LogPage.java b/src/wa/server/page/LogPage.java
index 3289432..9c86b12 100755
--- a/src/wa/server/page/LogPage.java
+++ b/src/wa/server/page/LogPage.java
@@ -22,11 +22,14 @@
package wa.server.page;
+import wa.server.WAContext;
import wa.server.plugin.WALog;
+import zutil.io.file.FileUtil;
import zutil.net.http.HttpHeader;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpPrintStream;
import zutil.parser.DataNode;
+import zutil.parser.Templator;
import zutil.parser.json.JSONWriter;
import zutil.struct.CircularBuffer;
@@ -39,7 +42,9 @@ import java.util.logging.LogRecord;
/**
* Created by Ziver on 2015-09-22.
*/
-public class LogPage extends Handler implements HttpPage {
+public class LogPage extends Handler implements HttpPage, WAPage {
+ private static final String TMPL_FILE = "WebContent/page/Log.tmpl";
+
private CircularBuffer logBuffer;
private WALog log;
@@ -64,6 +69,18 @@ public class LogPage extends Handler implements HttpPage {
}
+ @Override
+ public Templator htmlResponse(WAContext context, HttpHeader client_info, Map session, Map cookie, Map request) {
+ try {
+ return new Templator(FileUtil.find(TMPL_FILE));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+
@Override
public void respond(HttpPrintStream out,
HttpHeader client_info,
@@ -71,6 +88,15 @@ public class LogPage extends Handler implements HttpPage {
Map cookie,
Map request) throws IOException {
+ JSONWriter writer = new JSONWriter(out);
+ writer.write(jsonResponse());
+ writer.close();
+ }
+ @Override
+ public DataNode jsonResponse(WAContext context, HttpHeader client_info, Map session, Map cookie, Map request) {
+ return jsonResponse();
+ }
+ public DataNode jsonResponse() {
DataNode logNode = new DataNode(DataNode.DataType.List);
Iterator it = logBuffer.iterator();
for(int i=0; i<20 && it.hasNext(); ++i){
@@ -84,8 +110,6 @@ public class LogPage extends Handler implements HttpPage {
DataNode root = new DataNode(DataNode.DataType.Map);
root.add(logNode);
- JSONWriter writer = new JSONWriter(out);
- writer.write(root);
- writer.close();
+ return root;
}
}
diff --git a/src/wa/server/page/ServicePage.java b/src/wa/server/page/ServicePage.java
index 1ac9648..3652b7c 100755
--- a/src/wa/server/page/ServicePage.java
+++ b/src/wa/server/page/ServicePage.java
@@ -102,7 +102,7 @@ public class ServicePage implements WAPage {
statusPage.htmlResponse(context, client_info, session, cookie, request));
if(logPage != null)
tmpl.set("service_logs",
- statusPage.htmlResponse(context, client_info, session, cookie, request));
+ logPage.htmlResponse(context, client_info, session, cookie, request));
return tmpl;
}
else{ // root page
diff --git a/src/wa/server/page/WALogPage.java b/src/wa/server/page/WALogPage.java
deleted file mode 100755
index 2851fe9..0000000
--- a/src/wa/server/page/WALogPage.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2015 ezivkoc
- *
- * 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 wa.server.page;
-
-import zutil.net.http.HttpHeader;
-import zutil.net.http.HttpHeaderParser;
-import zutil.net.http.HttpPage;
-import zutil.net.http.HttpPrintStream;
-import zutil.parser.DataNode;
-import zutil.parser.json.JSONWriter;
-import zutil.struct.CircularBuffer;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.logging.Handler;
-import java.util.logging.LogRecord;
-
-/**
- * Created by Ziver on 2015-09-22.
- */
-public class WALogPage extends Handler implements HttpPage {
- private CircularBuffer logBuffer;
-
- @Override
- public void publish(LogRecord record) {
- if(super.isLoggable(record)){
- logBuffer.add(record);
- }
- }
-
-
- @Override
- public void flush() {}
- @Override
- public void close() throws SecurityException {
- throw new UnsupportedOperationException ();
- }
-
-
- @Override
- public void respond(HttpPrintStream out,
- HttpHeader client_info,
- Map session,
- Map cookie,
- Map request) throws IOException {
-
- DataNode logNode = new DataNode(DataNode.DataType.List);
- Iterator it = logBuffer.iterator();
- for(int i=0; i<20 && it.hasNext(); ++i){
- LogRecord record = it.next();
- DataNode node = new DataNode(DataNode.DataType.Map);
- node.set("timestamp", record.getMillis());
- node.set("source", record.getLoggerName());
- node.set("msg", record.getMessage());
- logNode.add(node);
- }
-
- DataNode root = new DataNode(DataNode.DataType.Map);
- root.add(logNode);
- JSONWriter writer = new JSONWriter(out);
- writer.write(root);
- writer.close();
- }
-}
diff --git a/src/wa/server/page/struct/WANavigation.java b/src/wa/server/page/struct/WANavigation.java
index e0eafa7..48fd7d6 100755
--- a/src/wa/server/page/struct/WANavigation.java
+++ b/src/wa/server/page/struct/WANavigation.java
@@ -66,6 +66,7 @@ public class WANavigation implements Iterable{
nav = new WANavigation(name);
nav.setParentNav(this);
subNav.add(nav);
+ sortSubNavs();
return nav;
}
/**
@@ -82,6 +83,8 @@ public class WANavigation implements Iterable{
Collections.sort(subNav, new Comparator() {
@Override
public int compare(WANavigation o1, WANavigation o2) {
+ if (o1.weight == o2.weight)
+ return o1.name.compareToIgnoreCase(o2.name);
return o1.weight - o2.weight;
}
});
@@ -147,22 +150,7 @@ public class WANavigation implements Iterable{
return instance;
}
- /**
- * @param request A map of all url parameters sent from client
- * @return a List of WANavigation objects depicting the navigation hierarchy for the
- * requested page from the client. First entry will be the root navigation object.
- */
- public static List getBreadcrumb(Map request) {
- LinkedList list = new LinkedList();
- if(request.containsKey(NAVIGATION_URL_KEY)){
- WANavigation current = navMap.get(Integer.parseInt(request.get(NAVIGATION_URL_KEY)));
- while(current != null){
- list.addFirst(current);
- current = current.parentNav;
- }
- }
- return list;
- }
+
public static WANavigation createRootNav(){
return new WANavigation(null);
@@ -174,6 +162,33 @@ public class WANavigation implements Iterable{
return null;
}
+ /**
+ * @return the specific WANavigation object requested by client
+ */
+ public static WANavigation getNavigation(Map request) {
+ if(request.containsKey(NAVIGATION_URL_KEY))
+ return navMap.get(Integer.parseInt(request.get(NAVIGATION_URL_KEY)));
+ return null;
+ }
+
+ /**
+ * @param request A map of all url parameters sent from client
+ * @return a List of WANavigation objects depicting the navigation hierarchy for the
+ * requested page from the client. First entry will be the root navigation object.
+ */
+ public static List getBreadcrumb(Map request) {
+ LinkedList list = new LinkedList();
+ WANavigation current = getNavigation(request);
+ if (current != null){
+ while(current != null){
+ list.addFirst(current);
+ current = current.parentNav;
+ }
+ }
+ return list;
+ }
+
+
public static class NavInstance{
diff --git a/src/wa/server/plugin/apache/ApacheConfigVirtualHost.java b/src/wa/server/plugin/apache/ApacheConfigVirtualHost.java
index ccd3567..d2c28bc 100755
--- a/src/wa/server/plugin/apache/ApacheConfigVirtualHost.java
+++ b/src/wa/server/plugin/apache/ApacheConfigVirtualHost.java
@@ -1,6 +1,7 @@
package wa.server.plugin.apache;
import wa.server.WAConstants;
+import wa.server.WAContext;
import wa.server.plugin.WAConfigEntry;
import wa.server.plugin.WAServiceConfig;
import wa.server.util.ConfigFileUtil;
@@ -13,6 +14,7 @@ import zutil.ui.Configurator;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -26,9 +28,8 @@ public class ApacheConfigVirtualHost implements WAServiceConfig{
private List vhosts = new ArrayList<>();
- public ApacheConfigVirtualHost() throws Exception {
- DBConnection db = WAConstants.getDB();
- vhosts = DBBean.load(db, ApacheVirtualHostEntry.class);
+ public ApacheConfigVirtualHost() throws SQLException {
+ vhosts = DBBean.load(WAContext.getDB(), ApacheVirtualHostEntry.class);
}
@Override
diff --git a/src/wa/server/plugin/apache/ApacheService.java b/src/wa/server/plugin/apache/ApacheService.java
index 64e8db5..222efb5 100755
--- a/src/wa/server/plugin/apache/ApacheService.java
+++ b/src/wa/server/plugin/apache/ApacheService.java
@@ -25,13 +25,15 @@ package wa.server.plugin.apache;
import wa.server.plugin.*;
import zutil.log.LogUtil;
+import java.sql.SQLException;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by Ziver on 2014-12-23.
*/
public class ApacheService implements WAService {
- private static Logger log = LogUtil.getLogger();
+ private static Logger logger = LogUtil.getLogger();
public static final String SERVICE_NAME = "Apache2";
private ApacheStatus status;
@@ -65,9 +67,13 @@ public class ApacheService implements WAService {
@Override
public WAServiceConfig[] getConfigurations() {
if(config == null)
- config = new WAServiceConfig[]{
- //new ApacheConfigVirtualHost()
- };
+ try {
+ config = new WAServiceConfig[]{
+ new ApacheConfigVirtualHost()
+ };
+ } catch (SQLException e) {
+ logger.log(Level.SEVERE, null, e);
+ }
return config;
}
}
diff --git a/webadmin.db b/webadmin.db
new file mode 100755
index 0000000..88bdde7
Binary files /dev/null and b/webadmin.db differ
diff --git a/webadmin_default.db b/webadmin_default.db
new file mode 100755
index 0000000..88bdde7
Binary files /dev/null and b/webadmin_default.db differ