Commit 235c02a2 authored by Boris Kocherov's avatar Boris Kocherov

[erp5_only_office] add xmla_client, partial use xmla_client for cubefunctions

parent e84b1df2
/*global window, rJS, RSVP, DocsAPI, console, document, /*global window, rJS, RSVP, DocsAPI, console, document,
Common, require, jIO, URL, FileReader, atob, ArrayBuffer, Common, require, jIO, URL, FileReader, atob, ArrayBuffer,
Uint8Array, XMLHttpRequest, Blob, Rusha, define, Uint8Array, XMLHttpRequest, Blob, Rusha, define,
Uint8ClampedArray, Uint8ClampedArray, Asc, History,
TextDecoder, DesktopOfflineAppDocumentEndSave*/ TextDecoder, DesktopOfflineAppDocumentEndSave*/
/*jslint nomen: true, maxlen:80, indent:2*/ /*jslint nomen: true, maxlen:80, indent:2*/
"use strict"; "use strict";
...@@ -52,6 +52,154 @@ DocsAPI.DocEditor.version = function () { ...@@ -52,6 +52,154 @@ DocsAPI.DocEditor.version = function () {
return new Blob([ab], {type: mimeString}); return new Blob([ab], {type: mimeString});
} }
function printOlapTable(xmla_client, data) {
var Api = Asc.editor,
s = Api.GetActiveSheet(),
connection_name,
start_row,
start_column;
function endTransaction() {
s.worksheet.workbook.dependencyFormulas.unlockRecal();
History.EndTransaction();
Api._onUpdateAfterApplyChanges();
Api._onUpdateDocumentCanSave();
}
function setCell(row, col, value) {
// setValue on range
s.GetRangeByNumber(row, col).range._foreach(function (cell) {
cell.setValue(value);
});
}
function print_titles(levels, begin_row, begin_column, columns) {
var members = [],
member,
i,
m,
x,
z,
row,
col,
span,
repeats;
function amp_arr_length(amp, arr) {
if (arr.length === 0) {
return amp;
}
return amp * arr.length;
}
for (i = 0; i < levels.length; i += 1) {
members = levels[i];
span = levels.slice(i + 1).reduce(amp_arr_length, 1);
repeats = levels.slice(0, i).reduce(amp_arr_length, 1);
for (z = 0; z < repeats * members.length * span; z += (members.length * span)) {
for (m = 0; m < members.length; m += 1) {
member = members[m];
for (x = 0; x < span; x += 1) {
if (columns) {
row = begin_row + i;
col = begin_column + z + (m * span) + x;
} else {
row = begin_row + z + (m * span) + x;
col = begin_column + i;
}
setCell(row, col,
"=CUBEMEMBER(" + connection_name + ',"' + member.uname + '")');
}
}
}
}
return repeats * members.length * span;
}
return RSVP.Queue()
.push(function () {
// var active = s.GetActiveCell();
// var row = active.GetRow();
// var col = active.GetCol();
start_row = 0;
start_column = 0;
History.Create_NewPoint();
s.worksheet.workbook.dependencyFormulas.lockRecal();
// XXX use named ranges for cleaning space
s.worksheet.getRange3(0, 0, 100, 100).cleanAll();
// (new Asc.asc_CDefName(
// "name111",
// "Sheet1!$A$3:$D$13",
// null, // or number of sheet
// this.props.asc_getIsTable(),
// false, // Hidden
// false // locked
// ));
// rows titles
setCell(start_row, start_column, "Connection:");
setCell(start_row, start_column + 1, data.connection_name);
connection_name = "$B$1";
start_row += 2;
// XXX default absent in json schema
data.rows = data.rows || [];
data.columns = data.columns || [];
return RSVP.all([
RSVP.all(data.rows
.filter(function (i) {
return i.hasOwnProperty("level");
})
.map(function (i) {
return xmla_client
.getMembersOnLevel(data.connection_name, i.level);
})),
RSVP.all(data.columns
.filter(function (i) {
return i.hasOwnProperty("level");
})
.map(function (i) {
return xmla_client
.getMembersOnLevel(data.connection_name, i.level);
}))
]);
})
.push(function (arr) {
var rows = arr[0],
columns = arr[1],
c,
c_len,
r,
r_len;
r_len = print_titles(rows, start_row + columns.length, start_column, false);
c_len = print_titles(columns, start_row, start_column + rows.length, true);
r_len = r_len + start_row + columns.length;
c_len = c_len + start_column + rows.length;
for (r = start_row + columns.length; r < r_len; r += 1) {
for (c = start_column + rows.length; c < c_len; c += 1) {
setCell(r, c,
"=CUBEVALUE(" + connection_name + ',' +
s.worksheet.getRange3(r, start_column, r, start_column + rows.length -1).getName() +
',' +
s.worksheet.getRange3(start_row, c, start_row + columns.length - 1, c).getName() +
')');
}
}
endTransaction();
})
.push(undefined, function (error) {
endTransaction();
throw error;
});
}
rJS(window) rJS(window)
.ready(function (g) { .ready(function (g) {
g.props = { g.props = {
...@@ -167,13 +315,15 @@ DocsAPI.DocEditor.version = function () { ...@@ -167,13 +315,15 @@ DocsAPI.DocEditor.version = function () {
return queue; return queue;
}) })
.allowPublicAcquisition("notifyChange", function (arr, scope) { .allowPublicAcquisition("notifyChange", function (arr, scope) {
var gadget = this; var gadget = this,
content;
if (scope === "remote_settings") { if (scope === "remote_settings") {
return this.getDeclaredGadget(scope) return this.getDeclaredGadget(scope)
.push(function (g) { .push(function (g) {
return g.getContent(); return g.getContent();
}) })
.push(function (data) { .push(function (data) {
content = data;
return gadget return gadget
.jio_putAttachment('/', 'remote_settings.json', data); .jio_putAttachment('/', 'remote_settings.json', data);
}) })
...@@ -182,6 +332,12 @@ DocsAPI.DocEditor.version = function () { ...@@ -182,6 +332,12 @@ DocsAPI.DocEditor.version = function () {
Asc.editor._onUpdateDocumentCanSave(); Asc.editor._onUpdateDocumentCanSave();
return gadget.changeState({changed: true}); return gadget.changeState({changed: true});
}) })
.push(function () {
return gadget.getDeclaredGadget("xmla_client");
})
.push(function (g) {
return g.setConnectionsSettings(content);
})
.push(function () { .push(function () {
return gadget.getDeclaredGadget("xmlawizard"); return gadget.getDeclaredGadget("xmlawizard");
}) })
...@@ -195,10 +351,16 @@ DocsAPI.DocEditor.version = function () { ...@@ -195,10 +351,16 @@ DocsAPI.DocEditor.version = function () {
if (scope === "xmlawizard") { if (scope === "xmlawizard") {
return this.getDeclaredGadget(scope) return this.getDeclaredGadget(scope)
.push(function (g) { .push(function (g) {
return g.getContent(); return RSVP.all([
gadget.getDeclaredGadget("xmla_client"),
g.getContent()
]);
}) })
.push(function (data) { .push(function (arr) {
console.log(JSON.stringify(data)); return printOlapTable(arr[0], arr[1]);
})
.push(function () {
return gadget.changeState({changed: true});
}) })
.push(undefined, function (e) { .push(undefined, function (e) {
console.error(e); console.error(e);
...@@ -431,7 +593,7 @@ DocsAPI.DocEditor.version = function () { ...@@ -431,7 +593,7 @@ DocsAPI.DocEditor.version = function () {
config[old_url] = [ config[old_url] = [
new_url, new_url,
old_url old_url
]; ];
} }
} }
} }
...@@ -494,6 +656,12 @@ DocsAPI.DocEditor.version = function () { ...@@ -494,6 +656,12 @@ DocsAPI.DocEditor.version = function () {
return loadScript(app_url); return loadScript(app_url);
}) })
.push(function () {
// declare public gadgets only after configure requirejs
// public because xmla_client return not serialized data
return g.declareGadget('onlyoffice/xmla_client.html',
{scope: 'xmla_client', sandbox: "public"});
})
.push(undefined, function (error) { .push(undefined, function (error) {
display_error(g, error); display_error(g, error);
}); });
...@@ -562,9 +730,8 @@ DocsAPI.DocEditor.version = function () { ...@@ -562,9 +730,8 @@ DocsAPI.DocEditor.version = function () {
.push(function (Editor_bin) { .push(function (Editor_bin) {
if (Editor_bin) { if (Editor_bin) {
return zip.getAttachment('/', '/'); return zip.getAttachment('/', '/');
} else {
return new Blob();
} }
return new Blob();
}) })
.push(function (zip_blob) { .push(function (zip_blob) {
return jIO.util.readBlobAsDataURL(zip_blob); return jIO.util.readBlobAsDataURL(zip_blob);
......
...@@ -68,6 +68,7 @@ function (window, RSVP, Xmla, console) { ...@@ -68,6 +68,7 @@ function (window, RSVP, Xmla, console) {
function xmla_request(func, prop) { function xmla_request(func, prop) {
var xmla = new Xmla({async: true}); var xmla = new Xmla({async: true});
prop = JSON.parse(JSON.stringify(prop));
// return function () { // return function () {
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
...@@ -85,30 +86,30 @@ function (window, RSVP, Xmla, console) { ...@@ -85,30 +86,30 @@ function (window, RSVP, Xmla, console) {
function xmla_request_retry(func, settings) { function xmla_request_retry(func, settings) {
var queue, var queue,
urls = settings.urls, urls = settings.urls || [""],
i; i;
function make_request(url) { function make_request(url) {
return function (error) { return function (error) {
settings.prop.url = url; settings.prop.url = url;
return xmla_request(func, settings.prop) return xmla_request(func, settings.prop)
.push(undefined, function (response) { .push(undefined, function (response) {
// fix mondrian Internal and Sql errors // fix mondrian Internal and Sql errors
if (response) { if (response) {
switch (response["code"]) { switch (response["code"]) {
case "SOAP-ENV:Server.00HSBE02": case "SOAP-ENV:Server.00HSBE02":
case "SOAP-ENV:00UE001.Internal Error": case "SOAP-ENV:00UE001.Internal Error":
// rarely server error, so try again // rarely server error, so try again
return xmla_request(func, settings.prop); return xmla_request(func, settings.prop);
} }
} }
throw response; throw response;
}); });
}; };
} }
queue = make_request(urls[0])(); queue = make_request(urls[0])();
for (i = 1; i < settings.urls.length; i += 1) { for (i = 1; i < urls.length; i += 1) {
queue.push(undefined, make_request(urls[i])); queue.push(undefined, make_request(urls[i]));
} }
return queue; return queue;
...@@ -415,85 +416,8 @@ function (window, RSVP, Xmla, console) { ...@@ -415,85 +416,8 @@ function (window, RSVP, Xmla, console) {
return execution_scheme.execute.promise; return execution_scheme.execute.promise;
} }
function discover_members(connection, opt) { function getXmlaClient() {
return getProperties(connection) return Common.Gateway.getDeclaredGadget("xmla_client");
.push(function (settings) {
var prop = settings.prop,
cached_member,
scheme = getExecutionScheme(connection);
prop.restrictions = {
// 'CATALOG_NAME': 'FoodMart',
'CUBE_NAME': settings["cube"]
};
if (!opt) {
opt = {};
}
if (opt.member_uname) {
prop.restrictions["MEMBER_UNIQUE_NAME"] = opt.member_uname;
}
if (opt.level_uname) {
prop.restrictions["LEVEL_UNIQUE_NAME"] = opt.level_uname;
}
if (opt.tree_op) {
prop.restrictions["TREE_OP"] = opt.tree_op;
}
return xmla_request_retry("discoverMDMembers", settings)
.push(function (r) {
var ret = [],
uname,
level,
cached_member;
while (r.hasMoreRows()) {
uname = r["getMemberUniqueName"]();
level = r["getLevelUniqueName"]();
// we can check cache twice because fist check
// only if discover by member_uname
if (!scheme.members.hasOwnProperty(uname)) {
cached_member = {
uname: uname,
h: r["getHierarchyUniqueName"](),
level: r["getLevelUniqueName"](),
caption: r["getMemberCaption"](),
type: r["getMemberType"]()
};
scheme.members[uname] = cached_member;
} else {
cached_member = scheme.members[uname];
}
ret.push(cached_member);
r.nextRow();
if (!scheme.levels.hasOwnProperty(level)) {
scheme.levels[level] = discover_level(connection, scheme, level);
}
}
return ret;
});
});
}
function discover_level(connection, scheme, level) {
return discover_members(connection, {
level_uname: level
})
.push(function (members) {
var i;
function compare(a, b) {
if (a.uname < b.uname) {
return -1;
}
if (a.uname > b.uname) {
return 1;
}
return 0;
}
members.sort(compare);
for (i = 0; i < members.length; i += 1) {
members[i].level_index = i;
}
scheme.levels[level] = members;
});
} }
function discover_members_for_arguments(connection, members) { function discover_members_for_arguments(connection, members) {
...@@ -511,16 +435,14 @@ function (window, RSVP, Xmla, console) { ...@@ -511,16 +435,14 @@ function (window, RSVP, Xmla, console) {
if (member) { if (member) {
promises promises
.push( .push(
discover_members(connection, { getXmlaClient()
member_uname: member, .push(function (xmla_client) {
tree_op: 8 return xmla_client.getMember(connection, member);
}) })
.push(function (members) { .push(function (member) {
var m; if (member) {
if (members.length > 0) { check_interseption(member.h);
m = members[0]; return member;
check_interseption(m.h);
return m;
} else { } else {
throw "member not found"; throw "member not found";
} }
...@@ -577,7 +499,7 @@ function (window, RSVP, Xmla, console) { ...@@ -577,7 +499,7 @@ function (window, RSVP, Xmla, console) {
caption; caption;
return queue return queue
.push(function (arg) { .push(function (arg) {
connection = getCell(arg[0]); connection = getCell(arg[0]).toString();
caption = getCell(arg[2]); caption = getCell(arg[2]);
if (caption) { if (caption) {
caption = caption.getValue(); caption = caption.getValue();
...@@ -603,26 +525,21 @@ function (window, RSVP, Xmla, console) { ...@@ -603,26 +525,21 @@ function (window, RSVP, Xmla, console) {
.push(undefined, error_handler(current_cell_id)); .push(undefined, error_handler(current_cell_id));
}; };
cCUBEMEMBER.prototype.changeOffsetElem = function (arg, offset) { cCUBEMEMBER.prototype.changeOffsetElem = function (arg, offset) {
var connection = getCell(arg[0]), var connection_name = getCell(arg[0]).toString();
scheme = getExecutionScheme(connection), return RSVP.all(arg.slice(1).map(function (elem) {
i,
elem,
member,
new_member,
level;
for (i = 0; i < arg.length; i += 1) {
elem = arg[i];
if (cElementType.string === elem.type) { if (cElementType.string === elem.type) {
member = scheme.members[elem.value]; return getXmlaClient()
if (member && (member.level_index >= 0)) { .push(function (xmla_client) {
level = scheme.levels[member.level]; return xmla_client
new_member = level[member.level_index + offset.offsetCol + offset.offsetRow]; .getMemberWithOffset(connection_name, elem.value, offset.offsetCol + offset.offsetRow);
if (new_member) { })
elem.value = new_member.uname; .push(function (member) {
} if (member) {
} elem.value = member.uname;
}
});
} }
} }));
}; };
cCUBEMEMBER.prototype.getInfo = function () { cCUBEMEMBER.prototype.getInfo = function () {
return { return {
...@@ -695,7 +612,7 @@ function (window, RSVP, Xmla, console) { ...@@ -695,7 +612,7 @@ function (window, RSVP, Xmla, console) {
waiter = AddCubeValueCalculate(current_cell_id); waiter = AddCubeValueCalculate(current_cell_id);
return queue return queue
.push(function (arg) { .push(function (arg) {
connection = getCell(arg[0]); connection = getCell(arg[0]).toString();
scheme = getExecutionScheme(connection); scheme = getExecutionScheme(connection);
return parseArgs(arg.slice(1))(); return parseArgs(arg.slice(1))();
}) })
......
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>XMLA Client</title>
<script type="text/javascript" src="../rsvp.js" ></script>
<script type="text/javascript" src="../renderjs.js"></script>
<script type="text/javascript" src="web-apps/vendor/xmla4js/Xmla-compiled.js"></script>
<script type="text/javascript" src="xmla_client.js"></script>
</head>
<body>
</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>xmla_client.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*/
(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 < urls.length; i += 1) {
queue.push(undefined, make_request(urls[i]));
}
return queue;
}
function discoverDimensions(schema, used_dimensions, opt) {
return xmla_request_retry("discoverMDDimensions", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
var arr = [],
row;
if (response && response.numRows > 0) {
while (response.hasMoreRows()) {
row = response.readAsObject();
if (row["DIMENSION_TYPE"] !== 2) {
if (used_dimensions.indexOf(row["DIMENSION_UNIQUE_NAME"]) < 0) {
arr.push({
const: row["DIMENSION_UNIQUE_NAME"] || undefined,
title: row["DIMENSION_NAME"] || undefined
});
}
}
response.nextRow();
}
}
if (arr.length !== 0) {
schema.properties.dimension = {
title: " ",
oneOf: arr
};
}
});
}
function discoverHierarchies(schema, opt) {
return xmla_request_retry("discoverMDHierarchies", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
var arr = [],
row;
if (response && response.numRows > 0) {
while (response.hasMoreRows()) {
row = response.readAsObject();
arr.push({
const: row["HIERARCHY_UNIQUE_NAME"] || undefined,
title: row["HIERARCHY_NAME"] || undefined
});
response.nextRow();
}
}
if (arr.length !== 0) {
schema.properties.hierarchy = {
title: " ",
oneOf: arr
};
}
});
}
function discoverLevels(schema, opt) {
return xmla_request_retry("discoverMDLevels", opt)
.push(undefined, function (error) {
console.log(error);
})
.push(function (response) {
var arr = [],
row;
if (response && response.numRows > 0) {
while (response.hasMoreRows()) {
row = response.readAsObject();
arr.push({
const: row["LEVEL_UNIQUE_NAME"] || undefined,
title: row["LEVEL_NAME"] || undefined
});
response.nextRow();
}
}
if (arr.length !== 0) {
schema.properties.level = {
title: " ",
oneOf: arr
};
}
});
}
rJS(window)
.ready(function () {
var g = this;
console.log("xmla_client");
g.props = {
cache: {},
connections: {}
};
return g.getRemoteSettings()
.push(function (settings) {
return g.setConnectionsSettings(settings);
})
})
.declareAcquiredMethod("getRemoteSettings", "getRemoteSettings")
.declareMethod("getConnectionSettings", function (name) {
return this.props.connections[name];
})
.declareMethod("setConnectionsSettings", function (connections) {
var key,
new_state = {};
for (key in connections) {
if (connections.hasOwnProperty(key) && connections[key]) {
new_state[key] = JSON.stringify(connections[key]);
}
}
for (key in this.state) {
if (this.state.hasOwnProperty(key) && !connections[key]) {
new_state[key] = null;
}
}
return this.changeState(new_state);
})
.onStateChange(function (m_dict) {
var g = this,
key;
for (key in m_dict) {
if (m_dict.hasOwnProperty(key)) {
delete g.props.cache[key];
delete g.props.connections[key];
if (m_dict[key] !== null) {
g.props.cache[key] = {
members: {},
levels: {}
};
g.props.connections[key] = JSON.parse(m_dict[key]);
}
}
}
})
.declareMethod("request", function (function_name, settings, connection_name) {
var queue;
if (connection_name) {
queue = this.getConnectionSettings(connection_name);
} else {
queue = RSVP.Queue();
}
return queue
.push(function (connection_settings) {
if (!settings) {
settings = {};
}
if (connection_settings) {
settings.urls = connection_settings.urls;
settings.prop.restrictions.CATALOG_NAME = connection_settings.properties.Catalog;
settings.prop.restrictions.CUBE_NAME = connection_settings.properties.Cube;
}
return xmla_request_retry(function_name, settings);
})
.push(undefined, function (error) {
console.error(error);
});
})
.declareMethod("getMembersOnLevel", function (connection_name, level_uname) {
var g = this,
cache = g.props.cache[connection_name];
if (cache.levels.hasOwnProperty(level_uname)) {
return cache.levels[level_uname];
}
return g.request("discoverMDMembers", {
prop: {
restrictions: {
LEVEL_UNIQUE_NAME: level_uname
}
}
}, connection_name)
.push(function (r) {
var uname,
member,
i,
level = [];
while (r.hasMoreRows()) {
uname = r["getMemberUniqueName"]();
if (level_uname !== r["getLevelUniqueName"]()) {
throw "xmla server fail";
}
member = {
uname: uname,
level: level_uname,
h: r["getHierarchyUniqueName"](),
caption: r["getMemberCaption"](),
type: r["getMemberType"]()
};
r.nextRow();
cache.members[uname] = member;
level.push(member);
}
function compare(a, b) {
if (a.uname < b.uname) {
return -1;
}
if (a.uname > b.uname) {
return 1;
}
return 0;
}
level.sort(compare);
for (i = 0; i < level.length; i += 1) {
level[i].level_index = i;
}
cache.levels[level_uname] = level;
return level;
});
}, {mutex: 'getMembersOnLevel'})
.declareMethod("getMember", function (connection_name, memeber_uname) {
var g = this,
cache = g.props.cache[connection_name];
if (cache.members.hasOwnProperty(memeber_uname)) {
return cache.members[memeber_uname];
}
return g.request("discoverMDMembers", {
prop: {
restrictions: {
MEMBER_UNIQUE_NAME: memeber_uname,
TREE_OP: 0x08 // MDTREEOP_SELF
// TREE_OP: 0x02 // MDTREEOP_SIBLINGS
}
}
}, connection_name)
.push(function (r) {
if (r.length === 0) {
return;
}
return g.getMembersOnLevel(connection_name, r["getLevelUniqueName"]());
})
.push(function (level) {
if (!level) {
return;
}
return cache.members[memeber_uname];
});
}, {mutex: 'getMember'})
.declareMethod("getMemberWithOffset", function (connection_name, memeber_uname, offset) {
var g = this,
member;
return g.getMember(connection_name, memeber_uname)
.push(function (m) {
member = m;
if (member && (member.level_index >= 0)) {
return g.getMembersOnLevel(connection_name, member.level);
}
})
.push(function (level) {
if (level) {
return level[member.level_index + offset];
}
});
});
}(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>xmla_client.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>
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