Commit f2b969c6 authored by Boris Kocherov's avatar Boris Kocherov Committed by Romain Courteaud

[erp5_only_office] use xmla discover to generate xmla settings form

parent 23ab2c80
......@@ -251,6 +251,8 @@ onlyoffice.gadget.html\n
onlyoffice.gadget.js\n
onlyoffice.gadget.appcache\n
#autogenerated for: erp5_onlyoffice_webapps\n
onlyoffice/remote_settings.html\n
onlyoffice/remote_settings.js\n
onlyoffice/remote_settings.json\n
onlyoffice/xmla_connection.json\n
onlyoffice/web-apps/apps/common/Analytics.js\n
......
......@@ -20,6 +20,8 @@ jsonform/gadget_json_generated_form_child.js
jsonform/tv4.js
#autogenerated for: erp5_onlyoffice_webapps
onlyoffice/remote_settings.html
onlyoffice/remote_settings.js
onlyoffice/remote_settings.json
onlyoffice/xmla_connection.json
onlyoffice/web-apps/apps/common/Analytics.js
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Demo UI OLAP Query editor based on JSON Schema form generator</title>
<link rel="stylesheet" href="../gadget_erp5_nojqm.css">
<script src="../rsvp.js"></script>
<script src="../renderjs.js"></script>
<script src="../jio.js"></script>
<script src="web-apps/vendor/xmla4js/Xmla-compiled.js"></script>
<script src="remote_settings.js"></script>
</head>
<body>
<div data-role="page">
<div role="main" class="ui-content gadget-content">
<section class="ui-content-header-plain">
<h3 class="ui-content-title ui-body-c">
Xmla connection settings form
</h3>
</section>
<div data-gadget-url="../jsonform.gadget.html"
data-gadget-scope="xmla_settings"
data-gadget-sandbox="public"></div>
<br>
</div>
</div>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value> <string>http_cache</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>remote_settings.html</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*jslint nomen: true, maxlen: 200, indent: 2*/
/*global rJS, console, window, document, RSVP, Xmla, Error*/
(function (window, rJS) {
"use strict";
function xmla_request(func, prop) {
var xmla = new Xmla({async: true});
prop = JSON.parse(JSON.stringify(prop));
// return function () {
return new RSVP.Queue()
.push(function () {
return new RSVP.Promise(function (resolve, reject) {
prop.success = function (xmla, options, response) {
resolve(response);
};
prop.error = function (xmla, options, response) {
reject(response);
};
xmla[func](prop);
});
});
}
function xmla_request_retry(func, settings) {
var queue,
urls = settings.urls,
i;
function make_request(url) {
return function (error) {
settings.prop.url = url;
return xmla_request(func, settings.prop)
.push(undefined, function (response) {
// fix mondrian Internal and Sql errors
if (response) {
switch (response["code"]) {
case "SOAP-ENV:Server.00HSBE02":
case "SOAP-ENV:00UE001.Internal Error":
// rarely server error, so try again
return xmla_request(func, settings.prop);
}
}
throw response;
});
};
}
queue = make_request(urls[0])();
for (i = 1; i < settings.urls.length; i += 1) {
queue.push(undefined, make_request(urls[i]));
}
return queue;
}
function discoverDataSources(schema, opt) {
return xmla_request_retry("discoverDataSources", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.DataSourceInfo = {
title: " ",
oneOf: []
};
var arr = schema.properties.DataSourceInfo.oneOf;
while (response.hasMoreRows()) {
arr.push({
const: response["getDataSourceInfo"]() || undefined,
title: response["getDataSourceName"]() || undefined,
description: response["getDataSourceDescription"]() || undefined
});
response.nextRow();
}
}
});
}
function discoverDBCatalogs(schema, opt) {
return xmla_request_retry("discoverDBCatalogs", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.Catalog = {
title: " ",
oneOf: []
};
var arr = schema.properties.Catalog.oneOf;
while (response.hasMoreRows()) {
arr.push({
const: response["getCatalogName"]() || undefined,
title: response["getCatalogName"]() || undefined
});
response.nextRow();
}
}
});
}
function discoverMDCubes(schema, opt) {
return xmla_request_retry("discoverMDCubes", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
if (response && response.numRows > 0) {
schema.properties.Cube = {
title: " ",
oneOf: []
};
var arr = schema.properties.Cube.oneOf;
while (response.hasMoreRows()) {
arr.push({
const: response["getCubeName"]() || undefined,
title: response["getCubeName"]() || undefined
// title: response["getCatalogName"]() || undefined
});
response.nextRow();
}
}
});
}
function generateSchema(settings) {
var schema = {
"type": "object",
"additionalProperties": false,
"required": ["Cube"],
"properties": {
"DataSourceInfo": {"type": "string"},
"Catalog": {"type": "string"},
"Cube": {"type": "string"}
}
};
if (!settings) {
return new RSVP.Queue()
.push(function () {
return schema;
});
}
if (!settings.hasOwnProperty('properties')) {
settings.properties = {};
}
return new RSVP.Queue()
.push(function () {
return RSVP.all([
discoverDataSources(schema, {
urls: settings.urls,
prop: {}
}),
discoverDBCatalogs(schema, {
urls: settings.urls,
prop: {
properties: {
DataSourceInfo: settings.properties.DataSourceInfo
}
}
}),
discoverMDCubes(schema, {
urls: settings.urls,
prop: {
properties: {
DataSourceInfo: settings.properties.DataSourceInfo,
Catalog: settings.properties.Catalog
}
}
})
]);
})
.push(function () {
return schema;
});
}
function decodeJsonPointer(_str) {
// https://tools.ietf.org/html/rfc6901#section-5
return _str.replace(/~1/g, '/').replace(/~0/g, '~');
}
function convertOnMultiLevel(d, key, value) {
var ii,
kk,
key_list = key.split("/");
for (ii = 1; ii < key_list.length; ii += 1) {
kk = decodeJsonPointer(key_list[ii]);
if (ii === key_list.length - 1) {
if (value !== undefined) {
d[kk] = value[0];
} else {
return d[kk];
}
} else {
if (!d.hasOwnProperty(kk)) {
if (value !== undefined) {
d[kk] = {};
} else {
return;
}
}
d = d[kk];
}
}
}
rJS(window)
.ready(function (g) {
g.props = {};
g.props.xmla_connections = {};
})
.allowPublicAcquisition("notifyValid", function (arr, scope) {
})
.allowPublicAcquisition("notifyInvalid", function (arr, scope) {
})
.declareMethod("render", function (opt) {
this.props.init_value = opt.value;
return this.getDeclaredGadget("xmla_settings")
.push(function (g) {
return g.render(opt);
});
})
.declareMethod("getContent", function () {
return this.getDeclaredGadget("xmla_settings")
.push(function (g) {
return g.getContent();
});
})
.declareAcquiredMethod("notifyChange", "notifyChange")
.allowPublicAcquisition("notifyChange", function (arr, scope) {
var g = this,
p = arr[0],
gadget_settings,
path;
function f(p) {
var settings;
return g.getDeclaredGadget("xmla_settings")
.push(function (gadget) {
gadget_settings = gadget;
return gadget.getContent(p);
})
.push(function (c) {
settings = c;
return generateSchema(c);
})
.push(function (schema) {
return gadget_settings.getGadgetByPath(p + '/properties')
.push(function (ret) {
return ret.gadget.rerender({
schema: schema,
value: convertOnMultiLevel(settings, '/properties')
});
});
})
.push(function () {
return g.notifyChange();
});
}
for (path in g.props.xmla_connections) {
if (g.props.xmla_connections.hasOwnProperty(path) &&
p.startsWith(path)) {
return f(path);
}
}
return g.notifyChange();
})
.allowPublicAcquisition("resolveExternalReference", function (arr) {
var g = this,
url = arr[0],
schema_path = arr[1],
path = arr[2],
settings,
connection_path;
if ("urn:jio:properties_from_xmla.connection.json" === url) {
connection_path = path.split('/').slice(0, -1).join('/');
if (!g.props.xmla_connections[connection_path]) {
return new RSVP.Queue()
.push(function () {
if (g.props.init_value) {
settings = convertOnMultiLevel(g.props.init_value, connection_path);
if (settings) {
convertOnMultiLevel(g.props.init_value, connection_path, []);
}
}
return generateSchema(settings);
})
.push(function (s) {
g.props.xmla_connections[connection_path] = false;
return s;
});
}
}
throw new Error("urn: '" + url + "' not supported");
});
}(window, rJS));
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Cacheable__manager_id</string> </key>
<value> <string>http_cache</string> </value>
</item>
<item>
<key> <string>__name__</string> </key>
<value> <string>remote_settings.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -492,10 +492,10 @@ define([
.push(function (value) {
me.dlgRemote = new Common.Views.RenderJSDialog({
toolclose: "hide",
gadget_url: "jsonform.gadget.html",
gadget_url: "onlyoffice/remote_settings.html",
scope: "remote_settings",
gadget_render_opt: {
schema_url: "onlyoffice/remote_settings.json",
schema_url: "remote_settings.json",
value: value
}
});
......
......@@ -14,20 +14,7 @@
"type": "array"
},
"properties": {
"type": "object",
"additionalProperties": false,
"required": ["Cube"],
"properties": {
"DataSourceInfo": {"type": "string"},
"Catalog": {"type": "string"},
"Cube": {"type": "string"}
}
},
"username": {
"type": "string"
},
"password": {
"type": "string"
"$ref": "urn:jio:properties_from_xmla.connection.json"
}
},
"required": [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment