diff --git a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
index 50831035..6fe1234f 100644
--- a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
+++ b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
@@ -46,6 +46,9 @@
+
+
@@ -118,6 +121,10 @@
+
+
+
+
diff --git a/productMods/templates/freemarker/visualization/tools.ftl b/productMods/templates/freemarker/visualization/tools.ftl
new file mode 100644
index 00000000..fc2bd313
--- /dev/null
+++ b/productMods/templates/freemarker/visualization/tools.ftl
@@ -0,0 +1,31 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#assign shortVisualizationURLRoot ="/vis">
+<#assign refreshCacheURL = "${urls.base}${shortVisualizationURLRoot}/refresh-cache">
+
+Visualization Tools
+
+Refresh Cached Models for Visualization
+
+Why
+Certain class of visualizations like Temporal graph and Map of Science that work on a large scale
+attempt to calculate counts of publications (or grants) for all the organizations within an organization.
+These queries tend to be both memory intensive and time consuming. In order to provide a good user experience when
+these visualizations are served we decided to save the results of these queries to be reused later.
+
+What
+To this end we have devised a caching solution which will store information about the organization
+hierarchy, which publications were published from which organizations etc (among other things) in
+semantic way (i.e. we store the rdf model).
+
+We're currently caching these models in-memory, which works nicely, for now. Currently the cache is only built
+once, on first user request after a server restart, so the visualization will essentially never be updated
+until the server is restarted again. It is not being updated real-time or periodically. This means that the data in these
+models might be stale depending upon when was it last created. In future releases we will come
+up with a solution that stores these models on disk and be updated periodically.
+
+How
+To refresh these models either restart the server or click on "refresh cache" link above. We realize that
+in production VIVO instances it is not feasible to restart the server to refresh these models. Hence we
+recommend the above link. Administrators can use this link to trigger regeneration of all the existing
+models.
\ No newline at end of file
diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/tools/ToolsRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/tools/ToolsRequestHandler.java
new file mode 100644
index 00000000..fee8e3ed
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/tools/ToolsRequestHandler.java
@@ -0,0 +1,72 @@
+package edu.cornell.mannlib.vitro.webapp.visualization.tools;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+
+import com.hp.hpl.jena.query.Dataset;
+
+import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
+import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.RefreshVisualizationCacheAction;
+import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
+import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.IllegalConstructedModelIdentifierException;
+import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
+import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.ConstructedModel;
+import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.ConstructedModelTracker;
+import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
+import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
+
+public class ToolsRequestHandler implements VisualizationRequestHandler {
+
+ public static final Actions REQUIRED_ACTIONS = new Actions(new RefreshVisualizationCacheAction());
+
+ @Override
+ public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
+ Dataset dataSource) throws MalformedQueryParametersException {
+ throw new UnsupportedOperationException("Visualization Tool does not provide Ajax Response.");
+ }
+
+ @Override
+ public Map generateDataVisualization(
+ VitroRequest vitroRequest, Log log, Dataset dataset)
+ throws MalformedQueryParametersException {
+ throw new UnsupportedOperationException("Visualization Tool does not provide Data Response.");
+ }
+
+ @Override
+ public ResponseValues generateStandardVisualization(
+ VitroRequest vitroRequest, Log log, Dataset dataSource)
+ throws MalformedQueryParametersException {
+ return renderToolsMenu(vitroRequest, log, dataSource);
+ }
+
+ @Override
+ public ResponseValues generateVisualizationForShortURLRequests(
+ Map parameters, VitroRequest vitroRequest, Log log,
+ Dataset dataSource) throws MalformedQueryParametersException {
+
+ return renderToolsMenu(vitroRequest, log, dataSource);
+ }
+
+ @Override
+ public Actions getRequiredPrivileges() {
+ return REQUIRED_ACTIONS;
+ }
+
+ private ResponseValues renderToolsMenu(VitroRequest vitroRequest,
+ Log log, Dataset dataSource) {
+
+ String standaloneTemplate = "tools.ftl";
+
+ Map body = new HashMap();
+ body.put("title", "Visualization Tools");
+
+ return new TemplateResponseValues(standaloneTemplate, body);
+ }
+
+}