Still more work on the protograph, toward being able to build and save a protograph, but it's not working yet.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@89 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-02-11 06:44:48 +00:00
parent d227db0cc6
commit f5942773ec
21 changed files with 667 additions and 117 deletions

View File

@ -20,12 +20,13 @@ import com.metaweb.gridworks.commands.edit.CreateProjectCommand;
import com.metaweb.gridworks.commands.edit.DoTextTransformCommand; import com.metaweb.gridworks.commands.edit.DoTextTransformCommand;
import com.metaweb.gridworks.commands.edit.JoinMultiValueCellsCommand; import com.metaweb.gridworks.commands.edit.JoinMultiValueCellsCommand;
import com.metaweb.gridworks.commands.edit.RemoveColumnCommand; import com.metaweb.gridworks.commands.edit.RemoveColumnCommand;
import com.metaweb.gridworks.commands.edit.SaveProtographCommand;
import com.metaweb.gridworks.commands.edit.SplitMultiValueCellsCommand; import com.metaweb.gridworks.commands.edit.SplitMultiValueCellsCommand;
import com.metaweb.gridworks.commands.edit.UndoRedoCommand; import com.metaweb.gridworks.commands.edit.UndoRedoCommand;
import com.metaweb.gridworks.commands.info.ComputeFacetsCommand; import com.metaweb.gridworks.commands.info.ComputeFacetsCommand;
import com.metaweb.gridworks.commands.info.ExportRowsCommand; import com.metaweb.gridworks.commands.info.ExportRowsCommand;
import com.metaweb.gridworks.commands.info.GetAllProjectMetadataCommand; import com.metaweb.gridworks.commands.info.GetAllProjectMetadataCommand;
import com.metaweb.gridworks.commands.info.GetColumnModelCommand; import com.metaweb.gridworks.commands.info.GetModelsCommand;
import com.metaweb.gridworks.commands.info.GetHistoryCommand; import com.metaweb.gridworks.commands.info.GetHistoryCommand;
import com.metaweb.gridworks.commands.info.GetProcessesCommand; import com.metaweb.gridworks.commands.info.GetProcessesCommand;
import com.metaweb.gridworks.commands.info.GetProjectMetadataCommand; import com.metaweb.gridworks.commands.info.GetProjectMetadataCommand;
@ -50,7 +51,7 @@ public class GridworksServlet extends HttpServlet {
_commands.put("get-project-metadata", new GetProjectMetadataCommand()); _commands.put("get-project-metadata", new GetProjectMetadataCommand());
_commands.put("get-all-project-metadata", new GetAllProjectMetadataCommand()); _commands.put("get-all-project-metadata", new GetAllProjectMetadataCommand());
_commands.put("get-column-model", new GetColumnModelCommand()); _commands.put("get-models", new GetModelsCommand());
_commands.put("get-rows", new GetRowsCommand()); _commands.put("get-rows", new GetRowsCommand());
_commands.put("get-processes", new GetProcessesCommand()); _commands.put("get-processes", new GetProcessesCommand());
_commands.put("get-history", new GetHistoryCommand()); _commands.put("get-history", new GetHistoryCommand());
@ -70,6 +71,8 @@ public class GridworksServlet extends HttpServlet {
_commands.put("discard-reconcile", new DiscardReconcileCommand()); _commands.put("discard-reconcile", new DiscardReconcileCommand());
_commands.put("judge-one-cell", new JudgeOneCellCommand()); _commands.put("judge-one-cell", new JudgeOneCellCommand());
_commands.put("save-protograph", new SaveProtographCommand());
_commands.put("preview-expression", new PreviewExpressionCommand()); _commands.put("preview-expression", new PreviewExpressionCommand());
_commands.put("get-expression-language-info", new GetExpressionLanguageInfoCommand()); _commands.put("get-expression-language-info", new GetExpressionLanguageInfoCommand());
} }

View File

@ -0,0 +1,42 @@
package com.metaweb.gridworks.commands.edit;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.operations.SaveProtographOperation;
import com.metaweb.gridworks.process.Process;
import com.metaweb.gridworks.protograph.Protograph;
public class SaveProtographCommand extends Command {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Project project = getProject(request);
String jsonString = request.getParameter("protograph");
JSONObject json = jsonStringToObject(jsonString);
Protograph protograph = Protograph.reconstruct(json);
AbstractOperation op = new SaveProtographOperation(protograph);
Process process = op.createProcess(project, new Properties());
boolean done = project.processManager.queueProcess(process);
respond(response, "{ \"code\" : " + (done ? "\"ok\"" : "\"pending\"") + " }");
} catch (Exception e) {
respondException(response, e);
}
}
}

