From 69906049814359e0520fd337543f235d6fbcddba Mon Sep 17 00:00:00 2001 From: Stefano Mazzocchi Date: Fri, 23 Apr 2010 08:25:52 +0000 Subject: [PATCH] implemented the full gridworks -> freebase conduit via delegated oauth and freeq/tripleloader (still doesn't work as argus returns a 500 but the entire conduit is in place) git-svn-id: http://google-refine.googlecode.com/svn/trunk@519 7d457c2a-affb-35e4-300a-418c747d4874 --- .classpath | 1 + LICENSE.txt | 3 - build.xml | 2 + gridworks | 13 +- lib-src/signpost-core-1.2.1.1-sources.jar | Bin 49305 -> 49334 bytes lib/signpost-core-1.2.1.1.jar | Bin 44558 -> 44603 bytes licenses/blockui.LICENSE.txt | 20 - src/conf/log4j.properties | 9 + .../metaweb/gridworks/GridworksServlet.java | 52 +- .../com/metaweb/gridworks/ProjectManager.java | 24 +- .../metaweb/gridworks/ProjectMetadata.java | 6 +- .../browsing/facets/ScatterplotFacet.java | 9 +- .../clustering/binning/BinningClusterer.java | 7 +- .../clustering/knn/kNNClusterer.java | 11 +- .../metaweb/gridworks/commands/Command.java | 59 ++- .../commands/auth/AuthorizationCommand.java | 33 -- .../commands/auth/AuthorizeCommand.java | 18 +- .../auth/CheckAuthorizationCommand.java | 49 +- .../commands/auth/DeAuthorizeCommand.java | 6 +- .../commands/edit/CreateProjectCommand.java | 14 +- .../commands/edit/ExportProjectCommand.java | 2 +- .../commands/edit/ImportProjectCommand.java | 7 +- .../commands/edit/UploadDataCommand.java | 51 ++ .../commands/info/ComputeClustersCommand.java | 7 +- .../commands/info/GetScatterplotCommand.java | 11 +- .../gridworks/expr/functions/ToDate.java | 9 +- .../gel/ControlFunctionRegistry.java | 2 +- .../gridworks/history/HistoryEntry.java | 2 +- .../com/metaweb/gridworks/model/Project.java | 15 +- .../model/changes/ColumnAdditionChange.java | 2 +- .../metaweb/gridworks/oauth/Credentials.java | 9 +- .../gridworks/oauth/OAuthUtilities.java | 32 +- .../gridworks/util/CookiesUtilities.java | 24 +- .../util/FreebaseDataExtensionJob.java | 2 +- .../metaweb/gridworks/util/FreebaseUtils.java | 115 +++++ .../webapp/WEB-INF/lib/slf4j-api-1.5.6.jar | Bin 0 -> 22338 bytes .../WEB-INF/lib/slf4j-log4j12-1.5.6.jar | Bin 0 -> 9678 bytes src/main/webapp/WEB-INF/log4j.properties | 8 - .../externals/blockui/jquery.blockui.js | 478 ------------------ src/main/webapp/project.html | 2 +- .../dialogs/freebase-loading-dialog.js | 116 +++-- src/main/webapp/scripts/util/sign.js | 44 +- .../dialogs/freebase-loading-dialog.css | 28 +- .../java/com/metaweb/gridworks/Gridworks.java | 55 +- 44 files changed, 551 insertions(+), 806 deletions(-) delete mode 100644 licenses/blockui.LICENSE.txt create mode 100644 src/conf/log4j.properties delete mode 100644 src/main/java/com/metaweb/gridworks/commands/auth/AuthorizationCommand.java create mode 100644 src/main/java/com/metaweb/gridworks/commands/edit/UploadDataCommand.java create mode 100644 src/main/java/com/metaweb/gridworks/util/FreebaseUtils.java create mode 100644 src/main/webapp/WEB-INF/lib/slf4j-api-1.5.6.jar create mode 100644 src/main/webapp/WEB-INF/lib/slf4j-log4j12-1.5.6.jar delete mode 100644 src/main/webapp/WEB-INF/log4j.properties delete mode 100644 src/main/webapp/externals/blockui/jquery.blockui.js diff --git a/.classpath b/.classpath index 9d7cfbbda..ecd53bded 100644 --- a/.classpath +++ b/.classpath @@ -7,6 +7,7 @@ + diff --git a/LICENSE.txt b/LICENSE.txt index 9bafe5d35..826ed2544 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -95,9 +95,6 @@ licenses/datejs.LICENSE.txt licenses/imgareaselect.LICENSE.txt imgareaselect - -licenses/blockui.LICENSE.txt - blockui licenses/slf4j.LICENSE.txt slf4j-api diff --git a/build.xml b/build.xml index 13653d455..cc40c960d 100644 --- a/build.xml +++ b/build.xml @@ -59,6 +59,7 @@ + @@ -68,6 +69,7 @@ + diff --git a/gridworks b/gridworks index 6da14e23c..3518d0d1d 100755 --- a/gridworks +++ b/gridworks @@ -46,6 +46,9 @@ where [options] include: -m max memory heap size to use default: 1024M + -v verbosity level [from low to high: error,warn,info,debug,trace] + default: info + --debug enable JVM debugging (on port 8000) --jmx enable JMX monitoring (for jconsole and jvisualvm) @@ -560,13 +563,13 @@ run() { if [ "$GRIDWORKS_DATA_DIR" ]; then add_option "-Dgridworks.data_dir=$GRIDWORKS_DATA_DIR" fi - + CLASSPATH="$GRIDWORKS_BUILD_DIR/classes${SEP}$GRIDWORKS_LIB_DIR/*" RUN_CMD="$JAVA -cp $CLASSPATH $OPTS com.metaweb.gridworks.Gridworks" #echo "$RUN_CMD" - #cd tooecho "" + #echo "" echo "Starting Gridworks at 'http://${GRIDWORKS_HOST}:${GRIDWORKS_PORT}/'" echo "" @@ -697,6 +700,7 @@ while [ $# -ne 0 ] ; do -w) shift; GRIDWORKS_WEBAPP="$1"; shift; continue;; -d) shift; GRIDWORKS_DATA_DIR="$1"; shift; continue;; -m) shift; GRIDWORKS_MEMORY="$1"; shift; continue;; + -v) shift; GRIDWORKS_VERBOSITY="$1"; shift; continue;; --debug) shift; add_option '-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n'; continue;; --jmx) shift; add_option '-Dcom.sun.management.jmxremote'; continue;; -*) fail "Invalid option: $1";; @@ -759,6 +763,11 @@ if [ -z "$GRIDWORKS_DIST_DIR" ]; then GRIDWORKS_DIST_DIR="dist" fi +if [ -z "$GRIDWORKS_VERBOSITY" ]; then + GRIDWORKS_VERBOSITY="info" +fi +add_option "-Dgridworks.verbosity=$GRIDWORKS_VERBOSITY" + if [ -z "$JYTHONPATH" ]; then JYTHONPATH="$GRIDWORKS_LIB_DIR/jython" else diff --git a/lib-src/signpost-core-1.2.1.1-sources.jar b/lib-src/signpost-core-1.2.1.1-sources.jar index 227a551740bde084aa0845745d80ff4d863dae26..3687dc989bb0921dcd180658f14af20b8d9fdc6c 100644 GIT binary patch delta 3935 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 n;MHzrXf>{FX=O diff --git a/lib/signpost-core-1.2.1.1.jar b/lib/signpost-core-1.2.1.1.jar index 7a75bd17699b6c02437c3cbe00101e97ed5ca3a3..e37a5e12fee7bde73a5bfb1e7f704d8a5f590413 100644 GIT binary patch delta 4260 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 lf*}1I;2Ks0@W`P7j<9qj*I)mW{|~mj5LEyG delta 4229 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 initialize"); ProjectManager.initialize(); @@ -156,10 +165,14 @@ public class GridworksServlet extends HttpServlet { ProjectManager.singleton.save(false); // quick, potentially incomplete save } }, period, period); + + logger.trace("< initialize"); } @Override public void destroy() { + logger.trace("> destroy"); + // cancel automatic periodic saving and force a complete save. if (_timer != null) { _timer.cancel(); @@ -171,34 +184,41 @@ public class GridworksServlet extends HttpServlet { } super.destroy(); - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - Command command = _commands.get(getCommandName(request)); - if (command != null) { - command.doPost(request, response); - } else { - response.sendError(404); - } + + logger.trace("< destroy"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - Command command = _commands.get(getCommandName(request)); + String commandName = getCommandName(request); + Command command = _commands.get(commandName); if (command != null) { + logger.trace("> GET {}", commandName); command.doGet(request, response); + logger.trace("< GET {}", commandName); } else { response.sendError(404); } } + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + String commandName = getCommandName(request); + Command command = _commands.get(commandName); + if (command != null) { + logger.trace("> POST {}", commandName); + command.doPost(request, response); + logger.trace("< POST {}", commandName); + } else { + response.sendError(404); + } + } + protected String getCommandName(HttpServletRequest request) { - /* - * Remove extraneous path segments that might be there for other purposes, - * e.g., for /export-rows/filename.ext, export-rows is the command while - * filename.ext is only for the browser to prompt a convenient filename. - */ + // Remove extraneous path segments that might be there for other purposes, + // e.g., for /export-rows/filename.ext, export-rows is the command while + // filename.ext is only for the browser to prompt a convenient filename. String commandName = request.getPathInfo().substring(1); int slash = commandName.indexOf('/'); return slash > 0 ? commandName.substring(0, slash) : commandName; } } + diff --git a/src/main/java/com/metaweb/gridworks/ProjectManager.java b/src/main/java/com/metaweb/gridworks/ProjectManager.java index b75601005..a64c63c82 100644 --- a/src/main/java/com/metaweb/gridworks/ProjectManager.java +++ b/src/main/java/com/metaweb/gridworks/ProjectManager.java @@ -19,6 +19,8 @@ import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.codeberry.jdatapath.DataPath; import com.codeberry.jdatapath.JDataPathSystem; @@ -34,6 +36,8 @@ public class ProjectManager { protected Map _projectsMetadata; protected List _expressions; + final static Logger logger = LoggerFactory.getLogger("project_manager"); + /** * While each project's metadata is loaded completely at start-up, each project's raw data * is loaded only when the project is accessed by the user. This is because project @@ -52,7 +56,7 @@ public class ProjectManager { static public synchronized void initialize() { if (singleton == null) { File dir = getProjectLocation(); - Gridworks.log("Using workspace directory: " + dir.getAbsolutePath()); + logger.info("Using workspace directory: {}", dir.getAbsolutePath()); singleton = new ProjectManager(dir); } @@ -83,9 +87,7 @@ public class ProjectManager { * environment variables and try our best to find a user-specific path. */ - Gridworks.log( - "Failed to use jdatapath to detect user data path. " + - "Resorting to environment variables."); + logger.warn("Failed to use jdatapath to detect user data path: resorting to environment variables"); File parentDir = null; { @@ -289,7 +291,7 @@ public class ProjectManager { } catch (Exception e) { e.printStackTrace(); - Gridworks.log("Failed to save workspace."); + logger.warn("Failed to save workspace"); return; } @@ -305,7 +307,7 @@ public class ProjectManager { oldFile.delete(); } - //Gridworks.log("Saved workspace."); + logger.info("Saved workspace"); } } @@ -397,7 +399,7 @@ public class ProjectManager { } }); - Gridworks.log(allModified ? + logger.info(allModified ? "Saving all modified projects ..." : "Saving some modified projects ..." ); @@ -456,7 +458,7 @@ public class ProjectManager { } protected boolean loadFromFile(File file) { - Gridworks.log("Loading workspace from " + file.getAbsolutePath()); + logger.info("Loading workspace: {}", file.getAbsolutePath()); _projectsMetadata.clear(); _expressions.clear(); @@ -482,14 +484,14 @@ public class ProjectManager { JSONUtilities.getStringList(obj, "expressions", _expressions); return true; } catch (JSONException e) { - Gridworks.warn("Error reading " + file, e); + logger.warn("Error reading file", e); } catch (IOException e) { - Gridworks.warn("Error reading " + file, e); + logger.warn("Error reading file", e); } finally { try { reader.close(); } catch (IOException e) { - Gridworks.warn("Exception closing file",e); + logger.warn("Exception closing file",e); } } } diff --git a/src/main/java/com/metaweb/gridworks/ProjectMetadata.java b/src/main/java/com/metaweb/gridworks/ProjectMetadata.java index ac9e03428..fb162dc57 100644 --- a/src/main/java/com/metaweb/gridworks/ProjectMetadata.java +++ b/src/main/java/com/metaweb/gridworks/ProjectMetadata.java @@ -14,6 +14,8 @@ import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.metaweb.gridworks.util.JSONUtilities; import com.metaweb.gridworks.util.ParsingUtilities; @@ -30,6 +32,8 @@ public class ProjectMetadata implements Jsonizable { private int _encodingConfidence; private List _expressions = new LinkedList(); + final Logger logger = LoggerFactory.getLogger("project_metadata"); + protected ProjectMetadata(Date date) { _created = date; } @@ -64,7 +68,7 @@ public class ProjectMetadata implements Jsonizable { } catch (Exception e) { e.printStackTrace(); - Gridworks.log("Failed to save project metadata"); + logger.warn("Failed to save project metadata"); return; } diff --git a/src/main/java/com/metaweb/gridworks/browsing/facets/ScatterplotFacet.java b/src/main/java/com/metaweb/gridworks/browsing/facets/ScatterplotFacet.java index 7a246e7a5..f0f4281cc 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/facets/ScatterplotFacet.java +++ b/src/main/java/com/metaweb/gridworks/browsing/facets/ScatterplotFacet.java @@ -14,8 +14,9 @@ import org.apache.commons.codec.binary.Base64; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.filters.DualExpressionsNumberComparisonRowFilter; import com.metaweb.gridworks.browsing.filters.RowFilter; @@ -109,6 +110,8 @@ public class ScatterplotFacet implements Facet { public static String EMPTY_IMAGE; + final static Logger logger = LoggerFactory.getLogger("scatterplot_facet"); + static { try { EMPTY_IMAGE = serializeImage(new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR)); @@ -302,7 +305,7 @@ public class ScatterplotFacet implements Facet { try { image = serializeImage(drawer.getImage()); } catch (IOException e) { - Gridworks.warn("Exception caught while generating the image", e); + logger.warn("Exception caught while generating the image", e); } } else { image = EMPTY_IMAGE; @@ -341,7 +344,7 @@ public class ScatterplotFacet implements Facet { try { eval = MetaParser.parse(expression); } catch (ParsingException e) { - Gridworks.warn("Error parsing expression",e); + logger.warn("Error parsing expression",e); } } NumericBinIndex index = (NumericBinIndex) column.getPrecompute(key); diff --git a/src/main/java/com/metaweb/gridworks/clustering/binning/BinningClusterer.java b/src/main/java/com/metaweb/gridworks/clustering/binning/BinningClusterer.java index 609bbc1c3..a73b6f570 100644 --- a/src/main/java/com/metaweb/gridworks/clustering/binning/BinningClusterer.java +++ b/src/main/java/com/metaweb/gridworks/clustering/binning/BinningClusterer.java @@ -14,8 +14,9 @@ import java.util.Map.Entry; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.RowVisitor; @@ -30,6 +31,8 @@ public class BinningClusterer extends Clusterer { static final protected Map _keyers = new HashMap(); + final static Logger logger = LoggerFactory.getLogger("binning_clusterer"); + List> _clusters; static { @@ -54,7 +57,7 @@ public class BinningClusterer extends Clusterer { if (k instanceof NGramFingerprintKeyer) { try { int size = _config.getJSONObject("params").getInt("ngram-size"); - Gridworks.log("Using ngram size: " + size); + logger.debug("Using ngram size: {}", size); _params = new Object[1]; _params[0] = size; } catch (JSONException e) { diff --git a/src/main/java/com/metaweb/gridworks/clustering/knn/kNNClusterer.java b/src/main/java/com/metaweb/gridworks/clustering/knn/kNNClusterer.java index 816e059c0..8db516e1a 100644 --- a/src/main/java/com/metaweb/gridworks/clustering/knn/kNNClusterer.java +++ b/src/main/java/com/metaweb/gridworks/clustering/knn/kNNClusterer.java @@ -15,8 +15,9 @@ import java.util.Map.Entry; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.RowVisitor; @@ -47,6 +48,8 @@ public class kNNClusterer extends Clusterer { Map _counts = new HashMap(); + final static Logger logger = LoggerFactory.getLogger("kNN_clusterer"); + static { _distances.put("levenshtein", new LevenshteinDistance()); _distances.put("jaccard", new JaccardDistance()); @@ -109,11 +112,11 @@ public class kNNClusterer extends Clusterer { try { JSONObject params = o.getJSONObject("params"); _radius = params.getDouble("radius"); - Gridworks.warn("Use radius: " + _radius); + logger.debug("Use radius: {}", _radius); _blockingNgramSize = params.getInt("blocking-ngram-size"); - Gridworks.warn("Use blocking ngram size: " + _blockingNgramSize); + logger.debug("Use blocking ngram size: {}",_blockingNgramSize); } catch (JSONException e) { - Gridworks.warn("No parameters found, using defaults"); + logger.debug("No parameters found, using defaults"); } _clusterer = new NGramClusterer(_distance, _blockingNgramSize); } diff --git a/src/main/java/com/metaweb/gridworks/commands/Command.java b/src/main/java/com/metaweb/gridworks/commands/Command.java index 9690c72ef..0bb44342a 100644 --- a/src/main/java/com/metaweb/gridworks/commands/Command.java +++ b/src/main/java/com/metaweb/gridworks/commands/Command.java @@ -14,6 +14,8 @@ import org.apache.commons.lang.NotImplementedException; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.metaweb.gridworks.Jsonizable; import com.metaweb.gridworks.ProjectManager; @@ -28,6 +30,9 @@ import com.metaweb.gridworks.util.ParsingUtilities; * are AJAX calls. */ public abstract class Command { + + final static protected Logger logger = LoggerFactory.getLogger("command"); + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -50,10 +55,7 @@ public abstract class Command { */ static protected JSONObject getEngineConfig(HttpServletRequest request) throws Exception { String json = request.getParameter("engine"); - if (json != null) { - return ParsingUtilities.evaluateJsonStringToObject(json); - } - return null; + return (json == null) ? null : ParsingUtilities.evaluateJsonStringToObject(json); } /** @@ -108,10 +110,9 @@ public abstract class Command { String value = request.getParameter(name); if (value != null) { try { - JSONObject o = ParsingUtilities.evaluateJsonStringToObject(value); - - return o; + return ParsingUtilities.evaluateJsonStringToObject(value); } catch (JSONException e) { + logger.warn("error getting json parameter",e); } } return null; @@ -123,15 +124,22 @@ public abstract class Command { Project project, Process process ) throws Exception { + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-Type", "application/json"); + HistoryEntry historyEntry = project.processManager.queueProcess(process); if (historyEntry != null) { - JSONWriter writer = new JSONWriter(response.getWriter()); + Writer w = response.getWriter(); + JSONWriter writer = new JSONWriter(w); Properties options = new Properties(); writer.object(); writer.key("code"); writer.value("ok"); writer.key("historyEntry"); historyEntry.write(writer, options); writer.endObject(); + + w.flush(); + w.close(); } else { respond(response, "{ \"code\" : \"pending\" }"); } @@ -140,8 +148,25 @@ public abstract class Command { static protected void respond(HttpServletResponse response, String content) throws IOException { + response.setCharacterEncoding("UTF-8"); response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().write(content); + Writer w = response.getWriter(); + w.write(content); + w.flush(); + w.close(); + } + + static protected void respond(HttpServletResponse response, String status, String message) + throws IOException, JSONException { + + Writer w = response.getWriter(); + JSONWriter writer = new JSONWriter(w); + writer.object(); + writer.key("status"); writer.value(status); + writer.key("message"); writer.value(message); + writer.endObject(); + w.flush(); + w.close(); } static protected void respondJSON(HttpServletResponse response, Jsonizable o) @@ -157,15 +182,19 @@ public abstract class Command { response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Type", "application/json"); - JSONWriter writer = new JSONWriter(response.getWriter()); + Writer w = response.getWriter(); + JSONWriter writer = new JSONWriter(w); o.write(writer, options); + w.flush(); + w.close(); } static protected void respondException(HttpServletResponse response, Exception e) throws IOException { - e.printStackTrace(); + logger.warn("Exception caught", e); + try { JSONObject o = new JSONObject(); o.put("code", "error"); @@ -179,6 +208,7 @@ public abstract class Command { o.put("stack", sw.toString()); + response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Type", "application/json"); respond(response, o.toString()); } catch (JSONException e1) { @@ -187,12 +217,7 @@ public abstract class Command { } static protected void redirect(HttpServletResponse response, String url) throws IOException { - response.setStatus(HttpServletResponse.SC_OK); - - Writer writer = response.getWriter(); - writer.write(""); - writer.write(""); - writer.write(""); + response.sendRedirect(url); } } diff --git a/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizationCommand.java b/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizationCommand.java deleted file mode 100644 index 160d8e662..000000000 --- a/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizationCommand.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.metaweb.gridworks.commands.auth; - -import java.io.IOException; - -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.oauth.OAuthUtilities; -import com.metaweb.gridworks.oauth.Provider; - -public class AuthorizationCommand extends Command { - - private static final String PROVIDER_PARAM = "provider"; - - protected void respond(HttpServletResponse response, String status, String message) throws IOException, JSONException { - JSONWriter writer = new JSONWriter(response.getWriter()); - writer.object(); - writer.key("status"); writer.value(status); - writer.key("message"); writer.value(message); - writer.endObject(); - } - - protected Provider getProvider(HttpServletRequest request) { - String provider_str = request.getParameter(PROVIDER_PARAM); - Provider provider = OAuthUtilities.getProvider(request.getParameter(PROVIDER_PARAM)); - if (provider == null) throw new RuntimeException("Can't find OAuth provider '" + provider_str + "'"); - return provider; - } -} diff --git a/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizeCommand.java b/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizeCommand.java index ea8183c58..b31941fa1 100644 --- a/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizeCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/auth/AuthorizeCommand.java @@ -11,26 +11,28 @@ import oauth.signpost.OAuthConsumer; import oauth.signpost.OAuthProvider; import com.metaweb.gridworks.Gridworks; +import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.oauth.Credentials; import com.metaweb.gridworks.oauth.OAuthUtilities; import com.metaweb.gridworks.oauth.Provider; -public class AuthorizeCommand extends AuthorizationCommand { +public class AuthorizeCommand extends Command { private static final String OAUTH_VERIFIER_PARAM = "oauth_verifier"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // get the provider from the request + Provider provider = OAuthUtilities.getProvider(request); + try { - // get the provider from the request - Provider provider = getProvider(request); - // see if the request comes with access credentials Credentials access_credentials = Credentials.getCredentials(request, provider, Credentials.Type.ACCESS); // prepare the continuation URL that the OAuth provider will redirect the user to // (we need to make sure this URL points back to this code or the dance will never complete) - String callbackURL = Gridworks.getURL() + "/command/authorize"; + String callbackURL = Gridworks.getURL() + "/command/authorize/" + provider.getHost(); if (access_credentials == null) { // access credentials are not available so we need to check @@ -39,7 +41,7 @@ public class AuthorizeCommand extends AuthorizationCommand { // get the request token credentials Credentials request_credentials = Credentials.getCredentials(request, provider, Credentials.Type.REQUEST); - OAuthConsumer consumer = OAuthUtilities.getConsumer(provider); + OAuthConsumer consumer = OAuthUtilities.getConsumer(request_credentials, provider); OAuthProvider pp = OAuthUtilities.getOAuthProvider(provider); if (request_credentials == null) { @@ -70,7 +72,7 @@ public class AuthorizeCommand extends AuthorizationCommand { String verificationCode = request.getParameter(OAUTH_VERIFIER_PARAM); pp.retrieveAccessToken(consumer, verificationCode); - + access_credentials = new Credentials(consumer.getToken(), consumer.getTokenSecret(), provider); // no matter the result, we need to remove the request token @@ -95,6 +97,8 @@ public class AuthorizeCommand extends AuthorizationCommand { finish(response); } } catch (Exception e) { + Credentials.deleteCredentials(request, response, provider, Credentials.Type.REQUEST); + Credentials.deleteCredentials(request, response, provider, Credentials.Type.ACCESS); respondException(response, e); } } diff --git a/src/main/java/com/metaweb/gridworks/commands/auth/CheckAuthorizationCommand.java b/src/main/java/com/metaweb/gridworks/commands/auth/CheckAuthorizationCommand.java index 19deaa372..9c79e7035 100644 --- a/src/main/java/com/metaweb/gridworks/commands/auth/CheckAuthorizationCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/auth/CheckAuthorizationCommand.java @@ -1,34 +1,28 @@ package com.metaweb.gridworks.commands.auth; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import oauth.signpost.OAuthConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.CoreProtocolPNames; - -import com.metaweb.gridworks.Gridworks; +import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.oauth.Credentials; import com.metaweb.gridworks.oauth.OAuthUtilities; import com.metaweb.gridworks.oauth.Provider; -import com.metaweb.gridworks.util.IOUtils; +import com.metaweb.gridworks.util.FreebaseUtils; -public class CheckAuthorizationCommand extends AuthorizationCommand { +public class CheckAuthorizationCommand extends Command { + + final static Logger logger = LoggerFactory.getLogger("check-authorization_command"); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { - - Provider provider = getProvider(request); + Provider provider = OAuthUtilities.getProvider(request); // this cookie should not be there, but this is good hygiene practice Credentials.deleteCredentials(request, response, provider, Credentials.Type.REQUEST); @@ -39,30 +33,15 @@ public class CheckAuthorizationCommand extends AuthorizationCommand { response.setHeader("Content-Type", "application/json"); if (access_credentials != null) { - Gridworks.log(access_credentials.toString()); - - OAuthConsumer consumer = OAuthUtilities.getConsumer(access_credentials, provider); - - HttpGet httpRequest = new HttpGet("http://" + provider.getHost() + "/api/service/user_info"); - httpRequest.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Gridworks " + Gridworks.getVersion()); - - // this is required by the Metaweb API to avoid XSS - httpRequest.setHeader("X-Requested-With", "1"); - - consumer.sign(request); - - HttpClient httpClient = new DefaultHttpClient(); - HttpResponse httpResponse = httpClient.execute(httpRequest); - OutputStream output = response.getOutputStream(); - InputStream input = httpResponse.getEntity().getContent(); - IOUtils.copy(input, output); - input.close(); - output.close(); + String user_info = FreebaseUtils.getUserInfo(access_credentials, provider); + response.getWriter().write(user_info); + } else { + respond(response, "401 Unauthorized", "You don't have the right credentials"); } - - respond(response, "401 Unauthorized", "You don't have the right credentials"); } catch (Exception e) { + logger.info("error",e); respondException(response, e); } } + } diff --git a/src/main/java/com/metaweb/gridworks/commands/auth/DeAuthorizeCommand.java b/src/main/java/com/metaweb/gridworks/commands/auth/DeAuthorizeCommand.java index 2678a83b3..ac9b917a5 100644 --- a/src/main/java/com/metaweb/gridworks/commands/auth/DeAuthorizeCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/auth/DeAuthorizeCommand.java @@ -6,10 +6,12 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.metaweb.gridworks.commands.Command; import com.metaweb.gridworks.oauth.Credentials; +import com.metaweb.gridworks.oauth.OAuthUtilities; import com.metaweb.gridworks.oauth.Provider; -public class DeAuthorizeCommand extends AuthorizationCommand { +public class DeAuthorizeCommand extends Command { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -17,7 +19,7 @@ public class DeAuthorizeCommand extends AuthorizationCommand { response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Type", "application/json"); - Provider provider = getProvider(request); + Provider provider = OAuthUtilities.getProvider(request); Credentials.deleteCredentials(request, response, provider, Credentials.Type.ACCESS); diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/CreateProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/CreateProjectCommand.java index d4359cad9..182c2088f 100644 --- a/src/main/java/com/metaweb/gridworks/commands/edit/CreateProjectCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/edit/CreateProjectCommand.java @@ -36,6 +36,8 @@ import org.apache.commons.fileupload.util.Streams; import org.apache.tools.bzip2.CBZip2InputStream; import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.ibm.icu.text.CharsetDetector; import com.ibm.icu.text.CharsetMatch; @@ -54,6 +56,8 @@ import com.metaweb.gridworks.util.ParsingUtilities; public class CreateProjectCommand extends Command { + final static Logger logger = LoggerFactory.getLogger("create-project_command"); + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -164,7 +168,7 @@ public class CreateProjectCommand extends Command { InputStream inputStream ) throws Exception { - Gridworks.info("Importing " + fileName + ""); + logger.info("Importing '{}'", fileName); if (fileName.endsWith(".zip") || fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz") || fileName.endsWith(".tar.bz2")) { @@ -236,7 +240,8 @@ public class CreateProjectCommand extends Command { } } } - Gridworks.log("Most frequent extensions: " + exts.toString()); + + logger.info("Most frequent extensions: {}", exts.toString()); // second pass, load the data for real is = getStream(fileName, new FileInputStream(file)); @@ -399,10 +404,7 @@ public class CreateProjectCommand extends Command { options.setProperty("encoding", charsetMatch.getName()); options.setProperty("encoding_confidence", Integer.toString(charsetMatch.getConfidence())); - Gridworks.log( - "Best encoding guess: " + - charsetMatch.getName() + - " [confidence: " + charsetMatch.getConfidence() + "]"); + logger.info("Best encoding guess: {} [confidence: {}]", charsetMatch.getName(), charsetMatch.getConfidence()); break; } catch (UnsupportedEncodingException e) { diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java index 641547e30..ead87d61d 100644 --- a/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/edit/ExportProjectCommand.java @@ -1,6 +1,6 @@ package com.metaweb.gridworks.commands.edit; -import java.io.File; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java index 450e372cb..3f6d22078 100644 --- a/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/edit/ImportProjectCommand.java @@ -19,8 +19,9 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.util.Streams; import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.ProjectManager; import com.metaweb.gridworks.ProjectMetadata; import com.metaweb.gridworks.commands.Command; @@ -29,6 +30,8 @@ import com.metaweb.gridworks.util.ParsingUtilities; public class ImportProjectCommand extends Command { + final static Logger logger = LoggerFactory.getLogger("import-project_command"); + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -37,7 +40,7 @@ public class ImportProjectCommand extends Command { Properties options = ParsingUtilities.parseUrlParameters(request); long projectID = Project.generateID(); - Gridworks.log("Importing existing project using new ID " + projectID); + logger.info("Importing existing project using new ID {}", projectID); internalImport(request, options, projectID); diff --git a/src/main/java/com/metaweb/gridworks/commands/edit/UploadDataCommand.java b/src/main/java/com/metaweb/gridworks/commands/edit/UploadDataCommand.java new file mode 100644 index 000000000..a2ffef5cf --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/commands/edit/UploadDataCommand.java @@ -0,0 +1,51 @@ +package com.metaweb.gridworks.commands.edit; + +import java.io.IOException; +import java.io.StringWriter; +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.JSONObject; + +import com.metaweb.gridworks.browsing.Engine; +import com.metaweb.gridworks.commands.Command; +import com.metaweb.gridworks.exporters.TripleloaderExporter; +import com.metaweb.gridworks.model.Project; +import com.metaweb.gridworks.util.FreebaseUtils; + +public class UploadDataCommand extends Command { + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + try { + Project project = getProject(request); + Engine engine = getEngine(request, project); + TripleloaderExporter exporter = new TripleloaderExporter(); + StringWriter triples = new StringWriter(1024 * 10); + exporter.export(project, new Properties(), engine, triples); + + String info = request.getParameter("info"); + + String result = FreebaseUtils.uploadTriples(request, info, triples.toString()); + + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-Type", "application/json"); + + try { + new JSONObject(result); + response.getWriter().write(result); + } catch (JSONException e) { + respond(response,"500 Error", result); + } + + } catch (Exception e) { + respondException(response, e); + } + } +} diff --git a/src/main/java/com/metaweb/gridworks/commands/info/ComputeClustersCommand.java b/src/main/java/com/metaweb/gridworks/commands/info/ComputeClustersCommand.java index ff0513f5b..79ce2540b 100644 --- a/src/main/java/com/metaweb/gridworks/commands/info/ComputeClustersCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/info/ComputeClustersCommand.java @@ -7,8 +7,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.clustering.Clusterer; import com.metaweb.gridworks.clustering.binning.BinningClusterer; @@ -18,6 +19,8 @@ import com.metaweb.gridworks.model.Project; public class ComputeClustersCommand extends Command { + final static Logger logger = LoggerFactory.getLogger("compute-clusters_command"); + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -42,7 +45,7 @@ public class ComputeClustersCommand extends Command { clusterer.computeClusters(engine); respondJSON(response, clusterer); - Gridworks.log("computed clusters [" + type + "," + clusterer_conf.getString("function") + "] in " + (System.currentTimeMillis() - start) + "ms"); + logger.info("computed clusters [{},{}] in {}ms", new Object[] { type, clusterer_conf.getString("function"), Long.toString(System.currentTimeMillis() - start) }); } catch (Exception e) { respondException(response, e); } diff --git a/src/main/java/com/metaweb/gridworks/commands/info/GetScatterplotCommand.java b/src/main/java/com/metaweb/gridworks/commands/info/GetScatterplotCommand.java index 72ed4a5a6..c8c7e6e4f 100644 --- a/src/main/java/com/metaweb/gridworks/commands/info/GetScatterplotCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/info/GetScatterplotCommand.java @@ -13,8 +13,9 @@ import javax.servlet.http.HttpServletResponse; import org.json.JSONException; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.browsing.Engine; import com.metaweb.gridworks.browsing.FilteredRows; import com.metaweb.gridworks.browsing.facets.NumericBinIndex; @@ -29,6 +30,8 @@ import com.metaweb.gridworks.model.Project; public class GetScatterplotCommand extends Command { + final static Logger logger = LoggerFactory.getLogger("get-scatterplot_command"); + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { @@ -50,7 +53,7 @@ public class GetScatterplotCommand extends Command { sos.close(); } - Gridworks.log("Drawn scatterplot in " + (System.currentTimeMillis() - start) + "ms"); + logger.info("Drawn scatterplot in {} ms", Long.toString(System.currentTimeMillis() - start)); } catch (Exception e) { e.printStackTrace(); respondException(response, e); @@ -97,7 +100,7 @@ public class GetScatterplotCommand extends Command { try { eval_x = MetaParser.parse(expression_x); } catch (ParsingException e) { - Gridworks.warn("error parsing expression", e); + logger.warn("error parsing expression", e); } String columnName_y = o.getString(ScatterplotFacet.Y_COLUMN_NAME); @@ -115,7 +118,7 @@ public class GetScatterplotCommand extends Command { try { eval_y = MetaParser.parse(expression_y); } catch (ParsingException e) { - Gridworks.warn("error parsing expression", e); + logger.warn("error parsing expression", e); } NumericBinIndex index_x = null; diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/ToDate.java b/src/main/java/com/metaweb/gridworks/expr/functions/ToDate.java index 3c5fbad81..b6374563e 100644 --- a/src/main/java/com/metaweb/gridworks/expr/functions/ToDate.java +++ b/src/main/java/com/metaweb/gridworks/expr/functions/ToDate.java @@ -1,13 +1,12 @@ package com.metaweb.gridworks.expr.functions; -import java.util.Properties; - -import org.json.JSONException; -import org.json.JSONWriter; - import java.text.SimpleDateFormat; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Properties; + +import org.json.JSONException; +import org.json.JSONWriter; import com.metaweb.gridworks.expr.util.CalendarParser; import com.metaweb.gridworks.expr.util.CalendarParserException; diff --git a/src/main/java/com/metaweb/gridworks/gel/ControlFunctionRegistry.java b/src/main/java/com/metaweb/gridworks/gel/ControlFunctionRegistry.java index 5fe76f2b2..66189814e 100644 --- a/src/main/java/com/metaweb/gridworks/gel/ControlFunctionRegistry.java +++ b/src/main/java/com/metaweb/gridworks/gel/ControlFunctionRegistry.java @@ -34,7 +34,6 @@ import com.metaweb.gridworks.expr.functions.math.Pow; import com.metaweb.gridworks.expr.functions.math.Round; import com.metaweb.gridworks.expr.functions.math.Sum; import com.metaweb.gridworks.expr.functions.strings.Contains; -import com.metaweb.gridworks.expr.functions.strings.SplitByLengths; import com.metaweb.gridworks.expr.functions.strings.Diff; import com.metaweb.gridworks.expr.functions.strings.EndsWith; import com.metaweb.gridworks.expr.functions.strings.Fingerprint; @@ -51,6 +50,7 @@ import com.metaweb.gridworks.expr.functions.strings.ReplaceChars; import com.metaweb.gridworks.expr.functions.strings.SHA1; import com.metaweb.gridworks.expr.functions.strings.Split; import com.metaweb.gridworks.expr.functions.strings.SplitByCharType; +import com.metaweb.gridworks.expr.functions.strings.SplitByLengths; import com.metaweb.gridworks.expr.functions.strings.StartsWith; import com.metaweb.gridworks.expr.functions.strings.ToLowercase; import com.metaweb.gridworks.expr.functions.strings.ToTitlecase; diff --git a/src/main/java/com/metaweb/gridworks/history/HistoryEntry.java b/src/main/java/com/metaweb/gridworks/history/HistoryEntry.java index 2df3f5dd4..80c9ece93 100644 --- a/src/main/java/com/metaweb/gridworks/history/HistoryEntry.java +++ b/src/main/java/com/metaweb/gridworks/history/HistoryEntry.java @@ -1,6 +1,6 @@ package com.metaweb.gridworks.history; -import java.io.File; +import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; diff --git a/src/main/java/com/metaweb/gridworks/model/Project.java b/src/main/java/com/metaweb/gridworks/model/Project.java index c60633a91..0be0c8eb4 100644 --- a/src/main/java/com/metaweb/gridworks/model/Project.java +++ b/src/main/java/com/metaweb/gridworks/model/Project.java @@ -20,6 +20,9 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.metaweb.gridworks.Gridworks; import com.metaweb.gridworks.ProjectManager; import com.metaweb.gridworks.ProjectMetadata; @@ -40,6 +43,8 @@ public class Project { transient public ProcessManager processManager = new ProcessManager(); transient public Date lastSave = new Date(); + final static Logger logger = LoggerFactory.getLogger("project"); + static public long generateID() { return System.currentTimeMillis() + Math.round(Math.random() * 1000000000000L); } @@ -68,7 +73,7 @@ public class Project { } catch (Exception e) { e.printStackTrace(); - Gridworks.log("Failed to save project " + id); + logger.warn("Failed to save project {}", id); return; } @@ -86,7 +91,7 @@ public class Project { lastSave = new Date(); - Gridworks.log("Saved project " + id + "."); + logger.info("Saved project '{}'",id); } } @@ -213,10 +218,8 @@ public class Project { project.columnModel.setMaxCellIndex(maxCellCount - 1); - Gridworks.log( - "Loaded project " + id + " from disk in " + - (System.currentTimeMillis() - start) / 1000 + - " sec(s)" + logger.info( + "Loaded project {} from disk in {} sec(s)",id,Long.toString((System.currentTimeMillis() - start) / 1000) ); project.recomputeRowContextDependencies(); diff --git a/src/main/java/com/metaweb/gridworks/model/changes/ColumnAdditionChange.java b/src/main/java/com/metaweb/gridworks/model/changes/ColumnAdditionChange.java index 5142d5f81..66871f2db 100644 --- a/src/main/java/com/metaweb/gridworks/model/changes/ColumnAdditionChange.java +++ b/src/main/java/com/metaweb/gridworks/model/changes/ColumnAdditionChange.java @@ -1,6 +1,6 @@ package com.metaweb.gridworks.model.changes; -import java.io.IOException; +import java.io.IOException; import java.io.LineNumberReader; import java.io.Writer; import java.util.ArrayList; diff --git a/src/main/java/com/metaweb/gridworks/oauth/Credentials.java b/src/main/java/com/metaweb/gridworks/oauth/Credentials.java index ca27e42f2..9d65cb54b 100644 --- a/src/main/java/com/metaweb/gridworks/oauth/Credentials.java +++ b/src/main/java/com/metaweb/gridworks/oauth/Credentials.java @@ -25,6 +25,7 @@ public class Credentials { } public String getCookieName(Provider provider) { + if (provider == null) throw new RuntimeException("Provider can't be null"); return provider.getHost() + "_" + postfix; } }; @@ -36,10 +37,8 @@ public class Credentials { public static void setCredentials(HttpServletResponse response, Credentials credentials, Type type, int max_age) { String name = type.getCookieName(credentials.getProvider()); - Cookie c = new Cookie(name, credentials.toString()); - c.setPath("/"); - c.setMaxAge(max_age); - response.addCookie(c); + String value = credentials.toString(); + CookiesUtilities.setCookie(response, name, value, max_age); } public static void deleteCredentials(HttpServletRequest request, HttpServletResponse response, Provider provider, Type type) { @@ -60,6 +59,8 @@ public class Credentials { if (token == null) throw new RuntimeException("Could not find " + TOKEN + " in auth credentials"); this.secret = secret; if (secret == null) throw new RuntimeException("Could not find " + SECRET + " in auth credentials"); + this.provider = provider; + if (provider == null) throw new RuntimeException("Provider can't be null"); } public String getToken() { diff --git a/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java b/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java index 4f0c50714..64cade03b 100644 --- a/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java +++ b/src/main/java/com/metaweb/gridworks/oauth/OAuthUtilities.java @@ -3,10 +3,15 @@ package com.metaweb.gridworks.oauth; import java.util.HashMap; import java.util.Map; +import javax.servlet.http.HttpServletRequest; + import oauth.signpost.OAuthConsumer; import oauth.signpost.OAuthProvider; import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import oauth.signpost.commonshttp.CommonsHttpOAuthProvider; +import oauth.signpost.http.HttpParameters; + +import com.metaweb.gridworks.util.FreebaseUtils; public class OAuthUtilities { @@ -14,30 +19,43 @@ public class OAuthUtilities { static final private Map infos = new HashMap(); static private final String[] FREEBASE_OAUTH_INFO = { "#9202a8c04000641f80000000150979b7" , "8ded7babfad2f94f4c77e39bbd6c90f31939999b"}; - static private final String[] SANDBOX_OAUTH_INFO = { "#9202a8c04000641f800000001505964a" , "a816b13991bf1d191ad1c371f3c230feca6a11e2"}; static { - providers.put("freebase", new FreebaseProvider("www.freebase.com")); - providers.put("sandbox", new FreebaseProvider("www.sandbox-freebase.com")); + Provider freebase = new FreebaseProvider(FreebaseUtils.FREEBASE_HOST); + providers.put(freebase.getHost(), freebase); - infos.put("www.freebase.com", FREEBASE_OAUTH_INFO); - infos.put("www.sandbox-freebase.com", SANDBOX_OAUTH_INFO); + infos.put(freebase.getHost(), FREEBASE_OAUTH_INFO); } public static Provider getProvider(String name) { return (name == null) ? null : providers.get(name); } + public static Provider getProvider(HttpServletRequest request) { + String path = request.getPathInfo().substring(1); + int slash = path.lastIndexOf('/'); + String provider_str = path.substring(slash + 1); + Provider provider = getProvider(provider_str); + if (provider == null) throw new RuntimeException("Can't find OAuth provider '" + provider_str + "'"); + return provider; + } + public static OAuthConsumer getConsumer(Provider provider) { if (provider == null) throw new RuntimeException("Provider can't be null"); String[] consumer_info = infos.get(provider.getHost()); if (consumer_info == null) throw new RuntimeException("Can't find secrets for provider '" + provider.getHost() + "'"); - return new CommonsHttpOAuthConsumer(consumer_info[0],consumer_info[1]); + OAuthConsumer oauthConsumer = new CommonsHttpOAuthConsumer(consumer_info[0],consumer_info[1]); + HttpParameters params = new HttpParameters(); + params.put("realm", provider.getHost()); + oauthConsumer.setAdditionalParameters(params); + return oauthConsumer; } public static OAuthConsumer getConsumer(Credentials credentials, Provider provider) { OAuthConsumer consumer = getConsumer(provider); - consumer.setTokenWithSecret(credentials.getToken(), credentials.getSecret()); + if (credentials != null) { + consumer.setTokenWithSecret(credentials.getToken(), credentials.getSecret()); + } return consumer; } diff --git a/src/main/java/com/metaweb/gridworks/util/CookiesUtilities.java b/src/main/java/com/metaweb/gridworks/util/CookiesUtilities.java index c2602e6fe..9fe3ba9de 100644 --- a/src/main/java/com/metaweb/gridworks/util/CookiesUtilities.java +++ b/src/main/java/com/metaweb/gridworks/util/CookiesUtilities.java @@ -6,6 +6,9 @@ import javax.servlet.http.HttpServletResponse; public class CookiesUtilities { + public static final String DOMAIN = "127.0.0.1"; + public static final String PATH = "/"; + public static Cookie getCookie(HttpServletRequest request, String name) { if (name == null) throw new RuntimeException("cookie name cannot be null"); Cookie cookie = null; @@ -20,15 +23,20 @@ public class CookiesUtilities { return cookie; } + public static void setCookie(HttpServletResponse response, String name, String value, int max_age) { + Cookie c = new Cookie(name, value); + c.setDomain(DOMAIN); + c.setPath(PATH); + c.setMaxAge(max_age); + response.addCookie(c); + } + public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name) { - Cookie cookie = getCookie(request, name); - if (cookie != null) { - Cookie delCookie = new Cookie(cookie.getName(), cookie.getValue()); - delCookie.setDomain(cookie.getDomain()); - delCookie.setPath(cookie.getPath()); - delCookie.setMaxAge(0); - response.addCookie(delCookie); - } + Cookie c = new Cookie(name, ""); + c.setDomain(DOMAIN); + c.setPath(PATH); + c.setMaxAge(0); + response.addCookie(c); } } diff --git a/src/main/java/com/metaweb/gridworks/util/FreebaseDataExtensionJob.java b/src/main/java/com/metaweb/gridworks/util/FreebaseDataExtensionJob.java index 41e0efa7f..1a6a7f0a1 100644 --- a/src/main/java/com/metaweb/gridworks/util/FreebaseDataExtensionJob.java +++ b/src/main/java/com/metaweb/gridworks/util/FreebaseDataExtensionJob.java @@ -3,7 +3,7 @@ */ package com.metaweb.gridworks.util; -import java.io.DataOutputStream; +import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; diff --git a/src/main/java/com/metaweb/gridworks/util/FreebaseUtils.java b/src/main/java/com/metaweb/gridworks/util/FreebaseUtils.java new file mode 100644 index 000000000..b2c91938e --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/util/FreebaseUtils.java @@ -0,0 +1,115 @@ +package com.metaweb.gridworks.util; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import oauth.signpost.OAuthConsumer; +import oauth.signpost.exception.OAuthCommunicationException; +import oauth.signpost.exception.OAuthExpectationFailedException; +import oauth.signpost.exception.OAuthMessageSignerException; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.util.EntityUtils; +import org.json.JSONException; +import org.json.JSONObject; + +import com.metaweb.gridworks.Gridworks; +import com.metaweb.gridworks.oauth.Credentials; +import com.metaweb.gridworks.oauth.OAuthUtilities; +import com.metaweb.gridworks.oauth.Provider; + +public class FreebaseUtils { + + static final public String FREEBASE_HOST = "www.freebase.com"; + static final public String FREEBASE_SANDBOX_HOST = "www.sandbox-freebase.com"; + + static final private String FREEQ_URL = "http://data.labs.freebase.com/freeq/prod/"; + + private static String getUserInfoURL(String host) { + return "http://" + host + "/api/service/user_info"; + } + + public static String getUserInfo(Credentials credentials, Provider provider) + throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException { + + OAuthConsumer consumer = OAuthUtilities.getConsumer(credentials, provider); + + HttpGet httpRequest = new HttpGet(getUserInfoURL(provider.getHost())); + httpRequest.getParams().setParameter(CoreProtocolPNames.USER_AGENT, "Gridworks " + Gridworks.getVersion()); + + // this is required by the Metaweb API to avoid XSS + httpRequest.setHeader("X-Requested-With", "1"); + + // sign the request with the oauth library + consumer.sign(httpRequest); + + // execute the request + HttpClient httpClient = new DefaultHttpClient(); + HttpResponse httpResponse = httpClient.execute(httpRequest); + + // return the results + return EntityUtils.toString(httpResponse.getEntity()); + } + + public static String uploadTriples(HttpServletRequest request, String info, String triples) + throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, JSONException, IOException { + + Provider provider = OAuthUtilities.getProvider(FREEBASE_HOST); + + Credentials credentials = Credentials.getCredentials(request, provider, Credentials.Type.ACCESS); + + JSONObject user_info = new JSONObject(getUserInfo(credentials, provider)); + if (user_info.has("username")) { + + List formparams = new ArrayList(); + formparams.add(new BasicNameValuePair("user", user_info.getString("username"))); + formparams.add(new BasicNameValuePair("action_type", "LOAD_TRIPLE")); + formparams.add(new BasicNameValuePair("operator", "gridworks")); + formparams.add(new BasicNameValuePair("mdo_info", info)); + formparams.add(new BasicNameValuePair("graphport", provider.getHost().equals(FREEBASE_HOST) ? "otg" : "sandbox")); + formparams.add(new BasicNameValuePair("payload", triples)); + formparams.add(new BasicNameValuePair("check_params", "false")); + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8"); + + HttpPost httpRequest = new HttpPost(FREEQ_URL); + httpRequest.setEntity(entity); + + HttpPost surrogateRequest = new HttpPost(getUserInfoURL(FREEBASE_HOST)); + surrogateRequest.setEntity(entity); + + OAuthConsumer consumer = OAuthUtilities.getConsumer(credentials, provider); + + consumer.sign(surrogateRequest); + + Header[] h = surrogateRequest.getHeaders("Authorization"); + if (h.length > 0) { + httpRequest.setHeader("X-Freebase-Credentials", h[0].getValue()); + } else { + throw new RuntimeException("Couldn't find the oauth signature header in the surrogate request"); + } + + // execute the request + HttpClient httpClient = new DefaultHttpClient(); + HttpResponse httpResponse = httpClient.execute(httpRequest); + + // return the results + return EntityUtils.toString(httpResponse.getEntity()); + } else { + throw new RuntimeException("Invalid credentials"); + } + } + +} diff --git a/src/main/webapp/WEB-INF/lib/slf4j-api-1.5.6.jar b/src/main/webapp/WEB-INF/lib/slf4j-api-1.5.6.jar new file mode 100644 index 0000000000000000000000000000000000000000..d794252336e627b38e183beaaa66c62192a97135 GIT binary patch literal 22338 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 literal 0 HcmV?d00001 diff --git a/src/main/webapp/WEB-INF/log4j.properties b/src/main/webapp/WEB-INF/log4j.properties deleted file mode 100644 index cdb0ade48..000000000 --- a/src/main/webapp/WEB-INF/log4j.properties +++ /dev/null @@ -1,8 +0,0 @@ -log4j.rootLogger=INFO, console -log4j.logger.org.mortbay.jetty=ERROR - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.layout=org.apache.log4j.PatternLayout -#log4j.appender.console.layout.ConversionPattern=[%p] %m%n -#log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c(%L) - %m%n -log4j.appender.console.layout.ConversionPattern=[%p] %c(%L) - %m%n diff --git a/src/main/webapp/externals/blockui/jquery.blockui.js b/src/main/webapp/externals/blockui/jquery.blockui.js deleted file mode 100644 index bf3cdc731..000000000 --- a/src/main/webapp/externals/blockui/jquery.blockui.js +++ /dev/null @@ -1,478 +0,0 @@ -/*! - * jQuery blockUI plugin - * Version 2.31 (06-JAN-2010) - * @requires jQuery v1.2.3 or later - * - * Examples at: http://malsup.com/jquery/block/ - * Copyright (c) 2007-2008 M. Alsup - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Thanks to Amir-Hossein Sobhi for some excellent contributions! - */ - -;(function($) { - -if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) { - alert('blockUI requires jQuery v1.2.3 or later! You are using v' + $.fn.jquery); - return; -} - -$.fn._fadeIn = $.fn.fadeIn; - -var noOp = function() {}; - -// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle -// retarded userAgent strings on Vista) -var mode = document.documentMode || 0; -var setExpr = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8); -var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent) && !mode; - -// global $ methods for blocking/unblocking the entire page -$.blockUI = function(opts) { install(window, opts); }; -$.unblockUI = function(opts) { remove(window, opts); }; - -// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) -$.growlUI = function(title, message, timeout, onClose) { - var $m = $('

'); - if (title) $m.append('

'+title+'

'); - if (message) $m.append('

'+message+'

'); - if (timeout == undefined) timeout = 3000; - $.blockUI({ - message: $m, fadeIn: 700, fadeOut: 1000, centerY: false, - timeout: timeout, showOverlay: false, - onUnblock: onClose, - css: $.blockUI.defaults.growlCSS - }); -}; - -// plugin method for blocking element content -$.fn.block = function(opts) { - return this.unblock({ fadeOut: 0 }).each(function() { - if ($.css(this,'position') == 'static') - this.style.position = 'relative'; - if ($.browser.msie) - this.style.zoom = 1; // force 'hasLayout' - install(this, opts); - }); -}; - -// plugin method for unblocking element content -$.fn.unblock = function(opts) { - return this.each(function() { - remove(this, opts); - }); -}; - -$.blockUI.version = 2.31; // 2nd generation blocking at no extra cost! - -// override these in your code to change the default behavior and style -$.blockUI.defaults = { - // message displayed when blocking (use null for no message) - message: '

Please wait...

', - - title: null, // title string; only used when theme == true - draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) - - theme: false, // set to true to use with jQuery UI themes - - // styles for the message when blocking; if you wish to disable - // these and use an external stylesheet then do this in your code: - // $.blockUI.defaults.css = {}; - css: { - padding: 0, - margin: 0, - width: '30%', - top: '40%', - left: '35%', - textAlign: 'center', - color: '#000', - border: '3px solid #aaa', - backgroundColor:'#fff', - cursor: 'wait' - }, - - // minimal style set used when themes are used - themedCSS: { - width: '30%', - top: '40%', - left: '35%' - }, - - // styles for the overlay - overlayCSS: { - backgroundColor: '#000', - opacity: 0.6, - cursor: 'wait' - }, - - // styles applied when using $.growlUI - growlCSS: { - width: '350px', - top: '10px', - left: '', - right: '10px', - border: 'none', - padding: '5px', - opacity: 0.6, - cursor: 'default', - color: '#fff', - backgroundColor: '#000', - '-webkit-border-radius': '10px', - '-moz-border-radius': '10px' - }, - - // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w - // (hat tip to Jorge H. N. de Vasconcelos) - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', - - // force usage of iframe in non-IE browsers (handy for blocking applets) - forceIframe: false, - - // z-index for the blocking overlay - baseZ: 1000, - - // set these to true to have the message automatically centered - centerX: true, // <-- only effects element blocking (page block controlled via css above) - centerY: true, - - // allow body element to be stetched in ie6; this makes blocking look better - // on "short" pages. disable if you wish to prevent changes to the body height - allowBodyStretch: true, - - // enable if you want key and mouse events to be disabled for content that is blocked - bindEvents: true, - - // be default blockUI will supress tab navigation from leaving blocking content - // (if bindEvents is true) - constrainTabKey: true, - - // fadeIn time in millis; set to 0 to disable fadeIn on block - fadeIn: 200, - - // fadeOut time in millis; set to 0 to disable fadeOut on unblock - fadeOut: 400, - - // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock - timeout: 0, - - // disable if you don't want to show the overlay - showOverlay: true, - - // if true, focus will be placed in the first available input field when - // page blocking - focusInput: true, - - // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) - applyPlatformOpacityRules: true, - - // callback method invoked when fadeIn has completed and blocking message is visible - onBlock: null, - - // callback method invoked when unblocking has completed; the callback is - // passed the element that has been unblocked (which is the window object for page - // blocks) and the options that were passed to the unblock call: - // onUnblock(element, options) - onUnblock: null, - - // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 - quirksmodeOffsetHack: 4 -}; - -// private data and functions follow... - -var pageBlock = null; -var pageBlockEls = []; - -function install(el, opts) { - var full = (el == window); - var msg = opts && opts.message !== undefined ? opts.message : undefined; - opts = $.extend({}, $.blockUI.defaults, opts || {}); - opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); - var css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); - var themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); - msg = msg === undefined ? opts.message : msg; - - // remove the current block (if there is one) - if (full && pageBlock) - remove(window, {fadeOut:0}); - - // if an existing element is being used as the blocking content then we capture - // its current place in the DOM (and current display style) so we can restore - // it when we unblock - if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { - var node = msg.jquery ? msg[0] : msg; - var data = {}; - $(el).data('blockUI.history', data); - data.el = node; - data.parent = node.parentNode; - data.display = node.style.display; - data.position = node.style.position; - if (data.parent) - data.parent.removeChild(node); - } - - var z = opts.baseZ; - - // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; - // layer1 is the iframe layer which is used to supress bleed through of underlying content - // layer2 is the overlay layer which has opacity and a wait cursor (by default) - // layer3 is the message content that is displayed while blocking - - var lyr1 = ($.browser.msie || opts.forceIframe) - ? $('') - : $(''); - var lyr2 = $(''); - - var lyr3; - if (opts.theme && full) { - var s = ''; - lyr3 = $(s); - } - else { - lyr3 = full ? $('') - : $(''); - } - - // if we have a message, style it - if (msg) { - if (opts.theme) { - lyr3.css(themedCSS); - lyr3.addClass('ui-widget-content'); - } - else - lyr3.css(css); - } - - // style the overlay - if (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))) - lyr2.css(opts.overlayCSS); - lyr2.css('position', full ? 'fixed' : 'absolute'); - - // make iframe layer transparent in IE - if ($.browser.msie || opts.forceIframe) - lyr1.css('opacity',0.0); - - //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); - var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); - $.each(layers, function() { - this.appendTo($par); - }); - - if (opts.theme && opts.draggable && $.fn.draggable) { - lyr3.draggable({ - handle: '.ui-dialog-titlebar', - cancel: 'li' - }); - } - - // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) - var expr = setExpr && (!$.boxModel || $('object,embed', full ? null : el).length > 0); - if (ie6 || expr) { - // give body 100% height - if (full && opts.allowBodyStretch && $.boxModel) - $('html,body').css('height','100%'); - - // fix ie6 issue when blocked element has a border width - if ((ie6 || !$.boxModel) && !full) { - var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); - var fixT = t ? '(0 - '+t+')' : 0; - var fixL = l ? '(0 - '+l+')' : 0; - } - - // simulate fixed position - $.each([lyr1,lyr2,lyr3], function(i,o) { - var s = o[0].style; - s.position = 'absolute'; - if (i < 2) { - full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"') - : s.setExpression('height','this.parentNode.offsetHeight + "px"'); - full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"') - : s.setExpression('width','this.parentNode.offsetWidth + "px"'); - if (fixL) s.setExpression('left', fixL); - if (fixT) s.setExpression('top', fixT); - } - else if (opts.centerY) { - if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); - s.marginTop = 0; - } - else if (!opts.centerY && full) { - var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0; - var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; - s.setExpression('top',expression); - } - }); - } - - // show the message - if (msg) { - if (opts.theme) - lyr3.find('.ui-widget-content').append(msg); - else - lyr3.append(msg); - if (msg.jquery || msg.nodeType) - $(msg).show(); - } - - if (($.browser.msie || opts.forceIframe) && opts.showOverlay) - lyr1.show(); // opacity is zero - if (opts.fadeIn) { - var cb = opts.onBlock ? opts.onBlock : noOp; - var cb1 = (opts.showOverlay && !msg) ? cb : noOp; - var cb2 = msg ? cb : noOp; - if (opts.showOverlay) - lyr2._fadeIn(opts.fadeIn, cb1); - if (msg) - lyr3._fadeIn(opts.fadeIn, cb2); - } - else { - if (opts.showOverlay) - lyr2.show(); - if (msg) - lyr3.show(); - if (opts.onBlock) - opts.onBlock(); - } - - // bind key and mouse events - bind(1, el, opts); - - if (full) { - pageBlock = lyr3[0]; - pageBlockEls = $(':input:enabled:visible',pageBlock); - if (opts.focusInput) - setTimeout(focus, 20); - } - else - center(lyr3[0], opts.centerX, opts.centerY); - - if (opts.timeout) { - // auto-unblock - var to = setTimeout(function() { - full ? $.unblockUI(opts) : $(el).unblock(opts); - }, opts.timeout); - $(el).data('blockUI.timeout', to); - } -}; - -// remove the block -function remove(el, opts) { - var full = (el == window); - var $el = $(el); - var data = $el.data('blockUI.history'); - var to = $el.data('blockUI.timeout'); - if (to) { - clearTimeout(to); - $el.removeData('blockUI.timeout'); - } - opts = $.extend({}, $.blockUI.defaults, opts || {}); - bind(0, el, opts); // unbind events - - var els; - if (full) // crazy selector to handle odd field errors in ie6/7 - els = $('body').children().filter('.blockUI').add('body > .blockUI'); - else - els = $('.blockUI', el); - - if (full) - pageBlock = pageBlockEls = null; - - if (opts.fadeOut) { - els.fadeOut(opts.fadeOut); - setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut); - } - else - reset(els, data, opts, el); -}; - -// move blocking element back into the DOM where it started -function reset(els,data,opts,el) { - els.each(function(i,o) { - // remove via DOM calls so we don't lose event handlers - if (this.parentNode) - this.parentNode.removeChild(this); - }); - - if (data && data.el) { - data.el.style.display = data.display; - data.el.style.position = data.position; - if (data.parent) - data.parent.appendChild(data.el); - $(el).removeData('blockUI.history'); - } - - if (typeof opts.onUnblock == 'function') - opts.onUnblock(el,opts); -}; - -// bind/unbind the handler -function bind(b, el, opts) { - var full = el == window, $el = $(el); - - // don't bother unbinding if there is nothing to unbind - if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) - return; - if (!full) - $el.data('blockUI.isBlocked', b); - - // don't bind events when overlay is not in use or if bindEvents is false - if (!opts.bindEvents || (b && !opts.showOverlay)) - return; - - // bind anchors and inputs for mouse and key events - var events = 'mousedown mouseup keydown keypress'; - b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler); - -// former impl... -// var $e = $('a,:input'); -// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); -}; - -// event handler to suppress keyboard/mouse events when blocking -function handler(e) { - // allow tab navigation (conditionally) - if (e.keyCode && e.keyCode == 9) { - if (pageBlock && e.data.constrainTabKey) { - var els = pageBlockEls; - var fwd = !e.shiftKey && e.target == els[els.length-1]; - var back = e.shiftKey && e.target == els[0]; - if (fwd || back) { - setTimeout(function(){focus(back)},10); - return false; - } - } - } - // allow events within the message content - if ($(e.target).parents('div.blockMsg').length > 0) - return true; - - // allow events for content that is not being blocked - return $(e.target).parents().children().filter('div.blockUI').length == 0; -}; - -function focus(back) { - if (!pageBlockEls) - return; - var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; - if (e) - e.focus(); -}; - -function center(el, x, y) { - var p = el.parentNode, s = el.style; - var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); - var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); - if (x) s.left = l > 0 ? (l+'px') : '0'; - if (y) s.top = t > 0 ? (t+'px') : '0'; -}; - -function sz(el, p) { - return parseInt($.css(el,p))||0; -}; - -})(jQuery); - diff --git a/src/main/webapp/project.html b/src/main/webapp/project.html index a8b876170..6a91a5740 100644 --- a/src/main/webapp/project.html +++ b/src/main/webapp/project.html @@ -1 +1 @@ - Freebase Gridworks
starting up ...
\ No newline at end of file + Freebase Gridworks
starting up ...
\ No newline at end of file diff --git a/src/main/webapp/scripts/dialogs/freebase-loading-dialog.js b/src/main/webapp/scripts/dialogs/freebase-loading-dialog.js index 5fab5e43a..322afacc9 100644 --- a/src/main/webapp/scripts/dialogs/freebase-loading-dialog.js +++ b/src/main/webapp/scripts/dialogs/freebase-loading-dialog.js @@ -5,76 +5,118 @@ function FreebaseLoadingDialog() { FreebaseLoadingDialog.prototype._createDialog = function() { var self = this; var frame = DialogSystem.createDialog(); - frame.width("900px"); + frame.width("800px"); var header = $('
').addClass("dialog-header").text('Load Data into Freebase').appendTo(frame); var body = $('
').addClass("dialog-body").appendTo(frame); var footer = $( '' ).appendTo(frame); $.post( - "/command/export-rows?" + $.param({ + "/command/export-rows", + { project: theProject.id, format : "tripleloader" - }), - {}, + }, function(data) { - frame.find(".dialog-body").html('
' + data + ''); + console.log(data); + body.html( + '
' + data + '
' + + '
' + + '
Describe the data you\'re about to load ¬
' + + '' + + '
' + ); self._level = DialogSystem.showDialog(frame); } ); - var left_footer = footer.find(".left"); - $('').text("Cancel").click(function() { + var left_footer = footer.find(".left"); + + var cancel_button = $('').text("Cancel").click(function() { self._dismiss(); }).appendTo(left_footer); + var center_footer = footer.find(".center"); + + var authorization = $('
').addClass("freebase-loading-authorization").hide().appendTo(center_footer); + var right_footer = footer.find(".right"); - //$('').appendTo(right_footer); - - var selector = $('').addClass("freebase-loading-graph-selector").html("Load into " + + var selector = $('').addClass("freebase-loading-graph-selector").html("Load this data into " + '' + - '' + '' ).buttonset().appendTo(right_footer); - - $('').text("Load").click(function() { - self._check_authorization(self._load); - }).appendTo(right_footer); + + var load_button = $('').text("Sign In").appendTo(right_footer); this._elmts = DOM.bind(frame); + + var provider = "www.freebase.com"; - this._elmts.otg.click(function() { - if (!confirm("are you sure?")) { - self._elmts.sandbox.attr("checked","checked"); - self._elmts.otg.removeAttr("checked"); - selector.find("input").button('refresh'); - } + var check_authorization = function() { + $.get("/command/check-authorization/" + provider, function(data) { + if ("status" in data && data.status == "200 OK") { + authorization.html('Signed in as: ' + data.username + ' | Sign Out').show(); + DOM.bind(authorization).signout.click(function() { + Sign.signout(check_authorization,provider); + }); + load_button.text("Load").unbind().click(function() { + self._load(self); + }); + } else { + authorization.html("").hide(); + load_button.text("Sign In").removeAttr("disabled").unbind().click(function() { + Sign.signin(check_authorization,provider); + }); + } + },"json"); + }; + + check_authorization(); + + this._elmts.sandbox.click(function() { + //check_authorization(); }); -}; - -FreebaseLoadingDialog.prototype._check_authorization = function(cont) { - var freebase = this._elmts.otg.attr("checked"); - var provider = (freebase) ? "freebase" : "sandbox"; - $.get("/command/check-authorization",{ "provider" : provider }, function(data) { - if ("status" in data && data.status == "200 OK") { - if (typeof cont == "function") cont(); - } else { - alert("Sorry, we're working very hard to make this happen."); - //Sign.signin(cont,provider); + this._elmts.freebase.click(function() { + if (!confirm("Are you sure your data is clean enough to enter Freebase?")) { + self._elmts.sandbox.attr("checked","checked"); + self._elmts.freebase.removeAttr("checked"); + selector.find("input").button('refresh'); } - },"json"); + //check_authorization(); + }); }; -FreebaseLoadingDialog.prototype._load = function() { - // do the real loading here +FreebaseLoadingDialog.prototype._load = function(self) { + $.post("/command/upload-data", + { + project: theProject.id, + "graph" : ($("#freebase-loading-graph-selector-freebase").attr("checked")) ? "otg" : "sandbox", + "info" : $("#freebase-loading-tripleloader-info textarea").val() + }, + function(data) { + var body = $(".dialog-body"); + if ("status" in data && data.status == "200 OK") { + body.html('

Data successfully loaded!

' + data.message + '
'); + } else { + body.html('

Error loading data!

' + JSON.stringify(data,null,2) + '
'); + } + $("button#freebase-loading-load").text("Close").unbind().click(function() { + self._dismiss(); + }); + $("button#freebase-loading-cancel").hide(); + }, + "json" + ); } FreebaseLoadingDialog.prototype._dismiss = function() { diff --git a/src/main/webapp/scripts/util/sign.js b/src/main/webapp/scripts/util/sign.js index fd2ef350d..4522488e7 100644 --- a/src/main/webapp/scripts/util/sign.js +++ b/src/main/webapp/scripts/util/sign.js @@ -56,27 +56,7 @@ return window.open(url, windowname || "", params_list.join(",")); }, - - block : function() { - if ($.blockUI) { - $.blockUI({ css: { - border: 'none', - padding: '15px', - backgroundColor: '#000', - '-webkit-border-radius': '10px', - '-moz-border-radius': '10px', - opacity: .5, - color: '#fff' - } }); - } - }, - - unblock : function() { - if ($.unblockUI) { - $.unblockUI(); - } - }, - + signintize : function(cont) { $('.signedin').show(); $('.signedout').hide(); @@ -87,33 +67,31 @@ }, signin : function(success, provider, width, height) { - var newwin = window.Sign.popup("/command/authorize?" + $.param({ "provider" : provider}), width, height); + var newwin = window.Sign.popup("/command/authorize/" + provider, width, height); - console.log(newwin); - - newwin.opener = window; + if (newwin !== null) { + newwin.opener = window; + } window.onauthorization = function() { - window.Sign.block(); if (typeof success == 'undefined') { window.location.reload(); } else { $.ajax({ - url: "/command/check-authorization", + url: "/command/check-authorization/" + provider, dataType: "json", success: function(data) { window.user = data; window.Sign.signintize(success); - window.Sign.unblock(); } }); } }; - if (window.focus) { + if (window.focus && newwin !== null) { newwin.focus(); - console.log("focus"); } + return false; }, @@ -124,17 +102,13 @@ }, signout : function(success,provider) { - window.Sign.block(); - $.ajax({ - url: "/command/deauthorize", - data: { "provider" : provider }, + url: "/command/deauthorize/" + provider, success: function() { if (typeof success == 'undefined') { window.location.reload(); } else { window.Sign.signoutize(success); - window.Sign.unblock(); } } }); diff --git a/src/main/webapp/styles/dialogs/freebase-loading-dialog.css b/src/main/webapp/styles/dialogs/freebase-loading-dialog.css index 8c9eac7f8..8b76b2f18 100644 --- a/src/main/webapp/styles/dialogs/freebase-loading-dialog.css +++ b/src/main/webapp/styles/dialogs/freebase-loading-dialog.css @@ -1,8 +1,34 @@ .freebase-loading-tripleloader-data { - height: 500px; + height: 400px; + width: 99%; overflow: auto; border: 1px solid #aaa; white-space: pre; padding: 0.3em 0.5em 0.5em 0.5em; font-family: monospace; } + +.freebase-loading-tripleloader-message { + height: 500px; + overflow: auto; + border: 1px solid #aaa; + padding: 0.3em 0.5em 0.5em 0.5em; +} + +.freebase-loading-authorization { + margin: 0em 2em; + padding: 0.6em 0.8em; + border: 1px solid #ccc; + background-color: #fff; + -moz-border-radius: 0.8em; + -webkit-border-radius: 0.8em; +} + +.freebase-loading-tripleloader-info { + margin-top: 1em; +} + +.freebase-loading-tripleloader-info textarea { + width: 99%; + height: 5em; +} \ No newline at end of file diff --git a/src/server/java/com/metaweb/gridworks/Gridworks.java b/src/server/java/com/metaweb/gridworks/Gridworks.java index 2b1cd7859..f981a3250 100644 --- a/src/server/java/com/metaweb/gridworks/Gridworks.java +++ b/src/server/java/com/metaweb/gridworks/Gridworks.java @@ -20,18 +20,15 @@ import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; -import org.apache.log4j.Appender; -import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; -import org.apache.log4j.Logger; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Server; import org.mortbay.jetty.bio.SocketConnector; import org.mortbay.jetty.webapp.WebAppContext; -import org.mortbay.log.Log; import org.mortbay.util.Scanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.metaweb.util.logging.IndentingLayout; import com.metaweb.util.signal.AbstractSignalHandler; import com.metaweb.util.threads.ThreadPoolExecutorAdapter; @@ -45,29 +42,8 @@ public class Gridworks { static private File tempDir; static private int port; static private String host; - - private static Logger root = Logger.getRootLogger(); - private static Logger logger = Logger.getLogger("com.metaweb.gridworks"); - public static void log(String message) { - logger.info(message); - } - - public static void info(String message) { - logger.info(message); - } - - public static void error(String message, Throwable t) { - logger.error(message, t); - } - - public static void warn(String message) { - logger.warn(message); - } - - public static void warn(String message, Throwable t) { - logger.warn(message, t); - } + final static Logger logger = LoggerFactory.getLogger("gridworks"); public static String getVersion() { return VERSION; @@ -100,20 +76,15 @@ public class Gridworks { System.setProperty("com.apple.eawt.CocoaComponent.CompatibilityMode", "false"); // tell the signpost library to log - System.setProperty("debug","true"); + //System.setProperty("debug","true"); // if not already set, make sure jython can find its python stuff if (System.getProperty("python.path") == null) { System.setProperty("python.path","lib/python"); } - // initialize the log4j system - Appender console = new ConsoleAppender(new IndentingLayout()); - root.setLevel(Level.ALL); - root.addAppender(console); - - Logger jetty_logger = Logger.getLogger("org.mortbay.log"); - jetty_logger.setLevel(Level.WARN); + // set the log verbosity level + org.apache.log4j.Logger.getRootLogger().setLevel(Level.toLevel(Configurations.get("gridworks.verbosity","info"))); tempDir = new File(Configurations.get("gridworks.temp","temp")); if (!tempDir.exists()) tempDir.mkdirs(); @@ -137,7 +108,7 @@ public class Gridworks { GridworksClient client = new GridworksClient(); client.init(host,port); } catch (Exception e) { - Log.warn("Sorry, some error prevented us from launching the browser for you.\n\n Point your browser to http://" + host + ":" + port + "/ to start using Gridworks."); + logger.warn("Sorry, some error prevented us from launching the browser for you.\n\n Point your browser to http://" + host + ":" + port + "/ to start using Gridworks."); } } @@ -152,6 +123,8 @@ public class Gridworks { class GridworksServer extends Server { + final static Logger logger = LoggerFactory.getLogger("gridworks_server"); + private ThreadPoolExecutor threadPool; public void init(String host, int port) throws Exception { @@ -177,11 +150,11 @@ class GridworksServer extends Server { File webXml = new File(contextRoot, "WEB-INF/web.xml"); if (!webXml.isFile()) { - Gridworks.warn("Warning: Failed to find web application. Could not find 'web.xml' at '" + webXml.getAbsolutePath() + "'"); + logger.warn("Warning: Failed to find web application. Could not find 'web.xml' at '" + webXml.getAbsolutePath() + "'"); System.exit(-1); } - Gridworks.info("Initializing context: '" + contextPath + "' from '" + contextRoot.getAbsolutePath() + "'"); + logger.info("Initializing context: '" + contextPath + "' from '" + contextRoot.getAbsolutePath() + "'"); WebAppContext context = new WebAppContext(contextRoot.getAbsolutePath(), contextPath); //context.setCopyWebDir(false); //context.setDefaultsDescriptor(null); @@ -217,7 +190,7 @@ class GridworksServer extends Server { scanList.add(new File(contextRoot, "WEB-INF/web.xml")); findFiles(".class", new File(contextRoot, "WEB-INF/classes"), scanList); - Gridworks.info("Starting autoreloading scanner... "); + logger.info("Starting autoreloading scanner... "); Scanner scanner = new Scanner(); scanner.setScanInterval(Configurations.getInteger("gridworks.scanner.period",1)); @@ -228,10 +201,10 @@ class GridworksServer extends Server { @SuppressWarnings("unchecked") public void filesChanged(List changedFiles) { try { - Gridworks.info("Stopping context: " + contextRoot.getAbsolutePath()); + logger.info("Stopping context: " + contextRoot.getAbsolutePath()); context.stop(); - Gridworks.info("Starting context: " + contextRoot.getAbsolutePath()); + logger.info("Starting context: " + contextRoot.getAbsolutePath()); context.start(); } catch (Exception ex) { throw new RuntimeException(ex);