Refactoring to expose extension points that the rdf-exporter extension will plug into.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@1074 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-07-06 00:14:07 +00:00
parent ab82562016
commit f5fc44e24e
15 changed files with 233 additions and 87 deletions

View File

@ -7,11 +7,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.mit.simile.butterfly.ButterflyModule;
import edu.mit.simile.butterfly.MountPoint;
public class ClientSideResourceManager {
final static Logger logger = LoggerFactory.getLogger("gridworks_clientSideResourceManager");
static public class ClientSideResourceBundle {
final protected Set<String> _pathSet = new HashSet<String>();
final protected List<String> _pathList = new ArrayList<String>();
@ -33,6 +38,10 @@ public class ClientSideResourceManager {
for (String path : paths) {
String fullPath = resolve(module, path);
if (fullPath == null) {
logger.error("Failed to add paths to unmounted module " + module.getName());
break;
}
if (!bundle._pathSet.contains(fullPath)) {
bundle._pathSet.add(fullPath);
bundle._pathList.add(fullPath);
@ -52,16 +61,21 @@ public class ClientSideResourceManager {
}
static protected String resolve(ButterflyModule module, String path) {
StringBuffer sb = new StringBuffer();
MountPoint mountPoint = module.getMountPoint();
boolean slashed = path.startsWith("/");
char[] mountPointChars = mountPoint.getMountPoint().toCharArray();
sb.append(mountPointChars, 0, slashed ? mountPointChars.length - 1 : mountPointChars.length);
sb.append(path);
return sb.toString();
if (mountPoint != null) {
String mountPointPath = mountPoint.getMountPoint();
if (mountPointPath != null) {
StringBuffer sb = new StringBuffer();
boolean slashed = path.startsWith("/");
char[] mountPointChars = mountPointPath.toCharArray();
sb.append(mountPointChars, 0, slashed ? mountPointChars.length - 1 : mountPointChars.length);
sb.append(path);
return sb.toString();
}
}
return null;
}
}

View File

@ -28,6 +28,8 @@ public class GridworksServlet extends Butterfly {
private static final String JAVAX_SERVLET_CONTEXT_TEMPDIR = "javax.servlet.context.tempdir";
static private GridworksServlet s_singleton;
static final private Map<String, Command> commands = new HashMap<String, Command>();
// timer for periodically saving projects
@ -112,7 +114,7 @@ public class GridworksServlet extends Butterfly {
{"mqlwrite", "com.metaweb.gridworks.commands.freebase.MQLWriteCommand"},
{"get-preference", "com.metaweb.gridworks.commands.GetPreferenceCommand"},
{"set-preference", "com.metaweb.gridworks.commands.SetPreferenceCommand"}
{"set-preference", "com.metaweb.gridworks.commands.SetPreferenceCommand"},
};
public static String getVersion() {
@ -138,6 +140,8 @@ public class GridworksServlet extends Butterfly {
@Override
public void init() throws ServletException {
super.init();
s_singleton = this;
logger.trace("> initialize");
@ -249,29 +253,39 @@ public class GridworksServlet extends Butterfly {
for (String[] command : commandNames) {
String commandName = command[0];
String className = command[1];
logger.debug("Loading command " + commandName + " class: " + className);
Command cmd;
try {
cmd = (Command) this.getClass().getClassLoader().loadClass(className).newInstance();
cmd.init(this);
} catch (InstantiationException e) {
logger.error("Failed to load command class " + className, e);
status = false;
continue;
} catch (IllegalAccessException e) {
logger.error("Failed to load command class " + className, e);
status = false;
continue;
} catch (ClassNotFoundException e) {
logger.error("Failed to load command class " + className, e);
status = false;
continue;
}
status |= registerCommand(commandName, cmd);
status |= registerOneCommand(commandName, className);
}
return status;
}
/**
* Register a single command given its class name.
*
* @param name
* command verb for command
* @param className
* class name of command class
* @return true if command was loaded and registered successfully
*/
protected boolean registerOneCommand(String commandName, String className) {
logger.debug("Loading command " + commandName + " class: " + className);
Command cmd;
try {
cmd = (Command) this.getClass().getClassLoader().loadClass(className).newInstance();
return registerOneCommand(commandName, cmd);
} catch (InstantiationException e) {
logger.error("Failed to load command class " + className, e);
return false;
} catch (IllegalAccessException e) {
logger.error("Failed to load command class " + className, e);
return false;
} catch (ClassNotFoundException e) {
logger.error("Failed to load command class " + className, e);
return false;
}
}
/**
* Register a single command.
*
@ -281,11 +295,14 @@ public class GridworksServlet extends Butterfly {
* object implementing the command
* @return true if command was loaded and registered successfully
*/
protected boolean registerCommand(String name, Command commandObject) {
protected boolean registerOneCommand(String name, Command commandObject) {
if (commands.containsKey(name)) {
return false;
}
commandObject.init(this);
commands.put(name, commandObject);
return true;
}
@ -293,5 +310,19 @@ public class GridworksServlet extends Butterfly {
protected boolean unregisterCommand(String verb) {
return commands.remove(verb) != null;
}
/**
* Register a single command. Used by extensions.
*
* @param name
* command verb for command
* @param commandObject
* object implementing the command
*
* @return true if command was loaded and registered successfully
*/
static public boolean registerCommand(String commandName, Command commandObject) {
return s_singleton.registerOneCommand(commandName, commandObject);
}
}

View File

@ -38,6 +38,10 @@ public class ExportRowsCommand extends Command {
s_formatToExporter.put("mqlwrite", new MqlwriteLikeExporter());
}
static public void registerExporter(String format, Exporter exporter) {
s_formatToExporter.put(format, exporter);
}
@SuppressWarnings("unchecked")
static public Properties getRequestParameters(HttpServletRequest request) {
Properties options = new Properties();

View File

@ -13,6 +13,7 @@ import org.json.JSONWriter;
import com.metaweb.gridworks.commands.Command;
import com.metaweb.gridworks.expr.MetaParser;
import com.metaweb.gridworks.expr.MetaParser.LanguageInfo;
import com.metaweb.gridworks.model.OverlayModel;
import com.metaweb.gridworks.model.Project;
public class GetModelsCommand extends Command {
@ -32,12 +33,17 @@ public class GetModelsCommand extends Command {
writer.object();
writer.key("columnModel"); project.columnModel.write(writer, options);
writer.key("recordModel"); project.recordModel.write(writer, options);
writer.key("protograph");
if (project.protograph == null) {
writer.value(null);
} else {
project.protograph.write(writer, options);
writer.key("overlayModels"); writer.object();
for (String modelName : project.overlayModels.keySet()) {
OverlayModel overlayModel = project.overlayModels.get(modelName);
if (overlayModel != null) {
writer.key(modelName);
project.overlayModels.get(modelName).write(writer, options);
}
}
writer.endObject();
writer.key("scripting"); writer.object();
for (String languagePrefix : MetaParser.getLanguagePrefixes()) {

View File

@ -36,12 +36,12 @@ abstract public class ProtographTransposeExporter implements Exporter {
public void export(Project project, Properties options, Engine engine,
Writer writer) throws IOException {
if (project.protograph != null) {
Protograph protograph = project.protograph;
Protograph protograph = (Protograph) project.overlayModels.get("freebaseProtograph");
if (protograph != null) {
TransposedNodeFactory nodeFactory = createNodeFactory(project, writer);
Transposer.transpose(project, engine.getAllFilteredRows(), protograph, protograph.getRootNode(0), nodeFactory, -1);
Transposer.transpose(project, engine.getAllFilteredRows(),
protograph, protograph.getRootNode(0), nodeFactory, -1);
nodeFactory.flush();
}

View File

@ -0,0 +1,13 @@
package com.metaweb.gridworks.expr;
import java.util.Properties;
import com.metaweb.gridworks.model.Cell;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public interface Binder {
public void initializeBindings(Properties bindings, Project project);
public void bind(Properties bindings, Row row, int rowIndex, String columnName, Cell cell);
}

View File

@ -4,14 +4,22 @@ import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import com.metaweb.gridworks.model.Cell;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.model.Row;
public class ExpressionUtils {
static protected Set<Binder> s_binders = new HashSet<Binder>();
static public void registerBinder(Binder binder) {
s_binders.add(binder);
}
static public Properties createBindings(Project project) {
Properties bindings = new Properties();
@ -20,6 +28,10 @@ public class ExpressionUtils {
bindings.put("project", project);
for (Binder binder : s_binders) {
binder.initializeBindings(bindings, project);
}
return bindings;
}
@ -45,6 +57,10 @@ public class ExpressionUtils {
bindings.put("value", cell.value);
}
}
for (Binder binder : s_binders) {
binder.bind(bindings, row, rowIndex, columnName, cell);
}
}
static public boolean isError(Object o) {

View File

@ -103,12 +103,12 @@ public class ControlFunctionRegistry {
return s_nameToControl.entrySet();
}
static protected void registerFunction(String name, Function f) {
static public void registerFunction(String name, Function f) {
s_nameToFunction.put(name, f);
s_functionToName.put(f, name);
}
static protected void registerControl(String name, Control c) {
static public void registerControl(String name, Control c) {
s_nameToControl.put(name, c);
s_controlToName.put(c, name);
}

View File

@ -0,0 +1,7 @@
package com.metaweb.gridworks.model;
import com.metaweb.gridworks.Jsonizable;
public interface OverlayModel extends Jsonizable {
}

View File

@ -5,11 +5,17 @@ import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,17 +25,30 @@ import com.metaweb.gridworks.ProjectMetadata;
import com.metaweb.gridworks.history.History;
import com.metaweb.gridworks.process.ProcessManager;
import com.metaweb.gridworks.protograph.Protograph;
import com.metaweb.gridworks.util.ParsingUtilities;
import com.metaweb.gridworks.util.Pool;
public class Project {
final public long id;
final public List<Row> rows = new ArrayList<Row>();
final public ColumnModel columnModel = new ColumnModel();
final public RecordModel recordModel = new RecordModel();
public Protograph protograph;
final public History history;
final static protected Map<String, Class<? extends OverlayModel>>
s_overlayModelClasses = new HashMap<String, Class<? extends OverlayModel>>();
static public void registerOverlayModel(String modelName, Class<? extends OverlayModel> klass) {
s_overlayModelClasses.put(modelName, klass);
}
static {
registerOverlayModel("freebaseProtograph", Protograph.class);
}
final public long id;
final public List<Row> rows = new ArrayList<Row>();
final public ColumnModel columnModel = new ColumnModel();
final public RecordModel recordModel = new RecordModel();
final public Map<String, OverlayModel> overlayModels = new HashMap<String, OverlayModel>();
final public History history;
transient public ProcessManager processManager = new ProcessManager();
transient private Date _lastSave = new Date();
@ -78,43 +97,58 @@ public class Project {
protected void saveToWriter(Writer writer, Properties options) throws IOException {
writer.write(GridworksServlet.getVersion()); writer.write('\n');
writer.write("columnModel=\n"); columnModel.save(writer, options);
writer.write("history=\n"); history.save(writer, options);
if (protograph != null) {
writer.write("protograph="); protograph.save(writer, options); writer.write('\n');
for (String modelName : overlayModels.keySet()) {
writer.write("overlayModel:");
writer.write(modelName);
writer.write("=");
try {
JSONWriter jsonWriter = new JSONWriter(writer);
overlayModels.get(modelName).write(jsonWriter, options);
} catch (JSONException e) {
e.printStackTrace();
}
writer.write('\n');
}
writer.write("rowCount="); writer.write(Integer.toString(rows.size())); writer.write('\n');
for (Row row : rows) {
row.save(writer, options); writer.write('\n');
}
}
static public Project loadFromReader(
LineNumberReader reader,
long id,
Pool pool
) throws Exception {
long start = System.currentTimeMillis();
/* String version = */ reader.readLine();
Project project = new Project(id);
int maxCellCount = 0;
String line;
while ((line = reader.readLine()) != null) {
int equal = line.indexOf('=');
CharSequence field = line.subSequence(0, equal);
String field = line.substring(0, equal);
String value = line.substring(equal + 1);
// backward compatibility
if ("protograph".equals(field)) {
field = "overlayModel:freebaseProtograph";
}
if ("columnModel".equals(field)) {
project.columnModel.load(reader);
} else if ("history".equals(field)) {
project.history.load(project, reader);
} else if ("protograph".equals(field)) {
project.protograph = Protograph.load(project, value);
} else if ("rowCount".equals(field)) {
int count = Integer.parseInt(value);
@ -126,6 +160,22 @@ public class Project {
maxCellCount = Math.max(maxCellCount, row.cells.size());
}
}
} else if (field.startsWith("overlayModel:")) {
String modelName = field.substring("overlayModel:".length());
if (s_overlayModelClasses.containsKey(modelName)) {
Class<? extends OverlayModel> klass = s_overlayModelClasses.get(modelName);
try {
Method loadMethod = klass.getMethod("load", Project.class, JSONObject.class);
JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(value);
OverlayModel overlayModel = (OverlayModel) loadMethod.invoke(null, project, obj);
project.overlayModels.put(modelName, overlayModel);
} catch (Exception e) {
logger.error("Failed to load overlay model " + modelName);
}
}
}
}

View File

@ -34,7 +34,7 @@ public abstract class OperationRegistry {
static final public Map<String, Class<? extends AbstractOperation>> s_opNameToClass = new HashMap<String, Class<? extends AbstractOperation>>();
static final public Map<Class<? extends AbstractOperation>, String> s_opClassToName = new HashMap<Class<? extends AbstractOperation>, String>();
static protected void register(String name, Class<? extends AbstractOperation> klass) {
static public void register(String name, Class<? extends AbstractOperation> klass) {
s_opNameToClass.put(name, klass);
s_opClassToName.put(klass, name);
}

View File

@ -52,7 +52,7 @@ public class SaveProtographOperation extends AbstractOperation {
return new HistoryEntry(historyEntryID, project, description, SaveProtographOperation.this, change);
}
static public class ProtographChange implements Change {
final protected Protograph _newProtograph;
protected Protograph _oldProtograph;
@ -63,14 +63,19 @@ public class SaveProtographOperation extends AbstractOperation {
public void apply(Project project) {
synchronized (project) {
_oldProtograph = project.protograph;
project.protograph = _newProtograph;
_oldProtograph = (Protograph) project.overlayModels.get("freebaseProtograph");
project.overlayModels.put("freebaseProtograph", _newProtograph);
}
}
public void revert(Project project) {
synchronized (project) {
project.protograph = _oldProtograph;
if (_oldProtograph == null) {
project.overlayModels.remove("freebaseProtograph");
} else {
project.overlayModels.put("freebaseProtograph", _oldProtograph);
}
}
}

View File

@ -1,6 +1,5 @@
package com.metaweb.gridworks.protograph;
import java.io.Writer;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
@ -10,11 +9,10 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.metaweb.gridworks.Jsonizable;
import com.metaweb.gridworks.model.OverlayModel;
import com.metaweb.gridworks.model.Project;
import com.metaweb.gridworks.util.ParsingUtilities;
public class Protograph implements Jsonizable {
public class Protograph implements OverlayModel {
final protected List<Node> _rootNodes = new LinkedList<Node>();
public int getRootNodeCount() {
@ -123,7 +121,7 @@ public class Protograph implements Jsonizable {
o.getString("name")
);
}
public void write(JSONWriter writer, Properties options) throws JSONException {
writer.object();
writer.key("rootNodes"); writer.array();
@ -135,19 +133,8 @@ public class Protograph implements Jsonizable {
writer.endArray();
writer.endObject();
}
public void save(Writer writer, Properties options) {
JSONWriter jsonWriter = new JSONWriter(writer);
try {
write(jsonWriter, options);
} catch (JSONException e) {
e.printStackTrace();
}
}
static public Protograph load(Project project, String s) throws Exception {
JSONObject obj = ParsingUtilities.evaluateJsonStringToObject(s);
static public Protograph load(Project project, JSONObject obj) throws Exception {
return reconstruct(obj);
}
}

View File

@ -177,7 +177,7 @@ SchemaAlignmentDialog.prototype._constructFooter = function(footer) {
{
onDone: function() {
DialogSystem.dismissUntil(self._level - 1);
theProject.protograph = protograph;
theProject.overlayModels.freebaseProtograph = protograph;
}
}
);

View File

@ -68,4 +68,17 @@ URL.looksLikeUrl = function(s) {
}
}
return false;
};
URL.getHostname = function(){
var url = location.href; // entire url including querystring - also: window.location.href;
var baseURL = url.substring(0, url.indexOf('/',7));//7 is the length of http://
return baseURL;
};
URL.urlify = function(str) {
if(!str) {
return '';
}
return escape(str.replace(/\W/g, '_'));
};