View File

@ -1,28 +0,0 @@
package com.metaweb.gridworks.commands.info;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.model.Project;
public class GetColumnModelCommand extends Command {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Project project = getProject(request);
try {
respondJSON(response, project.columnModel);
} catch (JSONException e) {
respondException(response, e);
}
}
}

View File

@ -0,0 +1,44 @@
package com.metaweb.gridworks.commands.info;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONWriter;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.model.Project;
public class GetModelsCommand extends Command {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Project project = getProject(request);
try {
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "application/json");
Properties options = new Properties();
JSONWriter writer = new JSONWriter(response.getWriter());
writer.object();
writer.key("columnModel"); project.columnModel.write(writer, options);
writer.key("protograph");
if (project.protograph == null) {
writer.value(null);
} else {
project.protograph.write(writer, options);
}
writer.endObject();
} catch (JSONException e) {
respondException(response, e);
}
}
}

View File

@ -11,6 +11,7 @@ import java.util.List;
import com.metaweb.gridworks.expr.ExpressionUtils; import com.metaweb.gridworks.expr.ExpressionUtils;
import com.metaweb.gridworks.history.History; import com.metaweb.gridworks.history.History;
import com.metaweb.gridworks.process.ProcessManager; import com.metaweb.gridworks.process.ProcessManager;
import com.metaweb.gridworks.protograph.Protograph;
public class Project implements Serializable { public class Project implements Serializable {
private static final long serialVersionUID = -5089046824819472570L; private static final long serialVersionUID = -5089046824819472570L;
@ -20,6 +21,7 @@ public class Project implements Serializable {
final public ColumnModel columnModel = new ColumnModel(); final public ColumnModel columnModel = new ColumnModel();
final public List<Row> rows = new ArrayList<Row>(); final public List<Row> rows = new ArrayList<Row>();
final public History history; final public History history;
public Protograph protograph;
transient public ProcessManager processManager; transient public ProcessManager processManager;

View File

@ -0,0 +1,69 @@
package com.metaweb.gridworks.model.operations;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONWriter;
import com.metaweb.gridworks.history.Change;
import com.metaweb.gridworks.history.HistoryEntry;
import com.metaweb.gridworks.model.AbstractOperation;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.process.Process;
import com.metaweb.gridworks.process.QuickHistoryEntryProcess;
import com.metaweb.gridworks.protograph.Protograph;
public class SaveProtographOperation implements AbstractOperation {
private static final long serialVersionUID = 3134524625206033285L;
final protected Protograph _protograph;
public SaveProtographOperation(
Protograph protograph
) {
_protograph = protograph;
}
public Process createProcess(Project project, Properties options)
throws Exception {
String description = "Save schema-alignment protograph";
Change change = new ProtographChange(_protograph);
HistoryEntry historyEntry = new HistoryEntry(
project, description, this, change);
return new QuickHistoryEntryProcess(project, historyEntry);
}
public void write(JSONWriter writer, Properties options)
throws JSONException {
// TODO Auto-generated method stub
}
static public class ProtographChange implements Change {
private static final long serialVersionUID = -564820111174473901L;
final protected Protograph _newProtograph;
protected Protograph _oldProtograph;
public ProtographChange(Protograph protograph) {
_newProtograph = protograph;
}
public void apply(Project project) {
synchronized (project) {
_oldProtograph = project.protograph;
project.protograph = _newProtograph;
}
}
public void revert(Project project) {
synchronized (project) {
project.protograph = _oldProtograph;
}
}
}
}

View File

@ -5,7 +5,7 @@ import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONWriter; import org.json.JSONWriter;
public class AnonymousNode extends Node { public class AnonymousNode implements Node {
private static final long serialVersionUID = -6956243664838720646L; private static final long serialVersionUID = -6956243664838720646L;
final public FreebaseType type; final public FreebaseType type;

View File

@ -0,0 +1,31 @@
package com.metaweb.gridworks.protograph;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONWriter;
public class CellKeyNode extends CellNode {
private static final long serialVersionUID = 1684854896739592911L;
final public FreebaseTopic namespace;
public CellKeyNode(
String columnName,
FreebaseTopic namespace
) {
super(columnName);
this.namespace = namespace;
}
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("nodeType"); writer.value("cell-as-key");
writer.key("columnName"); writer.value(columnName);
writer.key("namespace"); namespace.write(writer, options);
writer.endObject();
}
}

View File

@ -1,13 +1,13 @@
package com.metaweb.gridworks.protograph; package com.metaweb.gridworks.protograph;
abstract public class CellNode extends Node { abstract public class CellNode implements Node {
private static final long serialVersionUID = 5820786756175547307L; private static final long serialVersionUID = 5820786756175547307L;
final public int cellIndex; final public String columnName;
public CellNode( public CellNode(
int cellIndex String columnName
) { ) {
this.cellIndex = cellIndex; this.columnName = columnName;
} }
} }

View File

@ -1,22 +1,25 @@
package com.metaweb.gridworks.protograph; package com.metaweb.gridworks.protograph;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONWriter; import org.json.JSONWriter;
public class CellTopicNode extends CellNode { public class CellTopicNode extends CellNode implements NodeWithLinks {
private static final long serialVersionUID = 1684854896739592911L; private static final long serialVersionUID = 1684854896739592911L;
final public boolean createForNoReconMatch; final public boolean createForNoReconMatch;
final public FreebaseType type; final public FreebaseType type;
final public List<Link> links = new LinkedList<Link>();
public CellTopicNode( public CellTopicNode(
int cellIndex, String columnName,
boolean createForNoReconMatch, boolean createForNoReconMatch,
FreebaseType type FreebaseType type
) { ) {
super(cellIndex); super(columnName);
this.createForNoReconMatch = createForNoReconMatch; this.createForNoReconMatch = createForNoReconMatch;
this.type = type; this.type = type;
@ -27,9 +30,20 @@ public class CellTopicNode extends CellNode {
writer.object(); writer.object();
writer.key("nodeType"); writer.value("cell-as-topic"); writer.key("nodeType"); writer.value("cell-as-topic");
writer.key("cellIndex"); writer.value(cellIndex); writer.key("columnName"); writer.value(columnName);
writer.key("type"); type.write(writer, options); writer.key("type"); type.write(writer, options);
writer.key("createUnlessRecon"); writer.value(createForNoReconMatch); writer.key("createUnlessRecon"); writer.value(createForNoReconMatch);
writer.key("links"); writer.array();
for (Link link : links) {
link.write(writer, options);
}
writer.endArray();
writer.endObject(); writer.endObject();
} }
public void addLink(Link link) {
links.add(link);
}
} }

View File

@ -12,11 +12,11 @@ public class CellValueNode extends CellNode {
final public String lang; final public String lang;
public CellValueNode( public CellValueNode(
int cellIndex, String columnName,
String valueType, String valueType,
String lang String lang
) { ) {
super(cellIndex); super(columnName);
this.valueType = valueType; this.valueType = valueType;
this.lang = lang; this.lang = lang;
@ -27,7 +27,7 @@ public class CellValueNode extends CellNode {
writer.object(); writer.object();
writer.key("nodeType"); writer.value("cell-as-value"); writer.key("nodeType"); writer.value("cell-as-value");
writer.key("cellIndex"); writer.value(cellIndex); writer.key("columnName"); writer.value(columnName);
writer.key("valueType"); writer.value(valueType); writer.key("valueType"); writer.value(valueType);
writer.key("lang"); writer.value(lang); writer.key("lang"); writer.value(lang);
writer.endObject(); writer.endObject();

View File

@ -1,14 +1,17 @@
package com.metaweb.gridworks.protograph; package com.metaweb.gridworks.protograph;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONWriter; import org.json.JSONWriter;
public class FreebaseTopicNode extends Node { public class FreebaseTopicNode implements Node, NodeWithLinks {
private static final long serialVersionUID = 8418548867745587387L; private static final long serialVersionUID = 8418548867745587387L;
final public FreebaseTopic topic; final public FreebaseTopic topic;
final public List<Link> links = new LinkedList<Link>();
public FreebaseTopicNode(FreebaseTopic topic) { public FreebaseTopicNode(FreebaseTopic topic) {
this.topic = topic; this.topic = topic;
@ -20,6 +23,17 @@ public class FreebaseTopicNode extends Node {
writer.object(); writer.object();
writer.key("nodeType"); writer.value("topic"); writer.key("nodeType"); writer.value("topic");
writer.key("topic"); topic.write(writer, options); writer.key("topic"); topic.write(writer, options);
writer.key("links"); writer.array();
for (Link link : links) {
link.write(writer, options);
}
writer.endArray();
writer.endObject(); writer.endObject();
} }
public void addLink(Link link) {
links.add(link);
}
} }

View File

@ -4,7 +4,5 @@ import java.io.Serializable;
import com.metaweb.gridworks.Jsonizable; import com.metaweb.gridworks.Jsonizable;
abstract public class Node implements Serializable, Jsonizable { public interface Node extends Serializable, Jsonizable {
private static final long serialVersionUID = 2892833010059212143L;
} }

View File

@ -0,0 +1,5 @@
package com.metaweb.gridworks.protograph;
public interface NodeWithLinks {
public void addLink(Link link);
}

View File

@ -0,0 +1,132 @@
package com.metaweb.gridworks.protograph;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
public class Protograph implements Serializable, Jsonizable {
private static final long serialVersionUID = 706700643851582450L;
final protected List<Node> _rootNodes = new LinkedList<Node>();
static public Protograph reconstruct(JSONObject o) throws JSONException {
Protograph g = new Protograph();
JSONArray rootNodes = o.getJSONArray("rootNodes");
int count = rootNodes.length();
for (int i = 0; i < count; i++) {
JSONObject o2 = rootNodes.getJSONObject(i);
Node node = reconstructNode(o2);
if (node != null) {
g._rootNodes.add(node);
}
}
return g;
}
static protected Node reconstructNode(JSONObject o) throws JSONException {
Node node = null;
String nodeType = o.getString("nodeType");
if (nodeType.startsWith("cell-as-")) {
String columnName = o.getString("columnName");
if ("cell-as-topic".equals(nodeType)) {
node = new CellTopicNode(
columnName,
o.getBoolean("createForNoReconMatch"),
reconstructType(o.getJSONObject("type"))
);
} else if ("cell-as-value".equals(nodeType)) {
node = new CellValueNode(
columnName,
o.getString("valueType"),
o.getString("lang")
);
} else if ("cell-as-key".equals(nodeType)) {
node = new CellKeyNode(
columnName,
reconstructTopic(o.getJSONObject("namespace"))
);
}
} else if ("topic".equals(nodeType)) {
node = new FreebaseTopicNode(reconstructTopic(o.getJSONObject("topic")));
} else if ("value".equals(nodeType)) {
node = new ValueNode(
o.get("value"),
o.getString("valueType"),
o.getString("lang")
);
} else if ("anonymous".equals(nodeType)) {
node = new AnonymousNode(reconstructType(o.getJSONObject("type")));
}
if (node != null) {
if (node instanceof NodeWithLinks && o.has("links")) {
NodeWithLinks node2 = (NodeWithLinks) node;
JSONArray links = o.getJSONArray("links");
int linkCount = links.length();
for (int j = 0; j < linkCount; j++) {
JSONObject oLink = links.getJSONObject(j);
node2.addLink(new Link(
reconstructProperty(oLink.getJSONObject("property")),
reconstructNode(oLink.getJSONObject("target"))
));
}
}
}
return node;
}
static protected FreebaseProperty reconstructProperty(JSONObject o) throws JSONException {
return new FreebaseProperty(
o.getString("id"),
o.getString("name"),
reconstructType(o.getJSONObject("expected"))
);
}
static protected FreebaseType reconstructType(JSONObject o) throws JSONException {
return new FreebaseType(
o.getString("id"),
o.getString("name"),
o.getBoolean("cvt")
);
}
static protected FreebaseTopic reconstructTopic(JSONObject o) throws JSONException {
return new FreebaseTopic(
o.getString("id"),
o.getString("name")
);
}
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("rootNodes"); writer.array();
for (Node node : _rootNodes) {
node.write(writer, options);
}
writer.endArray();
writer.endObject();
}
}

View File

@ -5,7 +5,7 @@ import java.util.Properties;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONWriter; import org.json.JSONWriter;
public class ValueNode extends Node { public class ValueNode implements Node {
private static final long serialVersionUID = -5626883493437735688L; private static final long serialVersionUID = -5626883493437735688L;
final public Object value; final public Object value;

View File

@ -1,2 +1,2 @@
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Gridlock</title> <link type="text/css" rel="stylesheet" href="externals/suggest/css/suggest-1.0.3.min.css" /> <link type="text/css" rel="stylesheet" href="externals/jquery-ui/css/ui-lightness/jquery-ui-1.7.2.custom.css" /> <link rel="stylesheet" href="/styles/common.css" /> <link rel="stylesheet" href="/styles/menu.css" /> <link rel="stylesheet" href="/styles/dialog.css" /> <link rel="stylesheet" href="/styles/project.css" /> <link rel="stylesheet" href="/styles/data-table-view.css" /> <link rel="stylesheet" href="/styles/history.css" /> <link rel="stylesheet" href="/styles/browsing.css" /> <link rel="stylesheet" href="/styles/process.css" /> <link rel="stylesheet" href="/styles/menu-bar.css" /> <link rel="stylesheet" href="/styles/expression-preview-dialog.css" /> <link rel="stylesheet" href="/styles/schema-alignment-dialog.css" /> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Gridlock</title> <link type="text/css" rel="stylesheet" href="externals/suggest/css/suggest-1.0.3.min.css" /> <link type="text/css" rel="stylesheet" href="externals/jquery-ui/css/ui-lightness/jquery-ui-1.7.2.custom.css" /> <link rel="stylesheet" href="/styles/common.css" /> <link rel="stylesheet" href="/styles/menu.css" /> <link rel="stylesheet" href="/styles/dialog.css" /> <link rel="stylesheet" href="/styles/project.css" /> <link rel="stylesheet" href="/styles/data-table-view.css" /> <link rel="stylesheet" href="/styles/history.css" /> <link rel="stylesheet" href="/styles/browsing.css" /> <link rel="stylesheet" href="/styles/process.css" /> <link rel="stylesheet" href="/styles/menu-bar.css" /> <link rel="stylesheet" href="/styles/expression-preview-dialog.css" /> <link rel="stylesheet" href="/styles/schema-alignment-dialog.css" />
<script type="text/javascript" src="externals/jquery-1.4.1.min.js"></script> <script type="text/javascript" src="externals/suggest/suggest-1.0.3.min.js"></script> <script type="text/javascript" src="externals/jquery-ui/jquery-ui-1.7.2.custom.min.js"></script> <script type="text/javascript" src="scripts/util/misc.js"></script> <script type="text/javascript" src="scripts/util/url.js"></script> <script type="text/javascript" src="scripts/util/string.js"></script> <script type="text/javascript" src="scripts/util/ajax.js"></script> <script type="text/javascript" src="scripts/util/menu.js"></script> <script type="text/javascript" src="scripts/util/dialog.js"></script> <script type="text/javascript" src="scripts/project.js"></script> <script type="text/javascript" src="scripts/project/list-facet.js"></script> <script type="text/javascript" src="scripts/project/range-facet.js"></script> <script type="text/javascript" src="scripts/project/text-search-facet.js"></script> <script type="text/javascript" src="scripts/project/browsing-engine.js"></script> <script type="text/javascript" src="scripts/project/data-table-view.js"></script> <script type="text/javascript" src="scripts/project/data-table-cell-ui.js"></script> <script type="text/javascript" src="scripts/project/data-table-column-header-ui.js"></script> <script type="text/javascript" src="scripts/project/history-widget.js"></script> <script type="text/javascript" src="scripts/project/process-widget.js"></script> <script type="text/javascript" src="scripts/project/menu-bar.js"></script> <script type="text/javascript" src="scripts/project/recon-dialog.js"></script> <script type="text/javascript" src="scripts/project/expression-preview-dialog.js"></script> <script type="text/javascript" src="scripts/project/schema-alignment.js"></script> </head> <body> <div id="header"> <div id="path"><a class="app-path-section" href="./index.html">Gridworks</a> &raquo; </div> </div> <div id="body"> <div id="loading-message"><img src="images/large-spinner.gif" /> starting up ...</div> </div> </body> </html> <script type="text/javascript" src="externals/jquery-1.4.1.min.js"></script> <script type="text/javascript" src="externals/suggest/suggest-1.0.3.min.js"></script> <script type="text/javascript" src="externals/jquery-ui/jquery-ui-1.7.2.custom.min.js"></script> <script type="text/javascript" src="scripts/util/misc.js"></script> <script type="text/javascript" src="scripts/util/url.js"></script> <script type="text/javascript" src="scripts/util/string.js"></script> <script type="text/javascript" src="scripts/util/ajax.js"></script> <script type="text/javascript" src="scripts/util/menu.js"></script> <script type="text/javascript" src="scripts/util/dialog.js"></script> <script type="text/javascript" src="scripts/util/dom.js"></script> <script type="text/javascript" src="scripts/project.js"></script> <script type="text/javascript" src="scripts/project/list-facet.js"></script> <script type="text/javascript" src="scripts/project/range-facet.js"></script> <script type="text/javascript" src="scripts/project/text-search-facet.js"></script> <script type="text/javascript" src="scripts/project/browsing-engine.js"></script> <script type="text/javascript" src="scripts/project/data-table-view.js"></script> <script type="text/javascript" src="scripts/project/data-table-cell-ui.js"></script> <script type="text/javascript" src="scripts/project/data-table-column-header-ui.js"></script> <script type="text/javascript" src="scripts/project/history-widget.js"></script> <script type="text/javascript" src="scripts/project/process-widget.js"></script> <script type="text/javascript" src="scripts/project/menu-bar.js"></script> <script type="text/javascript" src="scripts/project/recon-dialog.js"></script> <script type="text/javascript" src="scripts/project/expression-preview-dialog.js"></script> <script type="text/javascript" src="scripts/project/schema-alignment.js"></script> </head> <body> <div id="header"> <div id="path"><a class="app-path-section" href="./index.html">Gridworks</a> &raquo; </div> </div> <div id="body"> <div id="loading-message"><img src="images/large-spinner.gif" /> starting up ...</div> </div> </body> </html>

View File

@ -50,9 +50,11 @@ function reinitializeProjectData(f) {
function(data) { function(data) {
theProject.metadata = data; theProject.metadata = data;
}, },
"/command/get-column-model?" + $.param({ project: theProject.id }), null, "/command/get-models?" + $.param({ project: theProject.id }), null,
function(data) { function(data) {
theProject.columnModel = data; theProject.columnModel = data.columnModel;
theProject.protograph = data.protograph;
for (var i = 0; i < theProject.columnModel.columns.length; i++) { for (var i = 0; i < theProject.columnModel.columns.length; i++) {
theProject.columnModel.columns[i].collapsed = false; theProject.columnModel.columns[i].collapsed = false;
} }

View File

@ -136,14 +136,18 @@ MenuBar.prototype._doExportRows = function() {
MenuBar.prototype._doAutoSchemaAlignment = function() { MenuBar.prototype._doAutoSchemaAlignment = function() {
//SchemaAlignment.autoAlign(); //SchemaAlignment.autoAlign();
new SchemaAlignmentDialog({
var protograph = theProject.protograph != null ? theProject.protograph : {
rootNodes: [ rootNodes: [
{ {
nodeType: "existing", nodeType: "cell-as-topic",
column: "name", links: [
linkages: [
] ]
} }
] ]
};
new SchemaAlignmentDialog(protograph, function(newProtograph) {
}); });
}; };

View File

@ -90,19 +90,11 @@ SchemaAlignment._cleanName = function(s) {
return s.replace(/\W/g, " ").replace(/\s+/g, " ").toLowerCase(); return s.replace(/\W/g, " ").replace(/\s+/g, " ").toLowerCase();
} }
function SchemaAlignmentDialog(protograph) { function SchemaAlignmentDialog(protograph, onDone) {
protograph = { this._onDone = onDone;
rootNodes: [
{
nodeType: "cell-as-topic",
links: [
]
}
]
};
this._originalProtograph = protograph; this._originalProtograph = protograph;
this._protograph = cloneDeep(protograph); this._protograph = cloneDeep(protograph); // this is what can be munched on
this._nodeUIs = [];
this._createDialog(); this._createDialog();
}; };
@ -127,8 +119,26 @@ SchemaAlignmentDialog.prototype._renderFooter = function(footer) {
var self = this; var self = this;
$('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() { $('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() {
var protograph = self.getJSON();
$.post(
"/command/save-protograph?" + $.param({ project: theProject.id }),
{ protograph: JSON.stringify(protograph) },
function(data) {
if (data.code == "error") {
alert("Failed to save protograph");
return;
} else if (data.code == "ok") {
ui.historyWidget.update();
} else {
ui.processWidget.update();
}
DialogSystem.dismissUntil(self._level - 1); DialogSystem.dismissUntil(self._level - 1);
self._onDone(self._getNewProtograph()); self._onDone(prototgraph);
},
"json"
);
}).appendTo(footer); }).appendTo(footer);
$('<button></button>').text("Cancel").click(function() { $('<button></button>').text("Cancel").click(function() {
@ -143,17 +153,31 @@ SchemaAlignmentDialog.prototype._renderBody = function(body) {
this._nodeTable = $('<table></table>').addClass("schema-alignment-table-layout").appendTo(this._canvas)[0]; this._nodeTable = $('<table></table>').addClass("schema-alignment-table-layout").appendTo(this._canvas)[0];
for (var i = 0; i < this._originalProtograph.rootNodes.length; i++) { for (var i = 0; i < this._originalProtograph.rootNodes.length; i++) {
new SchemaAlignmentDialog.UINode( this._nodeUIs.push(new SchemaAlignmentDialog.UINode(
this._protograph.rootNodes[i], this._protograph.rootNodes[i],
this._nodeTable, this._nodeTable,
{ {
expanded: true, expanded: true,
mustBeCellTopic: true mustBeCellTopic: true
} }
); ));
} }
}; };
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
};
};
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* UINode * UINode
*---------------------------------------------------------------------- *----------------------------------------------------------------------
@ -212,7 +236,10 @@ SchemaAlignmentDialog.UINode.prototype._renderMain = function() {
} }
}); });
if (this._node.nodeType == "cell-as-topic" || this._node.nodeType == "cell-as-value") { if (this._node.nodeType == "cell-as-topic" ||
this._node.nodeType == "cell-as-value" ||
this._node.nodeType == "cell-as-key") {
if ("cellIndex" in this._node) { if ("cellIndex" in this._node) {
a.html(" cell"); a.html(" cell");
@ -385,53 +412,115 @@ SchemaAlignmentDialog.UINode.prototype._showTagDialog = function() {
var body = $('<div></div>').addClass("dialog-body").appendTo(frame); var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame); var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
/* /*--------------------------------------------------
* Body * Body
*--------------------------------------------------
*/ */
var table = $('<table></table>') var html = $(
.attr("width", "100%") '<table>' +
.attr("cellspacing", "10") '<tr>' +
.attr("cellpadding", "0") '<td>' +
.appendTo(body)[0]; '<p><input type="radio" name="schema-align-node-dialog-node-type" value="cell-as" id="radioCellAs" /> Set to Cell in Column</p>' +
'<table>' +
'<tr>' +
'<td><div class="schema-alignment-node-dialog-column-list" id="divColumns"></div></td>' +
'<td>' +
'<p>The cell\'s content will be ...</p>' +
'<table>' +
'<tr>' +
'<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-topic" id="radioCellAsTopic" /></td>' +
'<td colspan="2">name of a topic (as reconciled)</td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>of Freebase type</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>create new topic if not reconciled</td>' +
'<td><input type="checkbox" /></td>' +
'</tr>' +
var tr0 = table.insertRow(0); '<tr>' +
var tr1 = table.insertRow(1); '<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-value" id="radioCellAsValue" /></td>' +
'<td colspan="2">a literal value</td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>of literal type</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>in language</td>' +
'<td><input /></td>' +
'</tr>' +
var tdTop = tr0.insertCell(0); '<tr>' +
var tdRightColumn = tr0.insertCell(1); '<td><input type="radio" name="schema-align-node-dialog-node-subtype" value="cell-as-key" id="radioCellAsKey" /></td>' +
var tdLeftColumn = tr1.insertCell(0); '<td colspan="2">a key in a namespace</td>' +
var tdMiddleColumn = tr1.insertCell(1); '</tr>' +
'<tr>' +
'<td></td>' +
'<td>in namespace</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>' +
'</td>' +
$(tdTop).attr("colspan", "2"); '<td>' +
$(tdRightColumn).attr("rowspan", "2"); '<p><input type="radio" name="schema-align-node-dialog-node-type" value="anonymous" id="radioAnonymous" /> Set to Anonymous Node</p>' +
'<table>' +
'<tr>' +
'<td></td>' +
'<td>of Freebase type</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
var makeNodeTypeChoice = function(label, value, checked, parent) { '<p><input type="radio" name="schema-align-node-dialog-node-type" value="topic" id="radioTopic" /> Set to Freebase Topic</p>' +
var heading = $('<h3></h3>').appendTo(parent); '<table>' +
'<tr>' +
'<td></td>' +
'<td>topic</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
var radio = $('<input />') '<p><input type="radio" name="schema-align-node-dialog-node-type" value="value" id="radioValue" /> Set to Literal Value</p>' +
.attr("type", "radio") '<table>' +
.attr("value", value) '<tr>' +
.attr("name", "schema-align-node-dialog-node-type") '<td></td>' +
.appendTo(heading); '<td>value</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>value type</td>' +
'<td><input /></td>' +
'</tr>' +
'<tr>' +
'<td></td>' +
'<td>lang</td>' +
'<td><input /></td>' +
'</tr>' +
'</table>' +
'</td>' +
'</tr>' +
'</table>'
).appendTo(body);
if (checked) { var elmtMap = DOM.bind(html, [ "divColumns" ]);
radio.attr("checked", "true");
}
$('<span></span>').text(label).appendTo(heading);
};
makeNodeTypeChoice("Set to Cell in Column", "cell-as-topic", this._node.nodeType == "cell-as-value" || this._node.nodeType == "cell-as-topic", tdTop);
var divColumns = $('<div></div>')
.addClass("schema-alignment-node-dialog-column-list")
.appendTo(tdLeftColumn);
var makeColumnChoice = function(column) { var makeColumnChoice = function(column) {
var div = $('<div></div>') var div = $('<div></div>')
.addClass("schema-alignment-node-dialog-column-choice") .addClass("schema-alignment-node-dialog-column-choice")
.appendTo(divColumns); .appendTo(elmtMap.divColumns);
var radio = $('<input />') var radio = $('<input />')
.attr("type", "radio") .attr("type", "radio")
@ -450,12 +539,10 @@ SchemaAlignmentDialog.UINode.prototype._showTagDialog = function() {
makeColumnChoice(columns[i]); makeColumnChoice(columns[i]);
} }
makeNodeTypeChoice("Set to Anonymous Node", "anonymous", this._node.nodeType == "anonymous", tdRightColumn);
makeNodeTypeChoice("Set to Freebase Topic", "topic", this._node.nodeType == "topic", tdRightColumn);
makeNodeTypeChoice("Set to Value", "value", this._node.nodeType == "value", tdRightColumn);
/* /*--------------------------------------------------
* Footer * Footer
*--------------------------------------------------
*/ */
$('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() { $('<button></button>').html("&nbsp;&nbsp;OK&nbsp;&nbsp;").click(function() {
@ -470,7 +557,86 @@ SchemaAlignmentDialog.UINode.prototype._showTagDialog = function() {
var level = DialogSystem.showDialog(frame); var level = DialogSystem.showDialog(frame);
}; };
SchemaAlignmentDialog.UINode.prototype.getJSON = function() {
var result = null;
var getLinks = false;
if (this._node.nodeType.match(/^cell-as-/)) {
if (!("columnName" in this._node) || this._node.columnName == null) {
return null;
}
if (this._node.nodeType == "cell-as-topic") {
result = {
nodeType: this._node.nodeType,
columnName: this._node.columnName,
type: "type" in this._node ? cloneNode(this._node.type) : { "id" : "/common/topic", "name" : "Topic", "cvt" : false },
createForNoReconMatch: "createForNoReconMatch" in this._node ? this._node.createForNoReconMatch : true
};
getLinks = true;
} else if (this._node.nodeType == "cell-as-value") {
result = {
nodeType: this._node.nodeType,
columnName: this._node.columnName,
valueType: "valueType" in this._node ? this._node.valueType : "/type/text",
lang: "lang" in this._node ? this._node.lang : "/lang/en"
};
} else if (this._node.nodeType == "cell-as-key") {
if (!("namespace" in this._node) || this._node.namespace == null) {
return null;
}
result = {
nodeType: this._node.nodeType,
columnName: this._node.columnName,
type: cloneNode(this._node.namespace)
};
}
} else if (this._node.nodeType == "topic") {
if (!("topic" in this._node) || this._node.topic == null) {
return null;
}
result = {
nodeType: this._node.nodeType,
topic: cloneNode(this._node.topic)
};
getLinks = true;
} else if (this._node.nodeType == "value") {
if (!("value" in this._node) || this._node.value == null) {
return null;
}
result = {
nodeType: this._node.nodeType,
value: this._node.value,
valueType: "valueType" in this._node ? this._node.valueType : "/type/text",
lang: "lang" in this._node ? this._node.lang : "/lang/en"
};
} else if (this._node.nodeType == "anonymous") {
if (!("type" in this._node) || this._node.type == null) {
return null;
}
result = {
nodeType: this._node.nodeType,
type: cloneNode(this._node.type)
};
getLinks = true;
}
if (result == null) {
return null;
}
if (getLinks) {
var links = [];
for (var i = 0; i < this._linkUIs.length; i++) {
var link = this._linkUIs[i].getJSON();
if (link != null) {
links.push(link);
}
}
result.links = links;
}
return result;
};
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* UILink * UILink
@ -570,3 +736,18 @@ SchemaAlignmentDialog.UILink.prototype._showTagSuggest = function(elmt) {
}); });
input[0].focus(); input[0].focus();
}; };
SchemaAlignmentDialog.UILink.prototype.getJSON = function() {
if ("property" in this._link && this._link.property != null &&
"target" in this._link && this._link.target != null) {
var targetJSON = this._targetUI.getJSON();
if (targetJSON != null) {
return {
property: cloneNode(this._link.property),
target: targetJSON
};
}
}
return null;
};

View File

@ -0,0 +1,37 @@
var DOM = {};
DOM.bind = function(elmt, fields) {
var map = {};
for (var i = 0; i < fields.length; i++) {
map[fields[i]] = null;
}
DOM._bindDOMChildren(elmt[0], map);
return map;
};
DOM._bindDOMElement = function(elmt, map) {
var id = elmt.id;
if (id != null && id.length > 0) {
if (id in map && map.hasOwnProperty(id)) {
map[id] = $(elmt);
elmt.removeAttribute("id");
}
}
if (elmt.hasChildNodes()) {
DOM._bindDOMChildren(elmt, map);
}
};
DOM._bindDOMChildren = function(elmt, map) {
var node = elmt.firstChild;
while (node != null) {
var node2 = node.nextSibling;
if (node.nodeType == 1) {
DOM._bindDOMElement(node, map);
}
node = node2;
}
};