diff --git a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
index 22a3d0a9..0700f430 100644
--- a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
+++ b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml
@@ -12,13 +12,15 @@
+
+
+
diff --git a/productMods/templates/freemarker/visualization/personlevel/personLevelInjectHead.ftl b/productMods/templates/freemarker/visualization/personlevel/personLevelInjectHead.ftl
new file mode 100644
index 00000000..d3f9e354
--- /dev/null
+++ b/productMods/templates/freemarker/visualization/personlevel/personLevelInjectHead.ftl
@@ -0,0 +1,17 @@
+<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
+
+<#assign visualizationURLRoot ="/visualization">
+
+<#assign egoURI ="${egoURIParam?url}">
+
+<#assign egoCoAuthorshipDataFeederURL = '${urls.base}${visualizationURLRoot}?vis=coauthorship&uri=${egoURI}&render_mode=data&labelField=label'>
+
+<#assign egoCoPIDataFeederURL = '${urls.base}${visualizationURLRoot}?vis=coprincipalinvestigator&uri=${egoURI}&render_mode=data&labelField=label'>
+
+<#assign egoCoAuthorsListDataFileURL = '${urls.base}${visualizationURLRoot}?vis=person_level&uri=${egoURI}&render_mode=data&vis_mode=coauthors'>
+
+<#assign swfLink = '${urls.images}/visualization/coauthorship/EgoCentric.swf'>
+
+
+
+
diff --git a/productMods/templates/freemarker/visualization/publicationSparklineContent.ftl b/productMods/templates/freemarker/visualization/publicationSparklineContent.ftl
index c94c8fc8..f5406915 100644
--- a/productMods/templates/freemarker/visualization/publicationSparklineContent.ftl
+++ b/productMods/templates/freemarker/visualization/publicationSparklineContent.ftl
@@ -69,8 +69,6 @@
<#if sparklineVO.shortVisMode>
- console.log("Yay! Short Vis Mode!");
-
<#-- For the short view we only want the last 10 year's view of publication count, hence we filter
the data we actually want to use for render. -->
@@ -85,8 +83,6 @@
<#else>
- console.log("Yay! Full Vis Mode!");
-
#if>
@@ -175,8 +171,6 @@
row.append(sparklineImgTD);
- console.log(sparklineImgTD);
-
var sparklineNumberTD = $('
');
sparklineNumberTD.attr('width', '30');
sparklineNumberTD.attr('align', 'right');
@@ -191,8 +185,6 @@
}
- console.log(sparklineImgTD);
-
drawPubCountVisualization(sparklineImgTD);
});
diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java
index 4d065348..22418b1d 100644
--- a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java
+++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java
@@ -25,6 +25,8 @@ public class VisualizationFrameworkConstants {
*/
public static final String VISUALIZATION_URL_PREFIX = "/visualization";
public static final String FREEMARKERIZED_VISUALIZATION_URL_PREFIX = "/visualizationfm";
+ public static final String AJAX_VISUALIZATION_SERVICE_URL_PREFIX = "/visualizationAjax";
+ public static final String DATA_VISUALIZATION_SERVICE_URL_PREFIX = "/visualizationData";
public static final String INDIVIDUAL_URL_PREFIX = "/individual";
@@ -85,6 +87,5 @@ public class VisualizationFrameworkConstants {
public static final String ENTITY_COMPARISON_VIS = "entity_comparison";
public static final String CO_PI_VIS = "coprincipalinvestigator";
-
}
diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationController.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/AjaxVisualizationController.java
similarity index 65%
rename from src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationController.java
rename to src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/AjaxVisualizationController.java
index f57526b7..07f748d5 100644
--- a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationController.java
+++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/AjaxVisualizationController.java
@@ -9,12 +9,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hp.hpl.jena.query.DataSource;
import com.hp.hpl.jena.query.DatasetFactory;
@@ -28,6 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
import freemarker.template.Configuration;
@@ -39,75 +36,34 @@ import freemarker.template.Configuration;
* @author cdtank
*/
@SuppressWarnings("serial")
-public class VisualizationController extends FreemarkerHttpServlet {
-
- private Map visualizationIDsToClass;
+public class AjaxVisualizationController extends FreemarkerHttpServlet {
public static final String URL_ENCODING_SCHEME = "UTF-8";
- private static final Log log = LogFactory.getLog(VisualizationController.class.getName());
+ private static final Log log = LogFactory.getLog(AjaxVisualizationController.class.getName());
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
+ throws IOException, ServletException {
VitroRequest vreq = new VitroRequest(request);
-
- String renderMode = vreq.getParameter(VisualizationFrameworkConstants
- .RENDER_MODE_KEY);
-
- if (StringUtils.equalsIgnoreCase(renderMode, VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE)) {
-
- Configuration config = getConfig(vreq);
- TemplateResponseValues trv = (TemplateResponseValues) processRequest(vreq);
- writeTemplate(trv.getTemplateName(), trv.getMap(), config, request, response);
-
- } else {
- super.doGet(request, response);
- }
-
-
- }
-
-
-
- /* This method is overridden to inject vis dependencies i.e. the vis algorithms that are
- * being implemented into the vis controller. Modified Dependency Injection pattern is
- * used here. XML file containing the location of all the vis is saved in accessible folder.
- * @see javax.servlet.GenericServlet#init()
- */
- @Override
- public void init() throws ServletException {
- super.init();
- try {
+
+ Object ajaxResponse = processAjaxRequest(vreq);
+
+ if (ajaxResponse instanceof TemplateResponseValues) {
- String resourcePath =
- getServletContext()
- .getRealPath(VisualizationFrameworkConstants
- .RELATIVE_LOCATION_OF_FM_VISUALIZATIONS_BEAN);
+ Configuration config = getConfig(vreq);
+ TemplateResponseValues trv = (TemplateResponseValues) ajaxResponse;
+ writeTemplate(trv.getTemplateName(), trv.getMap(), config, request, response);
- ApplicationContext context = new ClassPathXmlApplicationContext(
- "file:" + resourcePath);
-
- BeanFactory factory = context;
-
- VisualizationInjector visualizationInjector =
- (VisualizationInjector) factory.getBean("visualizationInjector");
-
- visualizationIDsToClass = visualizationInjector.getVisualizationIDToClass();
-
- } catch (Exception e) {
- log.error(e);
+ } else {
+ response.getWriter().write(ajaxResponse.toString());
}
- }
+ }
-
-
- @Override
- protected ResponseValues processRequest(VitroRequest vreq) {
-
+ private Object processAjaxRequest(VitroRequest vreq) {
/*
* Based on the query parameters passed via URI get the appropriate visualization
* request handler.
@@ -131,12 +87,10 @@ public class VisualizationController extends FreemarkerHttpServlet {
vreq);
}
-
-
}
- private ResponseValues renderVisualization(VitroRequest vitroRequest,
+ private Object renderVisualization(VitroRequest vitroRequest,
VisualizationRequestHandler visRequestHandler) {
Model model = vitroRequest.getJenaOntModel(); // getModel()
@@ -158,9 +112,17 @@ public class VisualizationController extends FreemarkerHttpServlet {
if (dataSource != null && visRequestHandler != null) {
- return visRequestHandler.generateVisualization(vitroRequest,
- log,
- dataSource);
+ try {
+ return visRequestHandler.generateAjaxVisualization(vitroRequest,
+ log,
+ dataSource);
+ } catch (MalformedQueryParametersException e) {
+ return UtilityFunctions.handleMalformedParameters(
+ "Ajax Visualization Query Error - Individual Publication Count",
+ e.getMessage(),
+ vitroRequest);
+
+ }
} else {
@@ -184,10 +146,10 @@ public class VisualizationController extends FreemarkerHttpServlet {
.VIS_TYPE_KEY);
VisualizationRequestHandler visRequestHandler = null;
- System.out.println(visType + " --> " + visualizationIDsToClass);
-
try {
- visRequestHandler = visualizationIDsToClass.get(visType);
+ visRequestHandler = VisualizationsDependencyInjector
+ .getVisualizationIDsToClassMap(getServletContext()).get(visType);
+
} catch (NullPointerException nullKeyException) {
return null;
diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/DataVisualizationController.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/DataVisualizationController.java
new file mode 100644
index 00000000..a02bb4b2
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/DataVisualizationController.java
@@ -0,0 +1,178 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.hp.hpl.jena.query.DataSource;
+import com.hp.hpl.jena.query.DatasetFactory;
+import com.hp.hpl.jena.query.Syntax;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelMaker;
+
+import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
+import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
+
+/**
+ * Services a visualization request. This will return a simple error message and a 501 if
+ * there is no jena Model.
+ *
+ * @author cdtank
+ */
+@SuppressWarnings("serial")
+public class DataVisualizationController extends VitroHttpServlet {
+
+ public static final String URL_ENCODING_SCHEME = "UTF-8";
+
+ private static final Log log = LogFactory.getLog(DataVisualizationController.class.getName());
+
+ protected static final Syntax SYNTAX = Syntax.syntaxARQ;
+
+ public static final String FILE_CONTENT_TYPE_KEY = "fileContentType";
+ public static final String FILE_CONTENT_KEY = "fileContent";
+ public static final String FILE_NAME_KEY = "fileName";
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+
+ VitroRequest vreq = new VitroRequest(request);
+
+ /*
+ * Based on the query parameters passed via URI get the appropriate visualization
+ * request handler.
+ * */
+ VisualizationRequestHandler visRequestHandler =
+ getVisualizationRequestHandler(vreq);
+
+ if (visRequestHandler != null) {
+
+ /*
+ * Pass the query to the selected visualization request handler & render the visualization.
+ * Since the visualization content is directly added to the response object we are side-
+ * effecting this method.
+ * */
+ try {
+
+ Map dataResponse = renderVisualization(vreq, visRequestHandler);
+
+ response.setContentType(dataResponse.get(FILE_CONTENT_TYPE_KEY));
+
+ if (dataResponse.containsKey(FILE_NAME_KEY)) {
+ response.setHeader("Content-Disposition",
+ "attachment;filename=" + dataResponse.get(FILE_NAME_KEY));
+ }
+
+ response.getWriter().write(dataResponse.get(FILE_CONTENT_KEY));
+
+ return;
+
+ } catch (MalformedQueryParametersException e) {
+
+ UtilityFunctions.handleMalformedParameters("Visualization Query Error",
+ e.getMessage(),
+ vreq,
+ request,
+ response,
+ log);
+
+ }
+
+ return;
+
+ } else {
+
+ UtilityFunctions.handleMalformedParameters("Visualization Query Error",
+ "Inappropriate query parameters were submitted.",
+ vreq,
+ request,
+ response,
+ log);
+
+ }
+
+
+ }
+
+
+ private Map renderVisualization(
+ VitroRequest vitroRequest,
+ VisualizationRequestHandler visRequestHandler)
+ throws MalformedQueryParametersException {
+
+ Model model = vitroRequest.getJenaOntModel(); // getModel()
+ if (model == null) {
+
+ String errorMessage = "This service is not supporeted by the current "
+ + "webapp configuration. A jena model is required in the "
+ + "servlet context.";
+
+ log.error(errorMessage);
+
+ throw new MalformedQueryParametersException(errorMessage);
+ }
+
+ DataSource dataSource = setupJENADataSource(model, vitroRequest);
+
+ if (dataSource != null && visRequestHandler != null) {
+ return visRequestHandler.generateDataVisualization(vitroRequest,
+ log,
+ dataSource);
+
+ } else {
+
+ String errorMessage = "Data Model Empty &/or Inappropriate "
+ + "query parameters were submitted. ";
+
+ throw new MalformedQueryParametersException(errorMessage);
+
+ }
+ }
+
+ private VisualizationRequestHandler getVisualizationRequestHandler(
+ VitroRequest vitroRequest) {
+
+ String visType = vitroRequest.getParameter(VisualizationFrameworkConstants
+ .VIS_TYPE_KEY);
+ VisualizationRequestHandler visRequestHandler = null;
+
+
+ try {
+ visRequestHandler = VisualizationsDependencyInjector
+ .getVisualizationIDsToClassMap(getServletContext())
+ .get(visType);
+ } catch (NullPointerException nullKeyException) {
+
+ return null;
+ }
+
+ return visRequestHandler;
+ }
+
+ private DataSource setupJENADataSource(Model model, VitroRequest vreq) {
+
+ log.debug("rdfResultFormat was: " + VisConstants.RDF_RESULT_FORMAT_PARAM);
+
+ DataSource dataSource = DatasetFactory.create();
+ ModelMaker maker = (ModelMaker) getServletContext().getAttribute("vitroJenaModelMaker");
+
+ dataSource.setDefaultModel(model);
+
+ return dataSource;
+ }
+
+}
+
diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/StandardVisualizationController.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/StandardVisualizationController.java
new file mode 100644
index 00000000..efdbaf3a
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/StandardVisualizationController.java
@@ -0,0 +1,147 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.hp.hpl.jena.query.DataSource;
+import com.hp.hpl.jena.query.DatasetFactory;
+import com.hp.hpl.jena.query.Syntax;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelMaker;
+
+import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
+import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
+import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
+
+/**
+ * Services a standard visualization request, which involves templates. This will return a simple error message and a 501 if
+ * there is no jena Model.
+ *
+ * @author cdtank
+ */
+@SuppressWarnings("serial")
+public class StandardVisualizationController extends FreemarkerHttpServlet {
+
+ public static final String URL_ENCODING_SCHEME = "UTF-8";
+
+ private static final Log log = LogFactory.getLog(StandardVisualizationController.class.getName());
+
+ protected static final Syntax SYNTAX = Syntax.syntaxARQ;
+
+ @Override
+ protected ResponseValues processRequest(VitroRequest vreq) {
+
+ /*
+ * Based on the query parameters passed via URI get the appropriate visualization
+ * request handler.
+ * */
+ VisualizationRequestHandler visRequestHandler =
+ getVisualizationRequestHandler(vreq);
+
+ if (visRequestHandler != null) {
+
+ /*
+ * Pass the query to the selected visualization request handler & render the visualization.
+ * Since the visualization content is directly added to the response object we are side-
+ * effecting this method.
+ * */
+ return renderVisualization(vreq, visRequestHandler);
+
+ } else {
+ return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
+ "Inappropriate query parameters were submitted.",
+ vreq);
+ }
+
+
+ }
+
+
+ private ResponseValues renderVisualization(VitroRequest vitroRequest,
+ VisualizationRequestHandler visRequestHandler) {
+
+ Model model = vitroRequest.getJenaOntModel(); // getModel()
+ if (model == null) {
+
+ String errorMessage = "This service is not supporeted by the current "
+ + "webapp configuration. A jena model is required in the "
+ + "servlet context.";
+
+ log.error(errorMessage);
+
+ return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
+ errorMessage,
+ vitroRequest);
+
+ }
+
+ DataSource dataSource = setupJENADataSource(model, vitroRequest);
+
+ if (dataSource != null && visRequestHandler != null) {
+
+ try {
+ return visRequestHandler.generateStandardVisualization(vitroRequest,
+ log,
+ dataSource);
+ } catch (MalformedQueryParametersException e) {
+ return UtilityFunctions.handleMalformedParameters(
+ "Standard Visualization Query Error - Individual Publication Count",
+ e.getMessage(),
+ vitroRequest);
+ }
+
+ } else {
+
+ String errorMessage = "Data Model Empty &/or Inappropriate "
+ + "query parameters were submitted. ";
+
+ log.error(errorMessage);
+
+ return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
+ errorMessage,
+ vitroRequest);
+
+
+ }
+ }
+
+ private VisualizationRequestHandler getVisualizationRequestHandler(
+ VitroRequest vitroRequest) {
+
+ String visType = vitroRequest.getParameter(VisualizationFrameworkConstants
+ .VIS_TYPE_KEY);
+ VisualizationRequestHandler visRequestHandler = null;
+
+ try {
+ visRequestHandler = VisualizationsDependencyInjector
+ .getVisualizationIDsToClassMap(getServletContext())
+ .get(visType);
+ } catch (NullPointerException nullKeyException) {
+
+ return null;
+ }
+
+ return visRequestHandler;
+ }
+
+ private DataSource setupJENADataSource(Model model, VitroRequest vreq) {
+
+ log.debug("rdfResultFormat was: " + VisConstants.RDF_RESULT_FORMAT_PARAM);
+
+ DataSource dataSource = DatasetFactory.create();
+ ModelMaker maker = (ModelMaker) getServletContext().getAttribute("vitroJenaModelMaker");
+
+ dataSource.setDefaultModel(model);
+
+ return dataSource;
+ }
+
+}
+
diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationsDependencyInjector.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationsDependencyInjector.java
new file mode 100644
index 00000000..26147e8d
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/freemarker/VisualizationsDependencyInjector.java
@@ -0,0 +1,64 @@
+package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
+
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
+
+public class VisualizationsDependencyInjector {
+
+ private static Map visualizationIDsToClass;
+
+ /**
+ * This method is used to inject vis dependencies i.e. the vis algorithms that are
+ * being implemented into the vis controller. Modified Dependency Injection pattern is
+ * used here. XML file containing the location of all the vis is saved in accessible folder.
+ * @param servletContext
+ * @return
+ */
+ private synchronized static Map initVisualizations(
+ ServletContext servletContext) {
+
+ /*
+ * A visualization request has already been made causing the visualizationIDsToClass to be
+ * initiated & populated with visualization ids to its request handlers.
+ * */
+ if (visualizationIDsToClass != null) {
+ return visualizationIDsToClass;
+ }
+
+ String resourcePath =
+ servletContext
+ .getRealPath(VisualizationFrameworkConstants
+ .RELATIVE_LOCATION_OF_FM_VISUALIZATIONS_BEAN);
+
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "file:" + resourcePath);
+
+ BeanFactory factory = context;
+
+ VisualizationInjector visualizationInjector =
+ (VisualizationInjector) factory.getBean("visualizationInjector");
+
+ visualizationIDsToClass = visualizationInjector.getVisualizationIDToClass();
+
+
+ return visualizationIDsToClass;
+ }
+
+ public static Map getVisualizationIDsToClassMap(
+ ServletContext servletContext) {
+ if (visualizationIDsToClass != null) {
+ return visualizationIDsToClass;
+ } else {
+ return initVisualizations(servletContext);
+ }
+ }
+
+}
diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipGraphMLWriter.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipGraphMLWriter.java
new file mode 100644
index 00000000..0828f12e
--- /dev/null
+++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipGraphMLWriter.java
@@ -0,0 +1,332 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coauthorship;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.StandardVisualizationController;
+import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Edge;
+import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Node;
+
+public class CoAuthorshipGraphMLWriter {
+
+ private StringBuilder coAuthorshipGraphMLContent;
+
+ private final String GRAPHML_HEADER = "\n"
+ + " \n\n";
+
+ private final String GRAPHML_FOOTER = "";
+
+ public CoAuthorshipGraphMLWriter(CoAuthorshipData visVOContainer) {
+
+ coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer);
+
+ }
+
+ public StringBuilder getCoAuthorshipGraphMLContent() {
+ return coAuthorshipGraphMLContent;
+ }
+
+ private StringBuilder createCoAuthorshipGraphMLContent(
+ CoAuthorshipData coAuthorshipData) {
+
+ StringBuilder graphMLContent = new StringBuilder();
+
+ graphMLContent.append(GRAPHML_HEADER);
+
+ /*
+ * We are side-effecting "graphMLContent" object in this method since creating
+ * another String object to hold key definition data will be redundant & will
+ * not serve the purpose.
+ * */
+ generateKeyDefinitionContent(coAuthorshipData, graphMLContent);
+
+ /*
+ * Used to generate graph content. It will contain both the nodes & edge information.
+ * We are side-effecting "graphMLContent".
+ * */
+ generateGraphContent(coAuthorshipData, graphMLContent);
+
+ graphMLContent.append(GRAPHML_FOOTER);
+
+ return graphMLContent;
+ }
+
+ private void generateGraphContent(CoAuthorshipData coAuthorshipData,
+ StringBuilder graphMLContent) {
+
+ graphMLContent.append("\n\n");
+
+ if (coAuthorshipData.getNodes() != null & coAuthorshipData.getNodes().size() > 0) {
+ generateNodeSectionContent(coAuthorshipData, graphMLContent);
+ }
+
+ if (coAuthorshipData.getEdges() != null & coAuthorshipData.getEdges().size() > 0) {
+ generateEdgeSectionContent(coAuthorshipData, graphMLContent);
+ }
+
+ graphMLContent.append("\n");
+
+
+
+
+ }
+
+ private void generateEdgeSectionContent(CoAuthorshipData coAuthorshipData,
+ StringBuilder graphMLContent) {
+
+ graphMLContent.append("\n");
+
+ Set edges = coAuthorshipData.getEdges();
+
+ List orderedEdges = new ArrayList(edges);
+
+ Collections.sort(orderedEdges, new EdgeComparator());
+
+ for (Edge currentEdge : orderedEdges) {
+
+ /*
+ * This method actually creates the XML code for a single edge. "graphMLContent"
+ * is being side-effected.
+ * */
+ getEdgeContent(graphMLContent, currentEdge);
+
+ }
+
+ }
+
+ private void getEdgeContent(StringBuilder graphMLContent, Edge currentEdge) {
+
+ graphMLContent.append("\n");
+
+ graphMLContent.append("\t"
+ + currentEdge.getSourceNode().getNodeName()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + currentEdge.getTargetNode().getNodeName()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + currentEdge.getNumOfCoAuthoredWorks()
+ + "\n");
+
+ if (currentEdge.getEarliestCollaborationYearCount() != null) {
+
+ /*
+ * There is no clean way of getting the map contents in java even though
+ * we are sure to have only one entry on the map. So using the for loop.
+ * */
+ for (Map.Entry publicationInfo
+ : currentEdge.getEarliestCollaborationYearCount().entrySet()) {
+
+ graphMLContent.append("\t"
+ + publicationInfo.getKey()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + publicationInfo.getValue()
+ + "\n");
+ }
+
+ }
+
+ if (currentEdge.getLatestCollaborationYearCount() != null) {
+
+ for (Map.Entry publicationInfo
+ : currentEdge.getLatestCollaborationYearCount().entrySet()) {
+
+ graphMLContent.append("\t"
+ + publicationInfo.getKey()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + publicationInfo.getValue()
+ + "\n");
+ }
+
+ }
+
+ if (currentEdge.getUnknownCollaborationYearCount() != null) {
+
+ graphMLContent.append("\t"
+ + currentEdge.getUnknownCollaborationYearCount()
+ + "\n");
+
+ }
+
+ graphMLContent.append("\n");
+ }
+
+ private void generateNodeSectionContent(CoAuthorshipData coAuthorshipData,
+ StringBuilder graphMLContent) {
+
+ graphMLContent.append("\n");
+
+ Node egoNode = coAuthorshipData.getEgoNode();
+ Set authorNodes = coAuthorshipData.getNodes();
+
+ /*
+ * This method actually creates the XML code for a single node. "graphMLContent"
+ * is being side-effected. The egoNode is added first because this is the "requirement"
+ * of the co-author vis. Ego should always come first.
+ *
+ * */
+ getNodeContent(graphMLContent, egoNode);
+
+ List orderedAuthorNodes = new ArrayList(authorNodes);
+ orderedAuthorNodes.remove(egoNode);
+
+ Collections.sort(orderedAuthorNodes, new NodeComparator());
+
+
+ for (Node currNode : orderedAuthorNodes) {
+
+ /*
+ * We have already printed the Ego Node info.
+ * */
+ if (currNode != egoNode) {
+
+ getNodeContent(graphMLContent, currNode);
+
+ }
+
+ }
+
+ }
+
+ private void getNodeContent(StringBuilder graphMLContent, Node node) {
+
+ String profileURL = null;
+ try {
+ profileURL = VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX + "?"
+ + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ + "=" + URLEncoder.encode(node.getNodeURI(),
+ StandardVisualizationController
+ .URL_ENCODING_SCHEME).toString();
+ } catch (UnsupportedEncodingException e) {
+ System.err.println("URL Encoding ERRor. Move this to use log.error ASAP");
+ }
+
+ graphMLContent.append("\n");
+ graphMLContent.append("\t" + node.getNodeURI() + "\n");
+ graphMLContent.append("\t" + node.getNodeName() + "\n");
+
+ if (profileURL != null) {
+ graphMLContent.append("\t" + profileURL + "\n");
+ }
+
+
+ graphMLContent.append("\t"
+ + node.getNumOfAuthoredWorks()
+ + "\n");
+
+ if (node.getEarliestPublicationYearCount() != null) {
+
+ /*
+ * There is no clean way of getting the map contents in java even though
+ * we are sure to have only one entry on the map. So using the for loop.
+ * I am feeling dirty just about now.
+ * */
+ for (Map.Entry publicationInfo
+ : node.getEarliestPublicationYearCount().entrySet()) {
+
+ graphMLContent.append("\t"
+ + publicationInfo.getKey()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + publicationInfo.getValue()
+ + "\n");
+ }
+
+ }
+
+ if (node.getLatestPublicationYearCount() != null) {
+
+ for (Map.Entry publicationInfo
+ : node.getLatestPublicationYearCount().entrySet()) {
+
+ graphMLContent.append("\t"
+ + publicationInfo.getKey()
+ + "\n");
+
+ graphMLContent.append("\t"
+ + publicationInfo.getValue()
+ + "\n");
+ }
+
+ }
+
+ if (node.getUnknownPublicationYearCount() != null) {
+
+ graphMLContent.append("\t"
+ + node.getUnknownPublicationYearCount()
+ + "\n");
+
+ }
+
+ graphMLContent.append("\n");
+ }
+
+ private void generateKeyDefinitionContent(CoAuthorshipData visVOContainer,
+ StringBuilder graphMLContent) {
+
+ /*
+ * Generate the key definition content for node.
+ * */
+ getKeyDefinitionFromSchema(visVOContainer.getNodeSchema(), graphMLContent);
+
+ /*
+ * Generate the key definition content for edge.
+ * */
+ getKeyDefinitionFromSchema(visVOContainer.getEdgeSchema(), graphMLContent);
+
+
+ }
+
+ private void getKeyDefinitionFromSchema(Set |