Archived
0

Web interface

This commit is contained in:
2017-03-07 01:19:40 +03:00
parent 4b47b63171
commit 003f90160b
9 changed files with 365 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
rootProject.name = 'asys'
include 'core'
include 'commons'
include 'commons'
include 'webinterface'

37
webinterface/build.gradle Normal file
View File

@@ -0,0 +1,37 @@
group = 'asys'
version = '0.8-SNAPSHOT'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.dm.gradle:gradle-bundle-plugin:0.10.0"
}
}
apply plugin: 'org.dm.bundle'
configurations {
included
compile.extendsFrom included
}
jar {
dependsOn configurations.included
from { configurations.included.collect { it.isDirectory() ? it : zipTree(it).matching{exclude{it.path.contains('META-INF')} } } }
}
bundle {
instructions << [
'Bundle-Name': 'ASys Web interface',
'Bundle-Activator': 'asys.webinterface.Activator',
'Import-Package': '*'
]
exclude group: 'com.google.code.gson'
}
dependencies {
compile project(':core')
included group: 'com.google.code.gson', name: 'gson', version: '2.7'
}

View File

@@ -0,0 +1,23 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-12-05
*/
package asys.webinterface;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private WebServer webServer;
@Override
public void start(BundleContext context) throws Exception {
webServer = new WebServer(context);
webServer.start(8778);
}
@Override
public void stop(BundleContext context) throws Exception {
webServer.stop();
}
}

View File

@@ -0,0 +1,120 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-12-13
*/
package asys.webinterface;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
public class AjaxHandler implements HttpHandler {
private static final Charset defaultCharset = Charset.forName("UTF-8");
private BundleContext context;
private int selfId;
public AjaxHandler(BundleContext context) {
this.context = context;
selfId = (int) context.getBundle().getBundleId();
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
String outJson = "{}";
String jsonPath = httpExchange.getRequestURI().getPath();
if (jsonPath.equals("/ajax/bundles.json")) {
if (httpExchange.getRequestURI().getQuery() != null && !httpExchange.getRequestURI().getQuery().isEmpty()) {
Map<String, String> query = queryToMap(httpExchange.getRequestURI().getQuery());
if (query.containsKey("id")) {
Bundle bundle = context.getBundle(Integer.valueOf(query.get("id")));
if (bundle == null) {
sendResponse(httpExchange, outJson);
return;
}
if (query.containsKey("act") && query.get("act").equals("upd")) {
try {
bundle.update();
} catch (BundleException e) {
e.printStackTrace();
}
}
outJson = bundleInfo(bundle).toString();
}
} else {
outJson = bundleList().toString();
}
}
sendResponse(httpExchange, outJson);
}
private void sendResponse(HttpExchange httpExchange, String outJson) throws IOException {
httpExchange.getResponseHeaders().add("Context-Type", "application/json;charset=utf-8");
httpExchange.sendResponseHeaders(200, 0);
OutputStream responseBody = httpExchange.getResponseBody();
responseBody.write(outJson.getBytes(defaultCharset));
responseBody.close();
}
private JsonArray bundleList() {
JsonArray jsonArray = new JsonArray();
for (Bundle bundle : context.getBundle(0).getBundleContext().getBundles()) {
if (bundle.getBundleId() == 0 || bundle.getBundleId() == selfId) {
continue;
}
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", bundle.getBundleId());
jsonObject.addProperty("state", bundle.getState());
jsonObject.addProperty("name", bundle.getHeaders().get("Bundle-Name"));
jsonObject.addProperty("symname", bundle.getSymbolicName());
jsonObject.addProperty("lastModified", bundle.getHeaders().get("Bnd-LastModified"));
jsonObject.addProperty("version", bundle.getVersion().toString());
jsonArray.add(jsonObject);
}
return jsonArray;
}
private JsonObject bundleInfo(Bundle bundle) {
JsonObject jsonObject = new JsonObject();
if (bundle != null && bundle.getBundleId() != 0 && bundle.getBundleId() != selfId) {
jsonObject.addProperty("id", bundle.getBundleId());
jsonObject.addProperty("state", bundle.getState());
jsonObject.addProperty("name", bundle.getHeaders().get("Bundle-Name"));
jsonObject.addProperty("symname", bundle.getSymbolicName());
jsonObject.addProperty("lastModified", bundle.getHeaders().get("Bnd-LastModified"));
jsonObject.addProperty("version", bundle.getVersion().toString());
}
return jsonObject;
}
private Map<String, String> queryToMap(String query){
Map<String, String> result = new HashMap<>();
for (String param : query.split("&")) {
String pair[] = param.split("=");
if (pair.length>1) {
result.put(pair[0], pair[1]);
}else{
result.put(pair[0], "");
}
}
return result;
}
}

