RandomSec/extensions/freebase/module/scripts/dialogs/schema-alignment/dialog.js

291 lines
9.1 KiB
JavaScript

var SchemaAlignment = {};
SchemaAlignment.autoAlign = function() {
var protograph = {};
var columns = theProject.columnModel.columns;
var typedCandidates = [];
var candidates = [];
for (var c = 0; c < columns.length; c++) {
var column = columns[c];
var typed = (column.reconConfig) &&
ReconciliationManager.isFreebaseIdOrMid(column.reconConfig.identifierSpace) &&
ReconciliationManager.isFreebaseId(column.reconConfig.schemaSpace);
var candidate = {
status: "unbound",
typed: typed,
index: c,
column: column
};
candidates.push(candidate);
if (typed) {
typedCandidates.push(candidate);
}
}
if (typedCandidates.length > 0) {
} else {
var queries = {};
for (var i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
var name = SchemaAlignment._cleanName(candidate.column.name);
var key = "t" + i + ":search";
queries[key] = {
"query" : name,
"limit" : 10,
"type" : "/type/type,/type/property",
"type_strict" : "any"
};
}
SchemaAlignment._batchSearch(queries, function(result) {
console.log(result);
});
}
};
SchemaAlignment._batchSearch = function(queries, onDone) {
var keys = [];
for (var n in queries) {
if (queries.hasOwnProperty(n)) {
keys.push(n);
}
}
var result = {};
var args = [];
var makeBatch = function(keyBatch) {
var batch = {};
for (var k = 0; k < keyBatch.length; k++) {
var key = keyBatch[k];
batch[key] = queries[key];
}
args.push("http://api.freebase.com/api/service/search?" +
$.param({ "queries" : JSON.stringify(batch) }) + "&callback=?");
args.push(null); // no data
args.push(function(data) {
for (var k = 0; k < keyBatch.length; k++) {
var key = keyBatch[k];
result[key] = data[key];
}
});
};
for (var i = 0; i < keys.length; i += 10) {
makeBatch(keys.slice(i, i + 10));
}
args.push(function() {
onDone(result);
});
Ajax.chainGetJSON.apply(null, args);
};
SchemaAlignment._cleanName = function(s) {
return s.replace(/\W/g, " ").replace(/\s+/g, " ").toLowerCase();
};
SchemaAlignment.createNewRootNode = function() {
var rootNode = null;
var links = [];
var columns = theProject.columnModel.columns;
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
var target = {
nodeType: "cell-as-topic",
columnName: column.name,
createForNoReconMatch: true
};
if ((column.reconConfig) &&
ReconciliationManager.isFreebaseIdOrMid(column.reconConfig.identifierSpace) &&
ReconciliationManager.isFreebaseId(column.reconConfig.schemaSpace) &&
(column.reconConfig.type)) {
target.type = {
id: column.reconConfig.type.id,
name: column.reconConfig.type.name
};
}
if (column.name == theProject.columnModel.keyColumnName) {
rootNode = target;
} else {
links.push({
property: null,
target: target
});
}
}
rootNode = rootNode || { nodeType: "cell-as-topic" };
rootNode.links = links;
return rootNode;
};
function SchemaAlignmentDialog(protograph, onDone) {
this._onDone = onDone;
this._originalProtograph = protograph || { rootNodes: [] };
this._protograph = cloneDeep(this._originalProtograph); // this is what can be munched on
if (!this._protograph.rootNodes.length) {
this._protograph.rootNodes.push(SchemaAlignment.createNewRootNode());
}
this._nodeUIs = [];
this._createDialog();
this.preview();
}
SchemaAlignmentDialog.prototype._createDialog = function() {
var self = this;
var frame = DialogSystem.createDialog();
frame.width("1000px");
var header = $('<div></div>').addClass("dialog-header").text("Schema Alignment").appendTo(frame);
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
this._constructFooter(footer);
this._constructBody(body);
this._level = DialogSystem.showDialog(frame);
this._renderBody(body);
};
SchemaAlignmentDialog.prototype._constructFooter = function(footer) {
var self = this;
$('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() {
var protograph = self.getJSON();
Refine.postProcess(
"freebase-extension",
"save-protograph",
{},
{ protograph: JSON.stringify(protograph) },
{},
{
onDone: function() {
DialogSystem.dismissUntil(self._level - 1);
theProject.overlayModels.freebaseProtograph = protograph;
}
}
);
}).appendTo(footer);
$('<button></button>').text("Cancel").click(function() {
DialogSystem.dismissUntil(self._level - 1);
}).appendTo(footer);
};
SchemaAlignmentDialog.prototype._constructBody = function(body) {
$('<p>' +
'The schema alignment skeleton below specifies how the graph-shaped data that will get generated ' +
'from your grid-shaped data and written into Freebase. The cells in each record of your data will ' +
'get placed into nodes within the skeleton. Configure the skeleton by specifying which ' +
'column to substitute into which node. A node can also be an automatically generated ' +
'anonymous node, or it can be an explicit value or topic that is the same for all records.' +
'</p>').appendTo(body);
$(
'<div id="schema-alignment-tabs" class="refine-tabs">' +
'<ul>' +
'<li><a href="#schema-alignment-tabs-protograph">Skeleton</a></li>' +
'<li><a href="#schema-alignment-tabs-preview-mqllike">MQL-like Preview</a></li>' +
'<li><a href="#schema-alignment-tabs-preview-tripleloader">TripleLoader Preview</a></li>' +
'</ul>' +
'<div id="schema-alignment-tabs-protograph">' +
'<div class="schema-alignment-dialog-canvas"></div>' +
'</div>' +
'<div id="schema-alignment-tabs-preview-mqllike" style="display: none;">' +
'<div class="schema-alignment-dialog-preview"></div>' +
'</div>' +
'<div id="schema-alignment-tabs-preview-tripleloader" style="display: none;">' +
'<div class="schema-alignment-dialog-preview"></div>' +
'</div>' +
'</div>'
).appendTo(body);
};
SchemaAlignmentDialog.prototype._renderBody = function(body) {
var self = this;
$("#schema-alignment-tabs").tabs();
$("#schema-alignment-tabs-preview-mqllike").css("display", "");
$("#schema-alignment-tabs-preview-tripleloader").css("display", "");
this._canvas = $(".schema-alignment-dialog-canvas");
this._nodeTable = $('<table></table>').addClass("schema-alignment-table-layout").appendTo(this._canvas)[0];
for (var i = 0; i < this._protograph.rootNodes.length; i++) {
this._nodeUIs.push(new SchemaAlignmentDialog.UINode(
this,
this._protograph.rootNodes[i],
this._nodeTable,
{
expanded: true,
mustBeCellTopic: true
}
));
}
this._previewPanes = $(".schema-alignment-dialog-preview");
};
SchemaAlignmentDialog.prototype.getJSON = function() {
var rootNodes = [];
for (var i = 0; i < this._nodeUIs.length; i++) {
var node = this._nodeUIs[i].getJSON();
if (node !== null) {
rootNodes.push(node);
}
}
return {
rootNodes: rootNodes
};
};
SchemaAlignmentDialog.prototype.preview = function() {
var self = this;
this._previewPanes.empty();
var protograph = this.getJSON();
$.post(
"/command/freebase-extension/preview-protograph?" + $.param({ project: theProject.id }),
{ protograph: JSON.stringify(protograph), engine: JSON.stringify(ui.browsingEngine.getJSON()) },
function(data) {
if ("mqllike" in data) {
$(self._previewPanes[0]).text(JSON.stringify(data.mqllike, null, 2));
}
if ("tripleloader" in data) {
$(self._previewPanes[1]).text(data.tripleloader);
}
},
"json"
);
};
SchemaAlignmentDialog._findColumn = function(cellIndex) {
var columns = theProject.columnModel.columns;
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
if (column.cellIndex == cellIndex) {
return column;
}
}
return null;
};