Skip to content

Commit

Permalink
Merge pull request #617 from peuter/openhab
Browse files Browse the repository at this point in the history
improve Openhab plugin + Notifications
  • Loading branch information
ChristianMayer committed Sep 17, 2017
2 parents 8dc9b70 + f85667e commit 778f8bd
Show file tree
Hide file tree
Showing 42 changed files with 2,496 additions and 407 deletions.
62 changes: 53 additions & 9 deletions client/source/class/cv/io/Client.js
Expand Up @@ -196,6 +196,14 @@ qx.Class.define('cv.io.Client', {
*/
currentTransport: {
init: null
},

/**
* The server we are currently speaking to (read from the login response)
*/
server: {
check: "String",
nullable: true
}
},

Expand Down Expand Up @@ -247,12 +255,25 @@ qx.Class.define('cv.io.Client', {
if (backend.baseURL && backend.baseURL.substr(-1) !== "/") {
backend.baseURL += "/";
}
var currentTransport = this.getCurrentTransport();
switch(backend.transport) {
case "long-polling":
this.setCurrentTransport(new cv.io.transport.LongPolling(this));
if (!(currentTransport instanceof cv.io.transport.LongPolling)) {
// replace old transport
if (currentTransport) {
currentTransport.dispose();
}
this.setCurrentTransport(new cv.io.transport.LongPolling(this));
}
break;
case "sse":
this.setCurrentTransport(new cv.io.transport.Sse(this));
if (!(currentTransport instanceof cv.io.transport.Sse)) {
// replace old transport
if (currentTransport) {
currentTransport.dispose();
}
this.setCurrentTransport(new cv.io.transport.Sse(this));
}
break;
}
if (this.backend.name === "openHAB") {
Expand Down Expand Up @@ -364,14 +385,16 @@ qx.Class.define('cv.io.Client', {
* Get the json response from the parameter received from the used XHR transport
*/
getResponse: qx.core.Environment.select("cv.xhr", {
"jquery": function(data) {
"jquery": function(args) {
var data = args[0];
if (data && $.type(data) === "string") {
data = cv.io.parser.Json.parse(data);
}
return data;
},

"qx": function(ev) {
"qx": function(args) {
var ev = args[0];
if (!ev) { return null; }
var json = ev.getTarget().getResponse();
if (!json) { return null; }
Expand All @@ -382,6 +405,18 @@ qx.Class.define('cv.io.Client', {
}
}),

getResponseHeader: qx.core.Environment.select("cv.xhr", {
"jquery": function (args, name) {
return args[2].getResponseHeader(name);
},
"qx": function (args, name) {
if (!args[0]) {
return null;
}
return args[0].getTarget().getResponseHeader(name);
}
}),

getQueryString: function(data) {
var prefix = "";
var suffix = "";
Expand Down Expand Up @@ -500,21 +535,30 @@ qx.Class.define('cv.io.Client', {
* backend and forwards to the configurated transport handleSession
* function
*
* @param ev {Event} the 'success' event from the XHR request
* Parameter vary dependent from the XHR type used
* qx (Qooxdoo):
* ev {Event} the 'success' event from the XHR request
*
* jQuery:
* data {Object} The JSON data returned from the server
* textStatus {String} a string describing the status
* request {Object} the jqXHR object
*/
handleLogin : function (ev) {
var json = this.getResponse(ev);
handleLogin : function () {
var args = Array.prototype.slice.call(arguments, 0);
var json = this.getResponse(args);
// read backend configuration if send by backend
if (json.c) {
this.setBackend(qx.lang.Object.mergeWith(this.getBackend(), json.c));
}
this.session = json.s || "SESSION";
this.setServer(this.getResponseHeader(args, "Server"));

this.setDataReceived(false);
if (this.loginSettings.loginOnly) {
this.getCurrentTransport().handleSession(ev, false);
this.getCurrentTransport().handleSession(args, false);
} else {
this.getCurrentTransport().handleSession(ev, true);
this.getCurrentTransport().handleSession(args, true);
// once the connection is set up, start the watchdog
this.watchdog.start(5);
}
Expand Down
16 changes: 7 additions & 9 deletions client/source/class/cv/io/transport/LongPolling.js
Expand Up @@ -53,11 +53,11 @@ qx.Class.define('cv.io.transport.LongPolling', {
* This function gets called once the communication is established
* and this.client information is available.
*
* @param ev {Event|Object} qx event or json response
* @param args {Array} arguments from the XHR response callback
* @param connect {Boolean} whether to start the connection or not
*/
handleSession: function (ev, connect) {
var json = this.client.getResponse(ev);
handleSession: function (args, connect) {
var json = this.client.getResponse(args);
this.sessionId = json.s;
this.version = json.v.split('.', 3);

Expand Down Expand Up @@ -103,11 +103,9 @@ qx.Class.define('cv.io.transport.LongPolling', {
/**
* This function gets called once the communication is established
* and this.client information is available
*
* @param ev {Event}
*/
handleRead: function (ev) {
var json = this.client.getResponse(ev);
handleRead: function () {
var json = this.client.getResponse(Array.prototype.slice.call(arguments, 0));
if (this.doRestart || (!json && (-1 === this.lastIndex))) {
this.client.setDataReceived(false);
if (this.running) { // retry initial request
Expand Down Expand Up @@ -149,8 +147,8 @@ qx.Class.define('cv.io.transport.LongPolling', {
}
},

handleReadStart: function (ev) {
var json = this.client.getResponse(ev);
handleReadStart: function () {
var json = this.client.getResponse(Array.prototype.slice.call(arguments, 0));
if (!json && (-1 === this.lastIndex)) {
this.client.setDataReceived(false);
if (this.running) { // retry initial request
Expand Down
35 changes: 26 additions & 9 deletions client/source/class/cv/io/transport/Sse.js
Expand Up @@ -32,7 +32,7 @@ qx.Class.define('cv.io.transport.Sse', {
*/
construct: function(client) {
this.client = client;
this.__additionalTopics = [];
this.__additionalTopics = {};
},

/*
Expand All @@ -51,11 +51,11 @@ qx.Class.define('cv.io.transport.Sse', {
* This function gets called once the communication is established
* and session information is available
*
* @param ev {Event}
* @param args {Array} arguments from the XHR response callback
* @param connect {Boolean} whether to start the connection or not
*/
handleSession: function (ev, connect) {
var json = this.client.getResponse(ev);
handleSession: function (args, connect) {
var json = this.client.getResponse(args);
this.sessionId = json.s;
this.version = json.v.split('.', 3);

Expand All @@ -82,9 +82,7 @@ qx.Class.define('cv.io.transport.Sse', {
this.eventSource.addEventListener('message', this.handleMessage.bind(this), false);
this.eventSource.addEventListener('error', this.handleError.bind(this), false);
// add additional listeners
this.__additionalTopics.forEach(function(entry) {
this.eventSource.addEventListener(entry[0], entry[1].bind(entry[2]), false);
}, this);
Object.getOwnPropertyNames(this.__additionalTopics).forEach(this.__addRecordedEventListener, this);
this.eventSource.onerror = function () {
this.error("connection lost");
this.client.setConnected(false);
Expand All @@ -108,19 +106,38 @@ qx.Class.define('cv.io.transport.Sse', {
this.client.setDataReceived(true);
},

dispatchTopicMessage: function(topic, message) {
this.client.record(topic, message);
if (this.__additionalTopics[topic]) {
this.__additionalTopics[topic].forEach(function(entry) {
entry[0].call(entry[1], message);
});
}
},

/**
* Subscribe to SSE events of a certain topic
* @param topic {String}
* @param callback {Function}
* @param context {Object}
*/
subscribe: function(topic, callback, context) {
this.__additionalTopics.push([topic, callback, context]);
if (!this.__additionalTopics[topic]) {
this.__additionalTopics[topic] = [];
}
this.__additionalTopics[topic].push([callback, context]);
if (this.isConnectionRunning()) {
this.eventSource.addEventListener(topic, callback.bind(context, false));
this.__addRecordedEventListener(topic);
}
},

__addRecordedEventListener: function(topic) {
this.debug("subscribing to topic "+topic);
this.eventSource.addEventListener(topic, function(e) {
this.dispatchTopicMessage(topic, e);
}.bind(this), false);
},

/**
* Handle errors
*/
Expand Down
9 changes: 6 additions & 3 deletions config.json
Expand Up @@ -44,7 +44,8 @@
{
"APPLICATION" : "cv",
"QOOXDOO_PATH" : "./external/qooxdoo",
"API_EXCLUDE" : ["qx.test.*", "${APPLICATION}.test.*"],
"QXTHEME" : "cv.theme.Dark",
"API_EXCLUDE" : ["qx.test.*", "${APPLICATION}.test.*", "${QXTHEME}"],
"LOCALES" : [ "en", "de" ],
"CACHE" : "${TMPDIR}/qx${QOOXDOO_VERSION}/cache",
"ROOT" : ".",
Expand Down Expand Up @@ -83,7 +84,8 @@
"${APPLICATION}.transforms.*",
"${APPLICATION}.plugins.*",
"${APPLICATION}.parser.*",
"${APPLICATION}.core.*"
"${APPLICATION}.core.*",
"${QXTHEME}"
],

"lint-check" : {
Expand Down Expand Up @@ -263,7 +265,7 @@
},
"plugin-openhab" :
{
"include" : [ "${APPLICATION}.plugins.openhab.*" ]
"include" : [ "${APPLICATION}.plugins.openhab.*", "${QXTHEME}" ]
}
}
}
Expand Down Expand Up @@ -403,6 +405,7 @@
"Sunlight",
"replayLog",
"svg4everybody",
"EVENT_RECORDER",
"Favico"
],
"generate-widget-examples": true
Expand Down
20 changes: 19 additions & 1 deletion source/class/cv/Application.js
Expand Up @@ -49,6 +49,10 @@ qx.Class.define("cv.Application",
*/
createClient: function() {
var args = Array.prototype.slice.call(arguments);
if (args[0] === "openhab2") {
// auto-load openhab plugin for this backend
cv.Config.configSettings.pluginsToLoad.push("plugin-openhab");
}
args.unshift(null);
if (cv.Config.testMode === true) {
return new (Function.prototype.bind.apply(cv.io.Mockup, args)); // jshint ignore:line
Expand All @@ -72,6 +76,18 @@ qx.Class.define("cv.Application",
}
},

/*
******************************************************
PROPERTIES
******************************************************
*/
properties: {
root: {
nullable: true
}
},


/*
*****************************************************************************
MEMBERS
Expand Down Expand Up @@ -188,7 +204,8 @@ qx.Class.define("cv.Application",
exString += "\n Description: " + ex.description;
}
try {
exString += "\nStack: " + qx.dev.StackTrace.getStackTraceFromError(ex).join("\n\t")+"\n";
exString += "\nNormalized Stack: " + qx.dev.StackTrace.getStackTraceFromError(ex).join("\n\t")+"\n";
exString += "\nOriginal Stack: " + ex.stack +"\n";
} catch(exc) {
if (ex.stack) {
exString += "\nStack: " + ex.stack+"\n";
Expand Down Expand Up @@ -311,6 +328,7 @@ qx.Class.define("cv.Application",
ajaxRequest.addListenerOnce("success", function (e) {
this.block(false);
var req = e.getTarget();
cv.Config.configServer = req.getResponseHeader("Server");
// Response parsed according to the server's response content type
var xml = req.getResponse();
if (xml && qx.lang.Type.isString(xml)) {
Expand Down
17 changes: 17 additions & 0 deletions source/class/cv/Config.js
Expand Up @@ -169,6 +169,11 @@ qx.Class.define('cv.Config', {
*/
enableLogging: true,

/**
* The server that responded to the config request
*/
configServer: null,

/**
* Get the structure that is related to this design
* @param design {String?} name of the design
Expand All @@ -189,6 +194,18 @@ qx.Class.define('cv.Config', {
return "structure-pure";
},

/**
* This method tries to guess if the CometVisu is running on a proxied webserver.
* (by comparing if the visu_config.xml-File has been delivered from another server than the
* loging response). As this is just an assumption, you should not treat this result as reliable.
*/
guessIfProxied: function() {
if (this.configServer === null || cv.TemplateEngine.getInstance().visu.getServer() === null) {
throw new Error("not ready yet");
}
return this.configServer !== cv.TemplateEngine.getInstance().visu.getServer();
},

addMapping: function (name, mapping) {
this.configSettings.mappings[name] = mapping;
},
Expand Down

0 comments on commit 778f8bd

Please sign in to comment.