View File

@@ -0,0 +1,45 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-12-05
*/
package asys.webinterface;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import org.osgi.framework.BundleContext;
import java.io.*;
import java.nio.charset.Charset;
public class IndexHandler implements HttpHandler {
private static final Charset defaultCharset = Charset.forName("UTF-8");
private BundleContext context;
private String htmlTemplate;
public IndexHandler(BundleContext context) {
this.context = context;
try {
InputStream inputStream = getClass().getResourceAsStream("/index.html");
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
htmlTemplate = sb.toString();
} catch (Exception e) {
throw new RuntimeException("Error load htmlTemplate", e);
}
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
httpExchange.getResponseHeaders().add("Context-Type","text/html;charset=utf-8");
httpExchange.sendResponseHeaders(200, htmlTemplate.length());
OutputStream responseBody = httpExchange.getResponseBody();
responseBody.write(htmlTemplate.getBytes(defaultCharset));
responseBody.close();
}
}

View File

@@ -0,0 +1,41 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-12-12
*/
package asys.webinterface;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class StaticHandler implements HttpHandler {
@Override
public void handle(HttpExchange httpExchange) throws IOException {
String fileId = httpExchange.getRequestURI().getPath();
fileId = fileId.replace("../", "").replace("//", "/");
System.err.println(fileId);
InputStream inputStream = getClass().getResourceAsStream(fileId);
if (inputStream == null) {
String response = "Error 404 File not found.";
httpExchange.sendResponseHeaders(404, response.length());
OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(response.getBytes());
outputStream.flush();
outputStream.close();
} else {
httpExchange.sendResponseHeaders(200, 0);
OutputStream outputStream = httpExchange.getResponseBody();
final byte[] buffer = new byte[0x10000];
int len;
while((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 2016-12-05
*/
package asys.webinterface;
import com.sun.net.httpserver.HttpServer;
import org.osgi.framework.BundleContext;
import java.io.IOException;
import java.net.InetSocketAddress;
public class WebServer {
private HttpServer server;
private BundleContext context;
public WebServer(BundleContext context) {
this.context = context;
}
public void start(int port) throws IOException {
server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/", new IndexHandler(context));
server.createContext("/static", new StaticHandler());
server.createContext("/ajax", new AjaxHandler(context));
server.start();
}
public void stop() {
server.stop(0);
}
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="ru" ng-app="asysApp">
<head>
<meta charset="utf-8">
<title>ASys: Web interface</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<script src="/static/app.js"></script>
</head>
<body>
<h1>ASys: Web interface</h1>
<hr>
<bundle-list></bundle-list>
</body>
</html>

View File

@@ -0,0 +1,51 @@
var app = angular.module('asysApp', []);
// filtres
app.filter('stateFormat', function() {
return function(state) {
if (state == 1) {return 'UNINSTALLED';}
else if (state == 2) {return 'INSTALLED';}
else if (state == 4) {return 'RESOLVED';}
else if (state == 8) {return 'STARTING';}
else if (state == 16) {return 'STOPPING';}
else if (state == 32) {return 'ACTIVE';}
else {return 'UNKNOW('+state+')'}
}
});
/* --- [bundle-list] --- */
app.component('bundleList', {
template:
'<table width="100%">' +
'<thead><tr>' +
'<th>ID</th><th>Name</th><th>State</th><th>Version</th><th>Last modified</th><th>CTRL</th>' +
'</tr></thead>' +
'<tbody>' +
'<tr ng-repeat="bundle in $ctrl.bundles">' +
'<td>{{bundle.id}}</td>' +
'<td>{{bundle.name}}</td>' +
'<td>{{bundle.state | stateFormat}}</td>' +
'<td>{{bundle.version}}</td>' +
'<td>{{bundle.lastModified | date:"dd/MM/yyyy HH:mm"}}</td>' +
'<td><button ng-click="$ctrl.bndUpd(bundle.id)">update</button></td>' +
'</tr>' +
'</tbody>' +
'</table>',
controller: function BundleListController($http) {
var self = this;
$http.get('/ajax/bundles.json').then(function(response) {
self.bundles = response.data;
});
this.bndUpd = function(bundleId){
$http.get('/ajax/bundles.json?id='+bundleId+'&act=upd').then(function(response){
for(var i=0; i < self.bundles.length; i++) {
if (self.bundles[i].id == bundleId) {
self.bundles[i] = response.data;
break;
}
}
});
};
}
});