Fixed upgrade and Config object structure
This commit is contained in:
parent
b995063b43
commit
6601f75f49
12 changed files with 137 additions and 88 deletions
|
|
@ -57,14 +57,14 @@
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title" id="configureModalLabel">Configure</h4>
|
<h4 class="modal-title" id="configureModalLabel">Configure</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<form class="form-horizontal">
|
||||||
<form class="form-horizontal">
|
<div class="modal-body">
|
||||||
{{#params}}
|
{{#params}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{.getName()}}" class="control-label col-xs-2">{{.getNiceName()}}</label>
|
<label for="{{.getName()}}" class="control-label col-xs-2">{{.getNiceName()}}</label>
|
||||||
<div class="col-xs-10">
|
<div class="col-xs-10">
|
||||||
{{#.isTypeString()}}
|
{{#.isTypeString()}}
|
||||||
<input type="text" class="form-control" id="{{.getName()}}">
|
<input type="text" class="form-control" id="{{.getName()}}" placeholder="{{.getNiceName()}}">
|
||||||
{{/.isTypeString()}}
|
{{/.isTypeString()}}
|
||||||
{{#.isTypeInt()}}
|
{{#.isTypeInt()}}
|
||||||
<input type="number" class="form-control" id="{{.getName()}}">
|
<input type="number" class="form-control" id="{{.getName()}}">
|
||||||
|
|
@ -75,12 +75,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/params}}
|
{{/params}}
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
<div class="modal-footer">
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button type="submit" class="btn btn-success">Save</button>
|
||||||
<button type="submit" class="btn btn-success">Save</button>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -108,7 +108,9 @@
|
||||||
</a>
|
</a>
|
||||||
<ul id="{{.getName()}}_collapse" class="side-sub-menu collapse nav nav-pills nav-stacked ">
|
<ul id="{{.getName()}}_collapse" class="side-sub-menu collapse nav nav-pills nav-stacked ">
|
||||||
{{#.getSubNavs()}}
|
{{#.getSubNavs()}}
|
||||||
<li><a href="{{.getURL()}}">{{.getName()}}</a></li>
|
<li class="{{#.isActive()}}active{{/.isActive()}}">
|
||||||
|
<a href="{{.getURL()}}">{{.getName()}}</a>
|
||||||
|
</li>
|
||||||
{{/.getSubNavs()}}
|
{{/.getSubNavs()}}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ import zutil.ui.Navigation;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -47,6 +49,8 @@ import java.util.logging.Logger;
|
||||||
* Created by Ziver on 2015-04-06.
|
* Created by Ziver on 2015-04-06.
|
||||||
*/
|
*/
|
||||||
public class WAContext {
|
public class WAContext {
|
||||||
|
public static final String CONFIG_DB_VERSION = "db_version";
|
||||||
|
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
private static Navigation rootNav;
|
private static Navigation rootNav;
|
||||||
private static DBConnection db;
|
private static DBConnection db;
|
||||||
|
|
@ -93,12 +97,8 @@ public class WAContext {
|
||||||
throw new NoSuchFileException("Deafult DB missing: "+defDbFile.getAbsolutePath());
|
throw new NoSuchFileException("Deafult DB missing: "+defDbFile.getAbsolutePath());
|
||||||
db = new DBConnection(DBConnection.DBMS.SQLite, dbFile.getAbsolutePath());
|
db = new DBConnection(DBConnection.DBMS.SQLite, dbFile.getAbsolutePath());
|
||||||
DBConnection defaultDB = new DBConnection(DBConnection.DBMS.SQLite, defDbFile.getAbsolutePath());
|
DBConnection defaultDB = new DBConnection(DBConnection.DBMS.SQLite, defDbFile.getAbsolutePath());
|
||||||
int defaultDBVersion = Integer.parseInt(defaultDB.exec(
|
int defaultDBVersion = Integer.parseInt(getConfig(defaultDB, CONFIG_DB_VERSION));
|
||||||
"SELECT value FROM "+WAConstants.DB_TABLE_PREFIX+"_config WHERE key=='db_version'",
|
int dbVersion = Integer.parseInt(getConfig(db, CONFIG_DB_VERSION));
|
||||||
new SimpleSQLResult<String>()));
|
|
||||||
int dbVersion = Integer.parseInt(db.exec(
|
|
||||||
"SELECT value FROM "+WAConstants.DB_TABLE_PREFIX+"_config WHERE key=='db_version'",
|
|
||||||
new SimpleSQLResult<String>()));
|
|
||||||
logger.info("DB version: "+ dbVersion);
|
logger.info("DB version: "+ dbVersion);
|
||||||
if(defaultDBVersion > dbVersion ) {
|
if(defaultDBVersion > dbVersion ) {
|
||||||
logger.info("Starting DB upgrade...");
|
logger.info("Starting DB upgrade...");
|
||||||
|
|
@ -113,6 +113,7 @@ public class WAContext {
|
||||||
handler.addIgnoredTable("sqlite_sequence"); //sqlite internal
|
handler.addIgnoredTable("sqlite_sequence"); //sqlite internal
|
||||||
handler.setTargetDB(db);
|
handler.setTargetDB(db);
|
||||||
handler.upgrade();
|
handler.upgrade();
|
||||||
|
setConfig(CONFIG_DB_VERSION, ""+defaultDBVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup fields
|
// Setup fields
|
||||||
|
|
@ -147,4 +148,18 @@ public class WAContext {
|
||||||
public static PluginManager getPluginManager() {
|
public static PluginManager getPluginManager() {
|
||||||
return pluginManager;
|
return pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String getConfig(DBConnection db, String key) throws SQLException {
|
||||||
|
PreparedStatement stmt = db.getPreparedStatement("SELECT value FROM "+WAConstants.DB_TABLE_PREFIX+"_config WHERE key==?");
|
||||||
|
stmt.setObject(1, key);
|
||||||
|
return db.exec(stmt, new SimpleSQLResult<String>());
|
||||||
|
}
|
||||||
|
public static void setConfig(String key, String value) throws SQLException {
|
||||||
|
PreparedStatement stmt = db.getPreparedStatement("REPLACE INTO wa_config (key, value) VALUES (?, ?)");
|
||||||
|
stmt.setObject(1, key);
|
||||||
|
stmt.setObject(2, value);
|
||||||
|
DBConnection.exec(stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
package wa.server.page;
|
package wa.server.page;
|
||||||
|
|
||||||
import wa.server.WAContext;
|
import wa.server.WAContext;
|
||||||
import wa.server.plugin.WAConfiguration;
|
import wa.server.plugin.WAConfigObject;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
|
@ -49,15 +49,15 @@ public class ConfigPage extends WAPage {
|
||||||
private static final String TEMPLATE = "WebContent/page/ConfigPage.tmpl";
|
private static final String TEMPLATE = "WebContent/page/ConfigPage.tmpl";
|
||||||
|
|
||||||
|
|
||||||
private Class<? extends WAConfiguration> configClass;
|
private Class<? extends WAConfigObject> configClass;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
public ConfigPage(Class<? extends WAConfiguration> configClass) {
|
public ConfigPage(Class<? extends WAConfigObject> configClass) {
|
||||||
super(getPageName(configClass));
|
super(getPageName(configClass));
|
||||||
this.configClass = configClass;
|
this.configClass = configClass;
|
||||||
|
|
||||||
WAConfiguration.WAConfig params = configClass.getAnnotation(WAConfiguration.WAConfig.class);
|
WAConfigObject.WAConfig params = configClass.getAnnotation(WAConfigObject.WAConfig.class);
|
||||||
WAContext.getRootNav()
|
WAContext.getRootNav()
|
||||||
.createSubNav(WAServicePage.NAVIGATION_NAME)
|
.createSubNav(WAServicePage.NAVIGATION_NAME)
|
||||||
.createSubNav(params.serviceName())
|
.createSubNav(params.serviceName())
|
||||||
|
|
@ -65,8 +65,8 @@ public class ConfigPage extends WAPage {
|
||||||
this.name = params.name();
|
this.name = params.name();
|
||||||
|
|
||||||
}
|
}
|
||||||
private static String getPageName(Class<? extends WAConfiguration> configClass){
|
private static String getPageName(Class<? extends WAConfigObject> configClass){
|
||||||
WAConfiguration.WAConfig params = configClass.getAnnotation(WAConfiguration.WAConfig.class);
|
WAConfigObject.WAConfig params = configClass.getAnnotation(WAConfigObject.WAConfig.class);
|
||||||
return WAServicePage.PAGE_NAME +"/"+ params.servicePage() +"/"+ params.pageName();
|
return WAServicePage.PAGE_NAME +"/"+ params.servicePage() +"/"+ params.pageName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,29 +80,29 @@ public class ConfigPage extends WAPage {
|
||||||
Map<String, String> request) throws Exception {
|
Map<String, String> request) throws Exception {
|
||||||
try {
|
try {
|
||||||
DBConnection db = WAContext.getDB();
|
DBConnection db = WAContext.getDB();
|
||||||
List<WAConfiguration> objList = getAllConfigs();
|
List<WAConfigObject> objList = WAConfigObject.getAllConfigObjs(db, configClass);
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
if (request.containsKey("action")) {
|
if (request.containsKey("action")) {
|
||||||
int id = -1;
|
int id = -1;
|
||||||
if (request.containsKey("pageName"))
|
if (request.containsKey("pageName"))
|
||||||
id = Integer.parseInt(request.get("pageName"));
|
id = Integer.parseInt(request.get("pageName"));
|
||||||
WAConfiguration target = getConfig(id);
|
WAConfigObject target = WAConfigObject.getConfig(db, configClass, id);
|
||||||
switch (request.get("action")) {
|
switch (request.get("action")) {
|
||||||
case "create":
|
case "create":
|
||||||
target = newConfig();
|
target = configClass.newInstance();
|
||||||
case "modify":
|
case "modify":
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
new Configurator<WAConfiguration>(target)
|
new Configurator<WAConfigObject>(target)
|
||||||
.setValues(request).applyConfiguration();
|
.setValues(request).applyConfiguration();
|
||||||
target.saveConfiguration();
|
target.saveConfiguration();
|
||||||
saveConfig(target);
|
target.save(db);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
target.deleteConfiguration();
|
target.deleteConfiguration();
|
||||||
deleteConfig(id);
|
target.delete(db);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -121,27 +121,11 @@ public class ConfigPage extends WAPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static WAConfiguration newConfig(){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private static WAConfiguration getConfig(int id){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private static List<WAConfiguration> getAllConfigs(){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private static WAConfiguration saveConfig(WAConfiguration target){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
private static WAConfiguration deleteConfig(int id){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
for (Iterator<Class<? extends WAConfiguration>> it = WAContext.getPluginManager().getClassIterator(WAConfiguration.class); it.hasNext(); ){
|
for (Iterator<Class<? extends WAConfigObject>> it = WAContext.getPluginManager().getClassIterator(WAConfigObject.class); it.hasNext(); ){
|
||||||
Class<? extends WAConfiguration> clazz = it.next();
|
Class<? extends WAConfigObject> clazz = it.next();
|
||||||
WAContext.registerWaPage(new ConfigPage(clazz));
|
WAContext.registerWaPage(new ConfigPage(clazz));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
82
src/wa/server/plugin/WAConfigObject.java
Executable file
82
src/wa/server/plugin/WAConfigObject.java
Executable file
|
|
@ -0,0 +1,82 @@
|
||||||
|
package wa.server.plugin;
|
||||||
|
|
||||||
|
|
||||||
|
import zutil.db.DBConnection;
|
||||||
|
import zutil.db.bean.DBBean;
|
||||||
|
import zutil.db.bean.DBBeanSQLResultHandler;
|
||||||
|
import zutil.db.handler.SimpleSQLResult;
|
||||||
|
import zutil.parser.json.JSONParser;
|
||||||
|
import zutil.parser.json.JSONWriter;
|
||||||
|
import zutil.ui.Configurator;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Ziver on 2016-07-27.
|
||||||
|
*/
|
||||||
|
@DBBean.DBTable(WAConfigObject.DB_TABLE)
|
||||||
|
public abstract class WAConfigObject extends DBBean{
|
||||||
|
protected static final String DB_TABLE = "wa_config_obj";
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface WAConfig{
|
||||||
|
String pageName();
|
||||||
|
String name();
|
||||||
|
String servicePage(); // TODO: this is horrible design!
|
||||||
|
String serviceName(); // TODO: this is horrible design!
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String className;
|
||||||
|
private String objConfig;
|
||||||
|
|
||||||
|
|
||||||
|
public WAConfigObject(){
|
||||||
|
className = this.getClass().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static WAConfigObject getConfig(DBConnection db, Class<? extends WAConfigObject> clazz, int id) throws SQLException, ClassNotFoundException {
|
||||||
|
PreparedStatement stmt = db.getPreparedStatement( "SELECT * FROM "+DB_TABLE+" WHERE id == ?" );
|
||||||
|
stmt.setInt(1, id);
|
||||||
|
WAConfigObject obj = DBConnection.exec(stmt, DBBeanSQLResultHandler.create(clazz, db) );
|
||||||
|
obj.configureObj();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
public static List<WAConfigObject> getAllConfigObjs(DBConnection db, Class<? extends WAConfigObject> clazz) throws SQLException {
|
||||||
|
List<WAConfigObject> list =
|
||||||
|
(List<WAConfigObject>) db.exec("SELECT * FROM "+DB_TABLE, DBBeanSQLResultHandler.createList(clazz, db) );
|
||||||
|
for (WAConfigObject obj : list)
|
||||||
|
obj.configureObj();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void configureObj(){
|
||||||
|
new Configurator(this).setValues(JSONParser.read(objConfig)).applyConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(DBConnection db) throws SQLException {
|
||||||
|
objConfig = JSONWriter.toString(
|
||||||
|
new Configurator(this).getValuesAsNode());
|
||||||
|
super.save(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure or reconfigure service with current configuration data
|
||||||
|
*/
|
||||||
|
public abstract void saveConfiguration() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the configuration
|
||||||
|
*/
|
||||||
|
public abstract void deleteConfiguration() throws Exception;
|
||||||
|
}
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
package wa.server.plugin;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Ziver on 2016-07-27.
|
|
||||||
*/
|
|
||||||
public abstract class WAConfiguration{
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public @interface WAConfig{
|
|
||||||
String pageName();
|
|
||||||
String name();
|
|
||||||
String servicePage(); // TODO: this is horrible design!
|
|
||||||
String serviceName(); // TODO: this is horrible design!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure or reconfigure service with current configuration data
|
|
||||||
*/
|
|
||||||
public abstract void saveConfiguration() throws Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the configuration
|
|
||||||
*/
|
|
||||||
public abstract void deleteConfiguration() throws Exception;
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
package wa.server.plugin.apache;
|
package wa.server.plugin.apache;
|
||||||
|
|
||||||
import wa.server.WAConstants;
|
import wa.server.WAConstants;
|
||||||
import wa.server.plugin.WAConfiguration;
|
import wa.server.plugin.WAConfigObject;
|
||||||
import zutil.db.bean.DBBean.DBTable;
|
|
||||||
import zutil.ui.Configurator;
|
import zutil.ui.Configurator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
|
||||||
public abstract class ApacheAbstractConfig extends WAConfiguration {
|
public abstract class ApacheAbstractConfig extends WAConfigObject {
|
||||||
private static final String CONFIG_NAME = "vhost";
|
private static final String CONFIG_NAME = "vhost";
|
||||||
private static final String NAVIGATION_NAME = "Apache Virtual Host";
|
private static final String NAVIGATION_NAME = "Apache Virtual Host";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package wa.server.plugin.apache;
|
package wa.server.plugin.apache;
|
||||||
|
|
||||||
import wa.server.plugin.WAConfiguration;
|
import wa.server.plugin.WAConfigObject;
|
||||||
import zutil.ui.Configurator;
|
import zutil.ui.Configurator;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
|
||||||
@WAConfiguration.WAConfig(servicePage=ApacheService.SERVICE_NAME, serviceName=ApacheService.NAVIGATION_NAME, pageName ="proxy", name="Proxy")
|
@WAConfigObject.WAConfig(servicePage=ApacheService.SERVICE_NAME, serviceName=ApacheService.NAVIGATION_NAME, pageName ="proxy", name="Proxy")
|
||||||
public class ApacheConfigProxy extends ApacheAbstractConfig {
|
public class ApacheConfigProxy extends ApacheAbstractConfig {
|
||||||
|
|
||||||
@Configurator.Configurable("Proxy Target")
|
@Configurator.Configurable("Proxy Target")
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package wa.server.plugin.apache;
|
package wa.server.plugin.apache;
|
||||||
|
|
||||||
import wa.server.plugin.WAConfiguration;
|
import wa.server.plugin.WAConfigObject;
|
||||||
import zutil.ui.Configurator;
|
import zutil.ui.Configurator;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
|
||||||
@WAConfiguration.WAConfig(servicePage=ApacheService.SERVICE_NAME, serviceName=ApacheService.NAVIGATION_NAME, pageName ="vhost", name="VirtualHost")
|
@WAConfigObject.WAConfig(servicePage=ApacheService.SERVICE_NAME, serviceName=ApacheService.NAVIGATION_NAME, pageName ="vhost", name="VirtualHost")
|
||||||
public class ApacheConfigVirtualHost extends ApacheAbstractConfig {
|
public class ApacheConfigVirtualHost extends ApacheAbstractConfig {
|
||||||
|
|
||||||
@Configurator.Configurable("Document Root")
|
@Configurator.Configurable("Document Root")
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"interfaces": [
|
"interfaces": [
|
||||||
{"wa.server.page.WAPage": "wa.server.plugin.apache.ApacheService"},
|
{"wa.server.page.WAPage": "wa.server.plugin.apache.ApacheService"},
|
||||||
{"wa.server.plugin.WAServiceStatus": "wa.server.plugin.apache.ApacheStatus"},
|
{"wa.server.plugin.WAServiceStatus": "wa.server.plugin.apache.ApacheStatus"},
|
||||||
{"wa.server.plugin.WAConfiguration": "wa.server.plugin.apache.ApacheConfigProxy"},
|
{"wa.server.plugin.WAConfigObject": "wa.server.plugin.apache.ApacheConfigProxy"},
|
||||||
{"wa.server.plugin.WAConfiguration": "wa.server.plugin.apache.ApacheConfigVirtualHost"}
|
{"wa.server.plugin.WAConfigObject": "wa.server.plugin.apache.ApacheConfigVirtualHost"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
BIN
webadmin.db
BIN
webadmin.db
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue