1. Removed SOPs from the visualization codebase. Switched it with log.debugs.
2. Added person grant count & coauthorship to the freemarker version of dependency inhection bean. 3. Fixed a bug in garnt count freemarker. 4. Made use of urlbuilder instead of making urls by just encoding/appending parameters. 5. Add co-pi to the freemarker package. Completed the back-end conversion.
This commit is contained in:
parent
209c9b6a7b
commit
81855eddc2
22 changed files with 1845 additions and 415 deletions
|
@ -15,12 +15,18 @@
|
|||
<bean id="utilities"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.utilities.UtilitiesRequestHandler" />
|
||||
|
||||
<!--
|
||||
|
||||
<bean id="coauthorship"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipRequestHandler" />
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coauthorship.CoAuthorshipRequestHandler" />
|
||||
|
||||
<bean id="person_grant_count"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount.PersonGrantCountRequestHandler" />
|
||||
|
||||
<!--
|
||||
<bean id="person_level"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.personlevel.PersonLevelRequestHandler" />
|
||||
|
||||
|
||||
<bean id="entity_comparison"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" />
|
||||
<bean id="coprincipalinvestigator"
|
||||
|
@ -38,10 +44,16 @@
|
|||
<entry key="utilities">
|
||||
<ref bean="utilities"></ref>
|
||||
</entry>
|
||||
<!--
|
||||
|
||||
<entry key="coauthorship">
|
||||
<ref bean="coauthorship"></ref>
|
||||
</entry>
|
||||
|
||||
<entry key="person_grant_count">
|
||||
<ref bean="person_grant_count"></ref>
|
||||
</entry>
|
||||
|
||||
<!--
|
||||
<entry key="person_level">
|
||||
<ref bean="person_level"></ref>
|
||||
</entry>
|
||||
|
|
|
@ -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 grant count, hence we filter
|
||||
the data we actually want to use for render. -->
|
||||
|
||||
|
@ -78,14 +76,10 @@
|
|||
column: 0,
|
||||
minValue: '${sparklineVO.earliestRenderedGrantYear?c}',
|
||||
maxValue: '${sparklineVO.latestRenderedGrantYear?c}'
|
||||
/*minValue: '2001',
|
||||
maxValue: '2011'*/
|
||||
}]));
|
||||
|
||||
<#else>
|
||||
|
||||
console.log("Yay! Full Vis Mode!");
|
||||
|
||||
</#if>
|
||||
|
||||
<#-- Create the vis object and draw it in the div pertaining to sparkline. -->
|
||||
|
@ -130,6 +124,7 @@
|
|||
|
||||
$('#${sparklineContainerID} td.sparkline_text').html(sparksText);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This will activate the visualization. It takes care of creating
|
||||
|
|
|
@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
|
||||
// QuerySolutionMap qs = new QuerySolutionMap();
|
||||
// qs.add("authPerson", queryParam); // bind resource to s
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
||||
// if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
|
||||
|
@ -455,7 +442,7 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
+ "} "
|
||||
+ "ORDER BY ?document ?coAuthorPerson";
|
||||
|
||||
System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
|
||||
log.debug("COAUTHORSHIP QUERY - " + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
+ "?CoPI rdfs:label ?CoPILabel . "
|
||||
+ " }";
|
||||
|
||||
System.out.println("COPI QUERY - " + sparqlQuery);
|
||||
log.debug("COPI QUERY - " + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
@ -100,20 +100,10 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
private ResultSet executeQuery(String queryText, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
||||
// if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
public CoPIData getQueryResult()
|
||||
|
@ -137,7 +127,6 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
|
||||
ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI),
|
||||
this.dataSource);
|
||||
System.out.println("ResultSet ");
|
||||
return createQueryResult(resultSet);
|
||||
}
|
||||
|
||||
|
@ -202,8 +191,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
egoNode.setNodeName(authorLabelNode.toString());
|
||||
}
|
||||
}
|
||||
System.out.println("\n----------------------------------");
|
||||
System.out.println("PI: "+ egoNode.getIndividualLabel());
|
||||
log.debug("PI: "+ egoNode.getIndividualLabel());
|
||||
|
||||
RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL);
|
||||
Grant grant;
|
||||
|
@ -216,7 +204,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
}
|
||||
|
||||
egoNode.addGrant(grant);
|
||||
System.out.println("Adding grant: "+ grant.getIndividualLabel());
|
||||
log.debug("Adding grant: "+ grant.getIndividualLabel());
|
||||
|
||||
/*
|
||||
* After some discussion we concluded that for the purpose of this visualization
|
||||
|
@ -247,7 +235,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
}
|
||||
}
|
||||
|
||||
System.out.println("Adding CO-PI: "+ coPINode.getIndividualLabel());
|
||||
log.debug("Adding CO-PI: "+ coPINode.getIndividualLabel());
|
||||
coPINode.addGrant(grant);
|
||||
|
||||
Set<CoPINode> coPIsForCurrentGrant;
|
||||
|
@ -262,10 +250,9 @@ public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
|||
}
|
||||
|
||||
coPIsForCurrentGrant.add(coPINode);
|
||||
System.out.println("Co-PI for current grant : "+ coPINode.getIndividualLabel());
|
||||
log.debug("Co-PI for current grant : "+ coPINode.getIndividualLabel());
|
||||
|
||||
CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO);
|
||||
System.out.println("\n----------------------------------");
|
||||
/*
|
||||
* If "egoCoPIEdge" is null it means that no edge exists in between the egoNode
|
||||
* & current coPINode. Else create a new edge, add it to the edges set & add
|
||||
|
|
|
@ -166,22 +166,11 @@ public class EntityPublicationCountQueryRunner implements QueryRunner<Entity> {
|
|||
private ResultSet executeQuery(String queryURI, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI, this.visMode), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
||||
return queryExecution.execSelect();
|
||||
// if (query.isSelectType()) {
|
||||
// return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI, this.visMode), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
private String getSparqlQuery(String queryURI, String visMode) {
|
||||
String result = "";
|
||||
|
@ -281,7 +270,7 @@ public class EntityPublicationCountQueryRunner implements QueryRunner<Entity> {
|
|||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}"
|
||||
+ "}";
|
||||
|
||||
System.out.println("\nThe sparql query is :\n" + sparqlQuery);
|
||||
log.debug("\nThe sparql query is :\n" + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison;
|
|||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
|
@ -16,17 +16,16 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Entity;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.JsonObject;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SubEntity;
|
||||
|
@ -45,7 +44,6 @@ public class EntityPublicationCountRequestHandler implements
|
|||
public static String SUB_ENTITY_VIS_MODE;
|
||||
|
||||
|
||||
@SuppressWarnings("null")
|
||||
public void generateVisualization(VitroRequest vitroRequest,
|
||||
HttpServletRequest request, HttpServletResponse response, Log log,
|
||||
DataSource dataSource) {
|
||||
|
@ -91,13 +89,13 @@ public class EntityPublicationCountRequestHandler implements
|
|||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult, response);
|
||||
prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult, response, log);
|
||||
|
||||
} else if (VisualizationFrameworkConstants.STANDALONE_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
prepareStandaloneResponse(request, response, vitroRequest,
|
||||
entity, subOrganizationTypesResult);
|
||||
entity, subOrganizationTypesResult, log);
|
||||
requestDispatcher = request
|
||||
.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
}
|
||||
|
@ -135,9 +133,10 @@ public class EntityPublicationCountRequestHandler implements
|
|||
* @param subOrganizationTypesResult
|
||||
* @param yearToPublicationCount
|
||||
* @param response
|
||||
* @param log
|
||||
*/
|
||||
private void prepareDataResponse(Entity entity, Set<SubEntity> subentities,
|
||||
Map<String, Set<String>> subOrganizationTypesResult, HttpServletResponse response) {
|
||||
Map<String, Set<String>> subOrganizationTypesResult, HttpServletResponse response, Log log) {
|
||||
|
||||
String entityLabel = entity.getEntityLabel();
|
||||
|
||||
|
@ -156,7 +155,7 @@ public class EntityPublicationCountRequestHandler implements
|
|||
* We are side-effecting responseWriter since we are directly
|
||||
* manipulating the response object of the servlet.
|
||||
*/
|
||||
responseWriter.append(writePublicationsOverTimeJSON(subentities, subOrganizationTypesResult));
|
||||
responseWriter.append(writePublicationsOverTimeJSON(subentities, subOrganizationTypesResult, log));
|
||||
|
||||
responseWriter.flush();
|
||||
responseWriter.close();
|
||||
|
@ -175,9 +174,10 @@ public class EntityPublicationCountRequestHandler implements
|
|||
* @param vreq
|
||||
* @param entity
|
||||
* @param subOrganizationTypesResult
|
||||
* @param log
|
||||
*/
|
||||
private void prepareStandaloneResponse(HttpServletRequest request,
|
||||
HttpServletResponse response, VitroRequest vreq, Entity entity, Map<String, Set<String>> subOrganizationTypesResult) {
|
||||
HttpServletResponse response, VitroRequest vreq, Entity entity, Map<String, Set<String>> subOrganizationTypesResult, Log log) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
String jsonContent = "";
|
||||
|
@ -185,7 +185,7 @@ public class EntityPublicationCountRequestHandler implements
|
|||
* We are side-effecting responseWriter since we are directly
|
||||
* manipulating the response object of the servlet.
|
||||
*/
|
||||
jsonContent = writePublicationsOverTimeJSON(entity.getSubEntities(), subOrganizationTypesResult);
|
||||
jsonContent = writePublicationsOverTimeJSON(entity.getSubEntities(), subOrganizationTypesResult, log);
|
||||
|
||||
request.setAttribute("JsonContent", jsonContent);
|
||||
|
||||
|
@ -201,15 +201,16 @@ public class EntityPublicationCountRequestHandler implements
|
|||
/**
|
||||
* function to generate a json file for year <-> publication count mapping
|
||||
* @param subOrganizationTypesResult
|
||||
* @param log
|
||||
*
|
||||
* @param yearToPublicationCount
|
||||
* @param responseWriter
|
||||
* @param visMode
|
||||
*/
|
||||
private String writePublicationsOverTimeJSON(Set<SubEntity> subentities, Map<String, Set<String>> subOrganizationTypesResult) {
|
||||
private String writePublicationsOverTimeJSON(Set<SubEntity> subentities, Map<String, Set<String>> subOrganizationTypesResult, Log log) {
|
||||
// System.out.println("\nsub entity vis mode ------>"
|
||||
// + SUB_ENTITY_VIS_MODE + "\n");
|
||||
System.out.println("Creating JSONObject \n-----------------------");
|
||||
log.debug("Creating JSONObject \n-----------------------");
|
||||
Gson json = new Gson();
|
||||
Set<JsonObject> subEntitiesJson = new HashSet<JsonObject>();
|
||||
|
||||
|
@ -239,7 +240,7 @@ public class EntityPublicationCountRequestHandler implements
|
|||
entityJson.setEntityURI(subentity.getIndividualURI());
|
||||
setEntityVisMode(entityJson);
|
||||
//entityJson.setVisMode(SUB_ENTITY_VIS_MODE);
|
||||
System.out.println("Adding object with uri: "
|
||||
log.debug("Adding object with uri: "
|
||||
+ entityJson.getEntityURI() + " vismode: "
|
||||
+ entityJson.getVisMode() + " label: "
|
||||
+ entityJson.getLabel() + " type: "
|
||||
|
|
|
@ -74,20 +74,10 @@ public class EntitySubOrganizationTypesQueryRunner implements QueryRunner<Map<St
|
|||
private ResultSet executeQuery(String queryURI, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
||||
// if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
private String getSparqlQuery(String queryURI) {
|
||||
|
@ -133,7 +123,7 @@ public class EntitySubOrganizationTypesQueryRunner implements QueryRunner<Map<St
|
|||
+ " ?personType rdfs:label ?personTypeLabel ."
|
||||
+ "}";;
|
||||
}
|
||||
System.out.println("\nThe sparql query is :\n" + sparqlQuery);
|
||||
log.debug("\nThe sparql query is :\n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
|
||||
}
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
|
||||
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.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
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;
|
||||
|
@ -29,13 +28,7 @@ public class CoAuthorshipGraphMLWriter {
|
|||
private final String GRAPHML_FOOTER = "</graphml>";
|
||||
|
||||
public CoAuthorshipGraphMLWriter(CoAuthorshipData visVOContainer) {
|
||||
|
||||
coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer);
|
||||
|
||||
}
|
||||
|
||||
public StringBuilder getCoAuthorshipGraphMLContent() {
|
||||
return coAuthorshipGraphMLContent;
|
||||
}
|
||||
|
||||
private StringBuilder createCoAuthorshipGraphMLContent(
|
||||
|
@ -63,6 +56,10 @@ public class CoAuthorshipGraphMLWriter {
|
|||
return graphMLContent;
|
||||
}
|
||||
|
||||
public StringBuilder getCoAuthorshipGraphMLContent() {
|
||||
return coAuthorshipGraphMLContent;
|
||||
}
|
||||
|
||||
private void generateGraphContent(CoAuthorshipData coAuthorshipData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
|
@ -77,10 +74,6 @@ public class CoAuthorshipGraphMLWriter {
|
|||
}
|
||||
|
||||
graphMLContent.append("</graph>\n");
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void generateEdgeSectionContent(CoAuthorshipData coAuthorshipData,
|
||||
|
@ -101,9 +94,7 @@ public class CoAuthorshipGraphMLWriter {
|
|||
* is being side-effected.
|
||||
* */
|
||||
getEdgeContent(graphMLContent, currentEdge);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getEdgeContent(StringBuilder graphMLContent, Edge currentEdge) {
|
||||
|
@ -212,16 +203,11 @@ public class CoAuthorshipGraphMLWriter {
|
|||
|
||||
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");
|
||||
}
|
||||
ParamMap individualProfileURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
node.getNodeURI());
|
||||
|
||||
String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX,
|
||||
individualProfileURLParams);
|
||||
|
||||
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
|
||||
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");
|
||||
|
|
|
@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
|
||||
// QuerySolutionMap qs = new QuerySolutionMap();
|
||||
// qs.add("authPerson", queryParam); // bind resource to s
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
System.out.println("\n\nquery.isSelectType() is "+ query.isSelectType()+ " \n\n");
|
||||
// if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
|
||||
|
|
|
@ -190,10 +190,6 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
|
|||
*/
|
||||
private Map<String, String> prepareNetworkDataResponse(CoAuthorshipData authorNodesAndEdges) {
|
||||
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||
* object of the servlet.
|
||||
* */
|
||||
CoAuthorshipGraphMLWriter coAuthorshipGraphMLWriter =
|
||||
new CoAuthorshipGraphMLWriter(authorNodesAndEdges);
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
|
||||
|
||||
|
||||
/**
|
||||
* This Comparator is used to sort the edges based on their IDs in ascending order.
|
||||
* @author bkoniden
|
||||
*
|
||||
*/
|
||||
public class CoPIEdgeComparator implements Comparator<CoPIEdge> {
|
||||
|
||||
@Override
|
||||
public int compare(CoPIEdge arg0, CoPIEdge arg1) {
|
||||
return arg0.getEdgeID() - arg1.getEdgeID();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,437 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.iri.IRI;
|
||||
import com.hp.hpl.jena.iri.IRIFactory;
|
||||
import com.hp.hpl.jena.iri.Violation;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.Query;
|
||||
import com.hp.hpl.jena.query.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||
import com.hp.hpl.jena.query.QueryFactory;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UniqueIDGenerator;
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
||||
|
||||
private static final int MAX_PI_PER_GRANT_ALLOWED = 100;
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String egoURI;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private Log log;
|
||||
|
||||
private UniqueIDGenerator nodeIDGenerator;
|
||||
|
||||
private UniqueIDGenerator edgeIDGenerator;
|
||||
|
||||
public CoPIGrantCountQueryRunner(String egoURI,
|
||||
DataSource dataSource, Log log) {
|
||||
|
||||
this.egoURI = egoURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
|
||||
this.nodeIDGenerator = new UniqueIDGenerator();
|
||||
this.edgeIDGenerator = new UniqueIDGenerator();
|
||||
|
||||
}
|
||||
|
||||
private String generateEgoCoPIquery(String queryURI) {
|
||||
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT "
|
||||
+ " (str(<" + queryURI + ">) as ?" + QueryFieldLabels.PI_URL + ") "
|
||||
+ " (str(?PILabel) as ?" + QueryFieldLabels.PI_LABEL + ") "
|
||||
+ " (str(?Grant) as ?" + QueryFieldLabels.GRANT_URL + ") "
|
||||
+ " (str(?GrantLabel) as ?" + QueryFieldLabels.GRANT_LABEL + ") "
|
||||
+ " (str(?GrantStartDate) as ?" + QueryFieldLabels.GRANT_START_DATE + ") "
|
||||
+ " (str(?GrantEndDate) as ?" + QueryFieldLabels.GRANT_END_DATE + ") "
|
||||
+ " (str(?CoPI) as ?" + QueryFieldLabels.CO_PI_URL + ") "
|
||||
+ " (str(?CoPILabel) as ?" + QueryFieldLabels.CO_PI_LABEL + ") "
|
||||
+ "WHERE { "
|
||||
+ "<" + queryURI + "> rdfs:label ?PILabel ;"
|
||||
+ " core:hasCo-PrincipalInvestigatorRole ?Role . "
|
||||
+ "?Role core:roleIn ?Grant . "
|
||||
+ "?Grant rdfs:label ?GrantLabel ; "
|
||||
+ "core:startDate ?GrantStartDate ; "
|
||||
+ "core:endDate ?GrantEndDate ;"
|
||||
+ "core:relatedRole ?RelatedRole . "
|
||||
+ "?RelatedRole core:co-PrincipalInvestigatorRoleOf ?CoPI . "
|
||||
+ "?CoPI rdfs:label ?CoPILabel . "
|
||||
+ " }";
|
||||
|
||||
log.debug("COPI QUERY - " + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryText, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
|
||||
public CoPIData getQueryResult()
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.egoURI)) {
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
* */
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
IRI iri = iRIFactory.create(this.egoURI);
|
||||
if (iri.hasViolation(false)) {
|
||||
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
|
||||
log.error("Ego Co-PI Vis Query " + errorMsg);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an individual is malformed.");
|
||||
}
|
||||
} else {
|
||||
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI),
|
||||
this.dataSource);
|
||||
return createQueryResult(resultSet);
|
||||
}
|
||||
|
||||
|
||||
private CoPIEdge getExistingEdge(
|
||||
CoPINode collaboratingNode1,
|
||||
CoPINode collaboratingNode2,
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
|
||||
|
||||
String edgeUniqueIdentifier = getEdgeUniqueIdentifier(collaboratingNode1.getNodeID(),
|
||||
collaboratingNode2.getNodeID());
|
||||
|
||||
return edgeUniqueIdentifierToVO.get(edgeUniqueIdentifier);
|
||||
|
||||
}
|
||||
|
||||
private String getEdgeUniqueIdentifier(int nodeID1, int nodeID2) {
|
||||
|
||||
String separator = "*";
|
||||
|
||||
if (nodeID1 < nodeID2) {
|
||||
return nodeID1 + separator + nodeID2;
|
||||
} else {
|
||||
return nodeID2 + separator + nodeID1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CoPIData createQueryResult(ResultSet resultSet) {
|
||||
|
||||
Set<CoPINode> nodes = new HashSet<CoPINode>();
|
||||
|
||||
Map<String, Grant> grantURLToVO = new HashMap<String, Grant>();
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs = new HashMap<String, Set<CoPINode>>();
|
||||
Map<String, CoPINode> nodeURLToVO = new HashMap<String, CoPINode>();
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO = new HashMap<String, CoPIEdge>();
|
||||
|
||||
CoPINode egoNode = null;
|
||||
|
||||
Set<CoPIEdge> edges = new HashSet<CoPIEdge>();
|
||||
|
||||
while (resultSet.hasNext()) {
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
/*
|
||||
* We only want to create only ONE ego node.
|
||||
* */
|
||||
RDFNode egoPIURLNode = solution.get(QueryFieldLabels.PI_URL);
|
||||
if (nodeURLToVO.containsKey(egoPIURLNode.toString())) {
|
||||
|
||||
egoNode = nodeURLToVO.get(egoPIURLNode.toString());
|
||||
|
||||
} else {
|
||||
|
||||
egoNode = new CoPINode(egoPIURLNode.toString(), nodeIDGenerator);
|
||||
nodes.add(egoNode);
|
||||
nodeURLToVO.put(egoPIURLNode.toString(), egoNode);
|
||||
|
||||
|
||||
RDFNode authorLabelNode = solution.get(QueryFieldLabels.PI_LABEL);
|
||||
if (authorLabelNode != null) {
|
||||
egoNode.setNodeName(authorLabelNode.toString());
|
||||
}
|
||||
}
|
||||
log.debug("PI: "+ egoNode.getIndividualLabel());
|
||||
|
||||
RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL);
|
||||
Grant grant;
|
||||
|
||||
if (grantURLToVO.containsKey(grantNode.toString())) {
|
||||
grant = grantURLToVO.get(grantNode.toString());
|
||||
} else {
|
||||
grant = createGrantVO(solution, grantNode.toString());
|
||||
grantURLToVO.put(grantNode.toString(), grant);
|
||||
}
|
||||
|
||||
egoNode.addGrant(grant);
|
||||
log.debug("Adding grant: "+ grant.getIndividualLabel());
|
||||
|
||||
/*
|
||||
* After some discussion we concluded that for the purpose of this visualization
|
||||
* we do not want a co-pi node or edge if the grant has only one
|
||||
* pi and that happens to be the ego.
|
||||
* */
|
||||
if (solution.get(QueryFieldLabels.PI_URL).toString().equalsIgnoreCase(
|
||||
solution.get(QueryFieldLabels.CO_PI_URL).toString())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CoPINode coPINode;
|
||||
|
||||
RDFNode coPIURLNode = solution.get(QueryFieldLabels.CO_PI_URL);
|
||||
if (nodeURLToVO.containsKey(coPIURLNode.toString())) {
|
||||
|
||||
coPINode = nodeURLToVO.get(coPIURLNode.toString());
|
||||
|
||||
} else {
|
||||
|
||||
coPINode = new CoPINode(coPIURLNode.toString(), nodeIDGenerator);
|
||||
nodes.add(coPINode);
|
||||
nodeURLToVO.put(coPIURLNode.toString(), coPINode);
|
||||
|
||||
RDFNode coPILabelNode = solution.get(QueryFieldLabels.CO_PI_LABEL);
|
||||
if (coPILabelNode != null) {
|
||||
coPINode.setNodeName(coPILabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Adding CO-PI: "+ coPINode.getIndividualLabel());
|
||||
coPINode.addGrant(grant);
|
||||
|
||||
Set<CoPINode> coPIsForCurrentGrant;
|
||||
|
||||
if (grantURLToCoPIs.containsKey(grant.getGrantURL())) {
|
||||
coPIsForCurrentGrant = grantURLToCoPIs
|
||||
.get(grant.getGrantURL());
|
||||
} else {
|
||||
coPIsForCurrentGrant = new HashSet<CoPINode>();
|
||||
grantURLToCoPIs.put(grant.getGrantURL(),
|
||||
coPIsForCurrentGrant);
|
||||
}
|
||||
|
||||
coPIsForCurrentGrant.add(coPINode);
|
||||
log.debug("Co-PI for current grant : "+ coPINode.getIndividualLabel());
|
||||
|
||||
CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO);
|
||||
/*
|
||||
* If "egoCoPIEdge" is null it means that no edge exists in between the egoNode
|
||||
* & current coPINode. Else create a new edge, add it to the edges set & add
|
||||
* the collaborator grant to it.
|
||||
* */
|
||||
if (egoCoPIEdge != null) {
|
||||
egoCoPIEdge.addCollaboratorGrant(grant);
|
||||
} else {
|
||||
egoCoPIEdge = new CoPIEdge(egoNode, coPINode, grant, edgeIDGenerator);
|
||||
edges.add(egoCoPIEdge);
|
||||
edgeUniqueIdentifierToVO.put(
|
||||
getEdgeUniqueIdentifier(egoNode.getNodeID(),
|
||||
coPINode.getNodeID()),
|
||||
egoCoPIEdge);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This method takes out all the PIs & edges between PIs that belong to grants
|
||||
* that have more than 100 PIs. We conjecture that these grants do not provide much
|
||||
* insight. However, we have left the grants be.
|
||||
*
|
||||
* This method side-effects "nodes" & "edges".
|
||||
* */
|
||||
removeLowQualityNodesAndEdges(nodes,
|
||||
grantURLToVO,
|
||||
grantURLToCoPIs,
|
||||
edges);
|
||||
/*
|
||||
* We need to create edges between 2 co-PIs. E.g. On a grant there were 3 PI
|
||||
* ego, A & B then we have already created edges like,
|
||||
* ego - A
|
||||
* ego - B
|
||||
* The below sub-routine will take care of,
|
||||
* A - B
|
||||
*
|
||||
* We are side-effecting "edges" here. The only reason to do this is because we are adding
|
||||
* edges en masse for all the co-PIs on all the grants considered so far. The
|
||||
* other reason being we dont want to compare against 2 sets of edges (edges created before
|
||||
* & co-PI edges created during the course of this method) when we are creating a new
|
||||
* edge.
|
||||
* */
|
||||
createCoPIEdges(grantURLToVO,
|
||||
grantURLToCoPIs,
|
||||
edges,
|
||||
edgeUniqueIdentifierToVO);
|
||||
|
||||
|
||||
return new CoPIData(egoNode, nodes, edges);
|
||||
}
|
||||
|
||||
private void createCoPIEdges(Map<String, Grant> grantURLToVO,
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges,
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
|
||||
|
||||
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
|
||||
: grantURLToCoPIs.entrySet()) {
|
||||
|
||||
/*
|
||||
* If there was only one co-PI (other than ego) then we dont have to create any
|
||||
* edges. so the below condition will take care of that.
|
||||
*
|
||||
* We are restricting edges between co-PI if a particular grant has more than
|
||||
* 100 co-PIs. Our conjecture is that such edges do not provide any good insight
|
||||
* & causes unnecessary computations causing the server to time-out.
|
||||
* */
|
||||
if (currentGrantEntry.getValue().size() > 1
|
||||
&& currentGrantEntry.getValue().size()
|
||||
<= MAX_PI_PER_GRANT_ALLOWED) {
|
||||
|
||||
|
||||
Set<CoPIEdge> newlyAddedEdges = new HashSet<CoPIEdge>();
|
||||
|
||||
/*
|
||||
* In order to leverage the nested "for loop" for making edges between all the
|
||||
* co-PIs we need to create a list out of the set first.
|
||||
* */
|
||||
List<CoPINode> coPINodes = new ArrayList<CoPINode>(currentGrantEntry.getValue());
|
||||
Collections.sort(coPINodes, new CoPINodeComparator());
|
||||
|
||||
int numOfCoPIs = coPINodes.size();
|
||||
|
||||
for (int ii = 0; ii < numOfCoPIs - 1; ii++) {
|
||||
for (int jj = ii + 1; jj < numOfCoPIs; jj++) {
|
||||
|
||||
CoPINode coPI1 = coPINodes.get(ii);
|
||||
CoPINode coPI2 = coPINodes.get(jj);
|
||||
|
||||
CoPIEdge coPI1_2Edge = getExistingEdge(coPI1,
|
||||
coPI2,
|
||||
edgeUniqueIdentifierToVO);
|
||||
|
||||
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
|
||||
|
||||
if (coPI1_2Edge != null) {
|
||||
coPI1_2Edge.addCollaboratorGrant(currentGrant);
|
||||
} else {
|
||||
coPI1_2Edge = new CoPIEdge(coPI1,
|
||||
coPI2,
|
||||
currentGrant,
|
||||
edgeIDGenerator);
|
||||
newlyAddedEdges.add(coPI1_2Edge);
|
||||
edgeUniqueIdentifierToVO.put(
|
||||
getEdgeUniqueIdentifier(coPI1.getNodeID(),
|
||||
coPI2.getNodeID()),
|
||||
coPI1_2Edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
edges.addAll(newlyAddedEdges);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void removeLowQualityNodesAndEdges(Set<CoPINode> nodes,
|
||||
Map<String, Grant> grantURLToVO,
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges) {
|
||||
|
||||
Set<CoPINode> nodesToBeRemoved = new HashSet<CoPINode>();
|
||||
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
|
||||
: grantURLToCoPIs.entrySet()) {
|
||||
|
||||
if (currentGrantEntry.getValue().size() > MAX_PI_PER_GRANT_ALLOWED) {
|
||||
|
||||
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
|
||||
|
||||
Set<CoPIEdge> edgesToBeRemoved = new HashSet<CoPIEdge>();
|
||||
|
||||
for (CoPIEdge currentEdge : edges) {
|
||||
Set<Grant> currentCollaboratorGrants =
|
||||
currentEdge.getCollaboratorGrants();
|
||||
|
||||
if (currentCollaboratorGrants.contains(currentGrant)) {
|
||||
currentCollaboratorGrants.remove(currentGrant);
|
||||
if (currentCollaboratorGrants.isEmpty()) {
|
||||
edgesToBeRemoved.add(currentEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edges.removeAll(edgesToBeRemoved);
|
||||
|
||||
for (CoPINode currentCoPI : currentGrantEntry.getValue()) {
|
||||
currentCoPI.getInvestigatedGrants().remove(currentGrant);
|
||||
if (currentCoPI.getInvestigatedGrants().isEmpty()) {
|
||||
nodesToBeRemoved.add(currentCoPI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes.removeAll(nodesToBeRemoved);
|
||||
|
||||
}
|
||||
|
||||
private Grant createGrantVO(QuerySolution solution, String grantURL) {
|
||||
|
||||
Grant grant = new Grant(grantURL);
|
||||
|
||||
RDFNode grantLabelNode = solution.get(QueryFieldLabels.GRANT_LABEL);
|
||||
if (grantLabelNode != null) {
|
||||
grant.setIndividualLabel(grantLabelNode.toString());
|
||||
}
|
||||
|
||||
|
||||
RDFNode grantStartYear = solution.get(QueryFieldLabels.GRANT_START_DATE);
|
||||
if (grantStartYear != null) {
|
||||
grant.setGrantStartDate(grantStartYear.toString());
|
||||
}
|
||||
|
||||
RDFNode grantEndDate = solution.get(QueryFieldLabels
|
||||
.GRANT_END_DATE);
|
||||
if (grantEndDate != null) {
|
||||
grant.setGrantEndDate(grantEndDate.toString());
|
||||
}
|
||||
|
||||
return grant;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
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.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DataVisualizationController;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler{
|
||||
|
||||
|
||||
@Override
|
||||
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
|
||||
DataSource dataSource) throws MalformedQueryParametersException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> generateDataVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
||||
QueryRunner<CoPIData> queryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
CoPIData PINodesAndEdges = queryManager.getQueryResult();
|
||||
|
||||
if (VisualizationFrameworkConstants.COPI_VIS_MODE
|
||||
.equalsIgnoreCase(visMode)) {
|
||||
|
||||
return prepareCoPIDataResponse(PINodesAndEdges);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* When the graphML file is required - based on which copi network
|
||||
* visualization will be rendered.
|
||||
* */
|
||||
return prepareNetworkDataResponse(PINodesAndEdges);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseValues generateStandardVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
|
||||
QueryRunner<CoPIData> queryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
CoPIData PINodesAndEdges = queryManager.getQueryResult();
|
||||
|
||||
return prepareStandaloneResponse(egoURI,
|
||||
PINodesAndEdges,
|
||||
vitroRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the page for person level visualization is requested.
|
||||
* @param egoURI
|
||||
* @param vitroRequest
|
||||
* @param coPIVO
|
||||
*/
|
||||
private TemplateResponseValues prepareStandaloneResponse(String egoURI,
|
||||
CoPIData pINodesAndEdges, VitroRequest vitroRequest) {
|
||||
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
|
||||
String title = "";
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
|
||||
if (pINodesAndEdges.getNodes() != null
|
||||
&& pINodesAndEdges.getNodes().size() > 0) {
|
||||
body.put("numOfAuthors", pINodesAndEdges.getNodes().size());
|
||||
|
||||
title = pINodesAndEdges.getEgoNode().getNodeName() + " - ";
|
||||
}
|
||||
|
||||
if (pINodesAndEdges.getEdges() != null
|
||||
&& pINodesAndEdges.getEdges().size() > 0) {
|
||||
body.put("numOfCoPIs", pINodesAndEdges.getEdges().size());
|
||||
}
|
||||
|
||||
String standaloneTemplate = "/visualization/coauthorship/coAuthorship.ftl";
|
||||
|
||||
body.put("portalBean", portal);
|
||||
body.put("egoURIParam", egoURI);
|
||||
body.put("title", title + "Co-PI Visualization");
|
||||
|
||||
return new TemplateResponseValues(standaloneTemplate, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a response when graphml formatted co-pi network is requested, typically by
|
||||
* the flash vis.
|
||||
* @param pINodesAndEdges
|
||||
*/
|
||||
private Map<String, String> prepareNetworkDataResponse(CoPIData pINodesAndEdges) {
|
||||
|
||||
CoPIGraphMLWriter coPIGraphMLWriter =
|
||||
new CoPIGraphMLWriter(pINodesAndEdges);
|
||||
|
||||
Map<String, String> fileData = new HashMap<String, String>();
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
|
||||
"text/xml");
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
|
||||
coPIGraphMLWriter.getCoPIGraphMLContent().toString());
|
||||
|
||||
return fileData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when a csv file containing number & names of unique co-pis per
|
||||
* year is requested.
|
||||
* @param pINodesAndEdges
|
||||
*/
|
||||
private Map<String, String> prepareCoPIDataResponse(CoPIData pINodesAndEdges) {
|
||||
|
||||
String outputFileName;
|
||||
Map<String, Set<CoPINode>> yearToCoPI = new TreeMap<String, Set<CoPINode>>();
|
||||
|
||||
if (pINodesAndEdges.getNodes() != null && pINodesAndEdges.getNodes().size() > 0) {
|
||||
|
||||
outputFileName = UtilityFunctions.slugify(pINodesAndEdges
|
||||
.getEgoNode().getNodeName())
|
||||
+ "_copis-per-year" + ".csv";
|
||||
|
||||
yearToCoPI = UtilityFunctions.getGrantYearToCoPI(pINodesAndEdges);
|
||||
|
||||
} else {
|
||||
|
||||
outputFileName = "no_copis-per-year" + ".csv";
|
||||
}
|
||||
|
||||
|
||||
Map<String, String> fileData = new HashMap<String, String>();
|
||||
fileData.put(DataVisualizationController.FILE_NAME_KEY,
|
||||
outputFileName);
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
|
||||
"application/octet-stream");
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
|
||||
getCoPIsPerYearCSVContent(yearToCoPI));
|
||||
|
||||
return fileData;
|
||||
}
|
||||
|
||||
private String getCoPIsPerYearCSVContent(Map<String, Set<CoPINode>> yearToCoPI) {
|
||||
|
||||
StringBuilder csvFileContent = new StringBuilder();
|
||||
|
||||
csvFileContent.append("Year, Count, Co-PI(s)\n");
|
||||
|
||||
for (Map.Entry<String, Set<CoPINode>> currentEntry : yearToCoPI.entrySet()) {
|
||||
|
||||
csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey()));
|
||||
csvFileContent.append(",");
|
||||
csvFileContent.append(currentEntry.getValue().size());
|
||||
csvFileContent.append(",");
|
||||
csvFileContent.append(StringEscapeUtils.escapeCsv(getCoPINamesAsString(currentEntry.getValue())));
|
||||
csvFileContent.append("\n");
|
||||
}
|
||||
|
||||
return csvFileContent.toString();
|
||||
}
|
||||
|
||||
private String getCoPINamesAsString(Set<CoPINode> CoPIs) {
|
||||
|
||||
StringBuilder coPIsMerged = new StringBuilder();
|
||||
|
||||
String coPISeparator = ";";
|
||||
for(CoPINode currentCoPI : CoPIs){
|
||||
coPIsMerged.append(currentCoPI.getNodeName() + coPISeparator);
|
||||
}
|
||||
|
||||
return StringUtils.removeEnd(coPIsMerged.toString(), coPISeparator);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
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.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIEdge;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class CoPIGraphMLWriter {
|
||||
|
||||
private StringBuilder coPIGraphMLContent;
|
||||
|
||||
private final String GRAPHML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ " <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n"
|
||||
+ " http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n\n";
|
||||
|
||||
private final String GRAPHML_FOOTER = "</graphml>";
|
||||
|
||||
public CoPIGraphMLWriter(CoPIData coPIData){
|
||||
coPIGraphMLContent = createCoPIGraphMLContent(coPIData);
|
||||
}
|
||||
|
||||
private StringBuilder createCoPIGraphMLContent(CoPIData coPIData) {
|
||||
|
||||
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(coPIData, graphMLContent);
|
||||
|
||||
/*
|
||||
* Used to generate graph content. It will contain both the nodes & edge information.
|
||||
* We are side-effecting "graphMLContent".
|
||||
* */
|
||||
generateGraphContent(coPIData, graphMLContent);
|
||||
|
||||
graphMLContent.append(GRAPHML_FOOTER);
|
||||
|
||||
return graphMLContent;
|
||||
}
|
||||
|
||||
public StringBuilder getCoPIGraphMLContent(){
|
||||
return coPIGraphMLContent;
|
||||
}
|
||||
|
||||
private void generateGraphContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("\n<graph edgedefault=\"undirected\">\n");
|
||||
|
||||
if (coPIData.getNodes() != null & coPIData.getNodes().size() > 0) {
|
||||
generateNodeSectionContent(coPIData, graphMLContent);
|
||||
}
|
||||
|
||||
if (coPIData.getEdges() != null & coPIData.getEdges().size() > 0) {
|
||||
generateEdgeSectionContent(coPIData, graphMLContent);
|
||||
}
|
||||
|
||||
graphMLContent.append("</graph>\n");
|
||||
}
|
||||
|
||||
private void generateEdgeSectionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("<!-- edges -->\n");
|
||||
|
||||
Set<CoPIEdge> edges = coPIData.getEdges();
|
||||
|
||||
List<CoPIEdge> orderedEdges = new ArrayList<CoPIEdge>(edges);
|
||||
|
||||
Collections.sort(orderedEdges, new CoPIEdgeComparator());
|
||||
|
||||
for (CoPIEdge 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, CoPIEdge currentEdge) {
|
||||
|
||||
graphMLContent.append("<edge "
|
||||
+ "id=\"" + currentEdge.getEdgeID() + "\" "
|
||||
+ "source=\"" + currentEdge.getSourceNode().getNodeID() + "\" "
|
||||
+ "target=\"" + currentEdge.getTargetNode().getNodeID() + "\" "
|
||||
+ ">\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"collaborator1\">"
|
||||
+ currentEdge.getSourceNode().getNodeName()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"collaborator2\">"
|
||||
+ currentEdge.getTargetNode().getNodeName()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"number_of_coinvestigated_grants\">"
|
||||
+ currentEdge.getNumberOfCoInvestigatedGrants()
|
||||
+ "</data>\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<String, Integer> publicationInfo
|
||||
: currentEdge.getEarliestCollaborationYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"earliest_collaboration\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_earliest_collaboration\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (currentEdge.getLatestCollaborationYearCount() != null) {
|
||||
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: currentEdge.getLatestCollaborationYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"latest_collaboration\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_latest_collaboration\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (currentEdge.getUnknownCollaborationYearCount() != null) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_unknown_collaboration\">"
|
||||
+ currentEdge.getUnknownCollaborationYearCount()
|
||||
+ "</data>\n");
|
||||
|
||||
}
|
||||
|
||||
graphMLContent.append("</edge>\n");
|
||||
}
|
||||
|
||||
|
||||
private void generateNodeSectionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("<!-- nodes -->\n");
|
||||
|
||||
CoPINode egoNode = coPIData.getEgoNode();
|
||||
Set<CoPINode> piNodes = coPIData.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-pi vis. Ego should always come first.
|
||||
*
|
||||
* */
|
||||
getNodeContent(graphMLContent, egoNode);
|
||||
|
||||
List<CoPINode> orderedPINodes = new ArrayList<CoPINode>(piNodes);
|
||||
orderedPINodes.remove(egoNode);
|
||||
|
||||
Collections.sort(orderedPINodes, new CoPINodeComparator());
|
||||
|
||||
|
||||
for (CoPINode currNode : orderedPINodes) {
|
||||
|
||||
/*
|
||||
* We have already printed the Ego Node info.
|
||||
* */
|
||||
if (currNode != egoNode) {
|
||||
|
||||
getNodeContent(graphMLContent, currNode);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getNodeContent(StringBuilder graphMLContent, CoPINode node) {
|
||||
|
||||
ParamMap individualProfileURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
node.getNodeURI());
|
||||
|
||||
String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX,
|
||||
individualProfileURLParams);
|
||||
|
||||
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
|
||||
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");
|
||||
graphMLContent.append("\t<data key=\"label\">" + node.getNodeName() + "</data>\n");
|
||||
|
||||
if (profileURL != null) {
|
||||
graphMLContent.append("\t<data key=\"profile_url\">" + profileURL + "</data>\n");
|
||||
}
|
||||
|
||||
|
||||
graphMLContent.append("\t<data key=\"number_of_investigated_grants\">"
|
||||
+ node.getNumberOfInvestigatedGrants()
|
||||
+ "</data>\n");
|
||||
|
||||
if (node.getEarliestGrantYearCount() != 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<String, Integer> publicationInfo
|
||||
: node.getEarliestGrantYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"earliest_grant\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_earliest_grant\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (node.getLatestGrantYearCount() != null) {
|
||||
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: node.getLatestGrantYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"latest_grant\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_latest_grant\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (node.getUnknownGrantYearCount() != null) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_unknown_grant\">"
|
||||
+ node.getUnknownGrantYearCount()
|
||||
+ "</data>\n");
|
||||
|
||||
}
|
||||
|
||||
graphMLContent.append("</node>\n");
|
||||
}
|
||||
|
||||
private void generateKeyDefinitionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
/*
|
||||
* Generate the key definition content for node.
|
||||
* */
|
||||
getKeyDefinitionFromSchema(coPIData.getNodeSchema(), graphMLContent);
|
||||
|
||||
/*
|
||||
* Generate the key definition content for edge.
|
||||
* */
|
||||
getKeyDefinitionFromSchema(coPIData.getEdgeSchema(), graphMLContent);
|
||||
}
|
||||
|
||||
private void getKeyDefinitionFromSchema(Set<Map<String, String>> schema,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
for (Map<String, String> currentNodeSchemaAttribute : schema) {
|
||||
|
||||
graphMLContent.append("\n<key ");
|
||||
|
||||
for (Map.Entry<String, String> currentAttributeKey
|
||||
: currentNodeSchemaAttribute.entrySet()) {
|
||||
|
||||
graphMLContent.append(currentAttributeKey.getKey()
|
||||
+ "=\"" + currentAttributeKey.getValue()
|
||||
+ "\" ");
|
||||
|
||||
}
|
||||
|
||||
if (currentNodeSchemaAttribute.containsKey("default")) {
|
||||
|
||||
graphMLContent.append(">\n");
|
||||
graphMLContent.append("<default>");
|
||||
graphMLContent.append(currentNodeSchemaAttribute.get("default"));
|
||||
graphMLContent.append("</default>\n");
|
||||
graphMLContent.append("</key>\n");
|
||||
|
||||
} else {
|
||||
graphMLContent.append("/>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
|
||||
/**
|
||||
* This Comparator is used to sort the CoPINodes based on their IDs in ascending order.
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
|
||||
public class CoPINodeComparator implements Comparator<CoPINode>{
|
||||
@Override
|
||||
public int compare(CoPINode arg0, CoPINode arg1) {
|
||||
return arg0.getNodeID() - arg1.getNodeID();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,623 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.coprincipalinvestigator;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
|
||||
|
||||
/**
|
||||
* This class contains code for rendering sparklines and displaying tables for
|
||||
* Co-PI visualization.
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CoPIVisCodeGenerator {
|
||||
|
||||
/*
|
||||
* There are 2 modes of sparkline that are available via this visualization.
|
||||
* 1. Short Sparkline - This sparkline will render all the data points (or sparks),
|
||||
* which in this case are the copi(s) over the years, from the last 10 years.
|
||||
*
|
||||
* 2. Full Sparkline - This sparkline will render all the data points (or sparks)
|
||||
* spanning the career of the person & last 10 years at the minimum, in case if
|
||||
* the person started his career in the last 10 years.
|
||||
* */
|
||||
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
|
||||
|
||||
put("SHORT_SPARK", "unique_copis_short_sparkline_vis");
|
||||
put("FULL_SPARK", "unique_copis_full_sparkline_vis");
|
||||
|
||||
} };
|
||||
|
||||
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
|
||||
|
||||
private static final String DEFAULT_VISCONTAINER_DIV_ID = "unique_copis_vis_container";
|
||||
|
||||
private Map<String, Set<CoPINode>> yearToUniqueCoPIs;
|
||||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
|
||||
private String contextPath;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
public CoPIVisCodeGenerator(String contextPath,
|
||||
String individualURI,
|
||||
String visMode,
|
||||
String visContainer,
|
||||
Map<String, Set<CoPINode>> yearToUniqueCoPIs,
|
||||
Log log){
|
||||
|
||||
this.contextPath = contextPath;
|
||||
this.individualURI = individualURI;
|
||||
|
||||
this.yearToUniqueCoPIs = yearToUniqueCoPIs;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
this.log = log;
|
||||
|
||||
generateVisualizationCode(visMode, visContainer);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate the visualization code (HMTL, CSS &
|
||||
* JavaScript). There 2 parts to it - 1. Actual Content Code & 2. Context
|
||||
* Code. 1. Actual Content code in this case is the sparkline image, text
|
||||
* related to data and the wrapping tables. This is generated via call to
|
||||
* google vis API through JavaScript. 2. Context code is generally optional
|
||||
* but contains code pertaining to tabulated data & links to download files
|
||||
* etc.
|
||||
*
|
||||
* @param visMode
|
||||
* @param visContainer
|
||||
*/
|
||||
private void generateVisualizationCode(String visMode, String visContainer) {
|
||||
|
||||
sparklineData.setSparklineContent(getMainVisualizationCode(visMode,
|
||||
visContainer));
|
||||
|
||||
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
|
||||
|
||||
}
|
||||
|
||||
private String getMainVisualizationCode(String visMode,
|
||||
String providedVisContainerID) {
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int shortSparkMinYear = currentYear
|
||||
- VisConstants.MINIMUM_YEARS_CONSIDERED_FOR_SPARKLINE + 1;
|
||||
|
||||
/*
|
||||
* This is required because when deciding the range of years over which
|
||||
* the vis was rendered we dont want to be influenced by the
|
||||
* "DEFAULT_GRANT_YEAR".
|
||||
*/
|
||||
Set<String> investigatedYears = new HashSet<String>(yearToUniqueCoPIs
|
||||
.keySet());
|
||||
investigatedYears.remove(VOConstants.DEFAULT_GRANT_YEAR);
|
||||
|
||||
/*
|
||||
* We are setting the default value of minGrantYear to be 10 years
|
||||
* before the current year (which is suitably represented by the
|
||||
* shortSparkMinYear), this in case we run into invalid set of investigated
|
||||
* years.
|
||||
*/
|
||||
int minGrantYear = shortSparkMinYear;
|
||||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
try {
|
||||
minGrantYear = Integer.parseInt(Collections
|
||||
.min(investigatedYears));
|
||||
} catch (NoSuchElementException e1) {
|
||||
log.debug("vis: " + e1.getMessage() + " error occurred for "
|
||||
+ yearToUniqueCoPIs.toString());
|
||||
} catch (NumberFormatException e2) {
|
||||
log.debug("vis: " + e2.getMessage() + " error occurred for "
|
||||
+ yearToUniqueCoPIs.toString());
|
||||
}
|
||||
}
|
||||
|
||||
int minGrantYearConsidered = 0;
|
||||
|
||||
/*
|
||||
* There might be a case that the person investigated his first grant
|
||||
* within the last 10 years but we want to make sure that the sparkline
|
||||
* is representative of at least the last 10 years, so we will set the
|
||||
* minGrantYearConsidered to "currentYear - 10" which is also given by
|
||||
* "shortSparkMinYear".
|
||||
*/
|
||||
if (minGrantYear > shortSparkMinYear) {
|
||||
minGrantYearConsidered = shortSparkMinYear;
|
||||
} else {
|
||||
minGrantYearConsidered = minGrantYear;
|
||||
}
|
||||
|
||||
numOfYearsToBeRendered = currentYear - minGrantYearConsidered + 1;
|
||||
|
||||
visualizationCode.append("<style type='text/css'>" + "."
|
||||
+ VISUALIZATION_STYLE_CLASS + " table{" + " margin: 0;"
|
||||
+ " padding: 0;" + " width: auto;"
|
||||
+ " border-collapse: collapse;" + " border-spacing: 0;"
|
||||
+ " vertical-align: inherit;" + "}"
|
||||
+ ".incomplete-data-holder {" + "" + "}"
|
||||
+ "td.sparkline_number { text-align:right; "
|
||||
+ "padding-right:5px; }"
|
||||
+ "td.sparkline_text {text-align:left;}" + "</style>\n");
|
||||
|
||||
visualizationCode
|
||||
.append("<script type=\"text/javascript\">\n"
|
||||
+ "function drawUniqueCoPICountVisualization(providedSparklineImgTD) {\n"
|
||||
+ "var data = new google.visualization.DataTable();\n"
|
||||
+ "data.addColumn('string', 'Year');\n"
|
||||
+ "data.addColumn('number', 'Unique Co-PI(s)');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int uniqueCoPICounter = 0;
|
||||
int renderedFullSparks = 0;
|
||||
Set<CoPINode> allCoPIsWithKnownGrantShipYears = new HashSet<CoPINode>();
|
||||
|
||||
for (int grantYear = minGrantYearConsidered; grantYear <= currentYear; grantYear++) {
|
||||
|
||||
String grantYearAsString = String.valueOf(grantYear);
|
||||
Set<CoPINode> currentCoPIs = yearToUniqueCoPIs
|
||||
.get(grantYearAsString);
|
||||
|
||||
Integer currentUniqueCoPIs = null;
|
||||
|
||||
if (currentCoPIs != null) {
|
||||
currentUniqueCoPIs = currentCoPIs.size();
|
||||
allCoPIsWithKnownGrantShipYears.addAll(currentCoPIs);
|
||||
} else {
|
||||
currentUniqueCoPIs = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue(" + uniqueCoPICounter
|
||||
+ ", 0, '" + grantYearAsString + "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue(" + uniqueCoPICounter
|
||||
+ ", 1, " + currentUniqueCoPIs + ");\n");
|
||||
uniqueCoPICounter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the purpose of this visualization I have come up with a term
|
||||
* "Sparks" which essentially means data points. Sparks that will be
|
||||
* rendered in full mode will always be the one's which have any year
|
||||
* associated with it. Hence.
|
||||
*/
|
||||
renderedFullSparks = allCoPIsWithKnownGrantShipYears.size();
|
||||
|
||||
/*
|
||||
* Total grants will also consider publications that have no year
|
||||
* associated with them. Hence.
|
||||
*/
|
||||
Integer unknownYearCoPIs = 0;
|
||||
if (yearToUniqueCoPIs.get(VOConstants.DEFAULT_GRANT_YEAR) != null) {
|
||||
unknownYearCoPIs = yearToUniqueCoPIs.get(
|
||||
VOConstants.DEFAULT_GRANT_YEAR).size();
|
||||
}
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
visContainerID = DEFAULT_VISCONTAINER_DIV_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* By default these represents the range of the rendered sparks. Only in
|
||||
* case of "short" sparkline mode we will set the Earliest
|
||||
* RenderedGrant year to "currentYear - 10".
|
||||
*/
|
||||
sparklineData.setEarliestRenderedGrantYear(minGrantYear);
|
||||
sparklineData.setLatestRenderedGrantYear(currentYear);
|
||||
|
||||
/*
|
||||
* The Full Sparkline will be rendered by default. Only if the url has
|
||||
* specific mention of SHORT_SPARKLINE_MODE_KEY then we render the short
|
||||
* sparkline and not otherwise.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Since building StringBuilder objects (which is being used to store
|
||||
* the vis code) is essentially a side-effecting process, we have both
|
||||
* the activators method as side-effecting. They both side-effect
|
||||
* "visualizationCode"
|
||||
*/
|
||||
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE
|
||||
.equalsIgnoreCase(visMode)) {
|
||||
|
||||
sparklineData.setEarliestRenderedGrantYear(shortSparkMinYear);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear, visContainerID, visualizationCode,
|
||||
unknownYearCoPIs, sparklineDisplayOptions);
|
||||
} else {
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minGrantYearConsidered, visContainerID, visualizationCode,
|
||||
unknownYearCoPIs, renderedFullSparks,
|
||||
sparklineDisplayOptions);
|
||||
}
|
||||
|
||||
log.debug(visualizationCode);
|
||||
|
||||
return visualizationCode.toString();
|
||||
}
|
||||
|
||||
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||
int shortSparkMinYear, String visContainerID,
|
||||
StringBuilder visualizationCode, int unknownYearGrants,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
/*
|
||||
* Create a view of the data containing only the column pertaining to
|
||||
* grant count.
|
||||
*/
|
||||
visualizationCode.append("var shortSparklineView = "
|
||||
+ "new google.visualization.DataView(data);\n"
|
||||
+ "shortSparklineView.setColumns([1]);\n");
|
||||
|
||||
/*
|
||||
* For the short view we only want the last 10 year's view of
|
||||
* grant count, hence we filter the data we actually want to use
|
||||
* for render.
|
||||
*/
|
||||
visualizationCode.append("shortSparklineView.setRows("
|
||||
+ "data.getFilteredRows([{column: 0, " + "minValue: '"
|
||||
+ shortSparkMinYear + "', " + "maxValue: '" + currentYear
|
||||
+ "'}])" + ");\n");
|
||||
|
||||
/*
|
||||
* Create the vis object and draw it in the div pertaining to
|
||||
* short-sparkline.
|
||||
*/
|
||||
visualizationCode
|
||||
.append("var short_spark = new google.visualization.ImageSparkLine("
|
||||
+ "providedSparklineImgTD[0]"
|
||||
+ ");\n"
|
||||
+ "short_spark.draw(shortSparklineView, "
|
||||
+ sparklineDisplayOptions + ");\n");
|
||||
|
||||
/*
|
||||
* We want to display how many grant counts were considered, so
|
||||
* this is used to calculate this.
|
||||
*/
|
||||
visualizationCode
|
||||
.append("var shortSparkRows = shortSparklineView.getViewRows();\n"
|
||||
+ "var renderedShortSparks = 0;\n"
|
||||
+ "$.each(shortSparkRows, function(index, value) {"
|
||||
+ "renderedShortSparks += data.getValue(value, 1);"
|
||||
+ "});\n");
|
||||
|
||||
/*
|
||||
* Generate the text introducing the vis.
|
||||
*/
|
||||
|
||||
String imcompleteDataText = "This information is based solely on grants which "
|
||||
+ "have been loaded into the VIVO system. "
|
||||
+ "This may only be a small sample of the person\\'s "
|
||||
+ "total work.";
|
||||
|
||||
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("SHORT_SPARK")
|
||||
+ " td.sparkline_number').text("
|
||||
+ "parseInt(renderedShortSparks) " + "+ parseInt("
|
||||
+ unknownYearGrants + "));");
|
||||
|
||||
visualizationCode.append("var shortSparksText = ''"
|
||||
+ "+ ' grant(s) within the last 10 years "
|
||||
+ "<span class=\"incomplete-data-holder\" title=\""
|
||||
+ imcompleteDataText + "\">incomplete data</span>'" + "+ '';"
|
||||
+ "$('#" + VIS_DIV_NAMES.get("SHORT_SPARK") + " "
|
||||
+ "td.sparkline_text').html(shortSparksText);");
|
||||
|
||||
visualizationCode.append("}\n ");
|
||||
|
||||
/*
|
||||
* Generate the code that will activate the visualization. It takes care
|
||||
* of creating div elements to hold the actual sparkline image and then
|
||||
* calling the drawUniqueCoPICountVisualization function.
|
||||
*/
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES
|
||||
.get("SHORT_SPARK"), visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private void generateFullSparklineVisualizationContent(
|
||||
int currentYear,
|
||||
int minGrantYearConsidered,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearGrants,
|
||||
int renderedFullSparks,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
|
||||
visualizationCode.append("var fullSparklineView = "
|
||||
+ "new google.visualization.DataView(data);\n"
|
||||
+ "fullSparklineView.setColumns([1]);\n");
|
||||
|
||||
visualizationCode.append("var full_spark = new google.visualization.ImageSparkLine("
|
||||
+ "providedSparklineImgTD[0]"
|
||||
+ ");\n"
|
||||
+ "full_spark.draw(fullSparklineView, "
|
||||
+ sparklineDisplayOptions + ");\n");
|
||||
|
||||
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
|
||||
+ " td.sparkline_number').text('" + (renderedFullSparks
|
||||
+ unknownYearGrants) + "');");
|
||||
|
||||
visualizationCode.append("var allSparksText = ''"
|
||||
+ "+ ' Co-Principal Investigator(s) '"
|
||||
+ "+ ' from "
|
||||
+ "<span class=\"sparkline_range\">"
|
||||
+ "" + minGrantYearConsidered + " to " + currentYear + ""
|
||||
+ "</span> '"
|
||||
+ "+ ' " + csvDownloadURLHref + " ';"
|
||||
+ "$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
|
||||
+ " td.sparkline_text').html(allSparksText);");
|
||||
|
||||
visualizationCode.append("}\n ");
|
||||
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("FULL_SPARK"),
|
||||
visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private String generateVisualizationActivator(String sparklineID, String visContainerID) {
|
||||
|
||||
String sparklineTableWrapper = "\n"
|
||||
+ "var table = $('<table>');"
|
||||
+ "table.attr('class', 'sparkline_wrapper_table');"
|
||||
+ "var row = $('<tr>');"
|
||||
+ "sparklineImgTD = $('<td>');"
|
||||
+ "sparklineImgTD.attr('id', '" + sparklineID + "_img');"
|
||||
+ "sparklineImgTD.attr('width', '65');"
|
||||
+ "sparklineImgTD.attr('align', 'right');"
|
||||
+ "sparklineImgTD.attr('class', '" + VISUALIZATION_STYLE_CLASS + "');"
|
||||
+ "row.append(sparklineImgTD);"
|
||||
+ "var sparklineNumberTD = $('<td>');"
|
||||
+ "sparklineNumberTD.attr('width', '30');"
|
||||
+ "sparklineNumberTD.attr('align', 'right');"
|
||||
+ "sparklineNumberTD.attr('class', 'sparkline_number');"
|
||||
+ "row.append(sparklineNumberTD);"
|
||||
+ "var sparklineTextTD = $('<td>');"
|
||||
+ "sparklineTextTD.attr('width', '450');"
|
||||
+ "sparklineTextTD.attr('class', 'sparkline_text');"
|
||||
+ "row.append(sparklineTextTD);"
|
||||
+ "table.append(row);"
|
||||
+ "table.prependTo('#" + sparklineID + "');\n";
|
||||
|
||||
return "$(document).ready(function() {"
|
||||
+ "var sparklineImgTD; "
|
||||
|
||||
/*
|
||||
* This is a nuclear option (creating the container in which everything goes)
|
||||
* the only reason this will be ever used is the API user never submitted a
|
||||
* container ID in which everything goes. The alternative was to let the
|
||||
* vis not appear in the calling page at all. So now atleast vis appears but
|
||||
* appended at the bottom of the body.
|
||||
* */
|
||||
|
||||
+ "if ($('#" + visContainerID + "').length === 0) {"
|
||||
+ " $('<div/>', {'id': '" + visContainerID + "'"
|
||||
+ " }).appendTo('body');"
|
||||
+ "}"
|
||||
+ "if ($('#" + sparklineID + "').length === 0) {"
|
||||
+ "$('<div/>', {'id': '" + sparklineID + "',"
|
||||
+ "'class': '" + VISUALIZATION_STYLE_CLASS + "'"
|
||||
+ "}).prependTo('#" + visContainerID + "');"
|
||||
+ sparklineTableWrapper
|
||||
+ "}"
|
||||
+ "drawUniqueCoPICountVisualization(sparklineImgTD);"
|
||||
+ "});"
|
||||
+ "</script>\n";
|
||||
}
|
||||
|
||||
private String getVisualizationContextCode(String visMode) {
|
||||
|
||||
String visualizationContextCode = "";
|
||||
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
|
||||
visualizationContextCode = generateShortVisContext();
|
||||
} else {
|
||||
visualizationContextCode = generateFullVisContext();
|
||||
}
|
||||
|
||||
log.debug(visualizationContextCode);
|
||||
|
||||
return visualizationContextCode;
|
||||
}
|
||||
|
||||
private String generateFullVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "No data available to export.<br />";
|
||||
}
|
||||
|
||||
String tableCode = generateDataTable();
|
||||
|
||||
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
|
||||
|
||||
sparklineData.setTable(tableCode);
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String getCSVDownloadURL() throws UnsupportedEncodingException {
|
||||
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
|
||||
|
||||
String downloadURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.CO_PI_VIS,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&" + VisualizationFrameworkConstants.VIS_MODE_KEY
|
||||
+ "=" + URLEncoder.encode("sparkline",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
return downloadURL;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToUniqueCoPIs.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
|
||||
String fullTimelineNetworkURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?"
|
||||
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode("person_level",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_CONTAINER_KEY
|
||||
+ "=" + URLEncoder.encode("ego_sparkline",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(
|
||||
VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL
|
||||
+ "'>View full timeline and co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<p>" + fullTimelineLink + "</p>");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
StringBuilder dataTable = new StringBuilder();
|
||||
|
||||
dataTable.append("<table id='sparkline_data_table'>"
|
||||
+ "<caption>Unique Co-PIs per year</caption>"
|
||||
+ "<thead>"
|
||||
+ "<tr>"
|
||||
+ "<th>Year</th>"
|
||||
+ "<th>Count</th>"
|
||||
+ "</tr>"
|
||||
+ "</thead>"
|
||||
+ "<tbody>");
|
||||
|
||||
for (Entry<String, Set<CoPINode>> currentEntry : yearToUniqueCoPIs.entrySet()) {
|
||||
dataTable.append("<tr>"
|
||||
+ "<td>" + currentEntry.getKey() + "</td>"
|
||||
+ "<td>" + currentEntry.getValue().size() + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
|
||||
dataTable.append("</tbody>\n </table>\n");
|
||||
|
||||
return dataTable.toString();
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
}
|
||||
}
|
|
@ -129,7 +129,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
|
|||
+ "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ."
|
||||
+ "}";
|
||||
|
||||
System.out.println("SPARQL query for person grant count -> \n"+ sparqlQuery);
|
||||
log.debug("SPARQL query for person grant count -> \n"+ sparqlQuery);
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,38 +2,29 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
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.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DataVisualizationController;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
|
||||
|
||||
|
@ -54,14 +45,42 @@ import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
|||
*/
|
||||
public class PersonGrantCountRequestHandler implements VisualizationRequestHandler {
|
||||
|
||||
public ResponseValues generateVisualization(VitroRequest vitroRequest,
|
||||
Log log, DataSource dataSource) {
|
||||
@Override
|
||||
public Map<String, String> generateDataVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
|
||||
String personURI = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
|
||||
String renderMode = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
|
||||
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
|
||||
|
||||
Set<Grant> piGrants = queryManager.getQueryResult();
|
||||
|
||||
/*
|
||||
* Create a map from the year to number of grants. Use the Grant's
|
||||
* parsedGrantYear to populate the data.
|
||||
* */
|
||||
Map<String, Integer> yearToGrantCount =
|
||||
UtilityFunctions.getYearToGrantCount(piGrants);
|
||||
|
||||
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
|
||||
|
||||
return prepareDataResponse(investigator,
|
||||
piGrants,
|
||||
yearToGrantCount);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
|
||||
DataSource dataSource) throws MalformedQueryParametersException {
|
||||
|
||||
String personURI = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
|
||||
String visMode = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
@ -69,9 +88,8 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
String visContainer = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
|
||||
|
||||
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
|
||||
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
|
||||
|
||||
try{
|
||||
Set<Grant> piGrants = queryManager.getQueryResult();
|
||||
|
||||
/*
|
||||
|
@ -81,40 +99,62 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
Map<String, Integer> yearToGrantCount =
|
||||
UtilityFunctions.getYearToGrantCount(piGrants);
|
||||
|
||||
Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator();
|
||||
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
boolean shouldVIVOrenderVis =
|
||||
yearToGrantCount.size() > 0 ? true : false;
|
||||
|
||||
/*
|
||||
* Computations required to generate HTML for the sparkline & related context.
|
||||
* */
|
||||
PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
|
||||
new PersonGrantCountVisCodeGenerator(personURI,
|
||||
visMode,
|
||||
visContainer,
|
||||
piGrants,
|
||||
yearToGrantCount,
|
||||
log);
|
||||
|
||||
|
||||
/*
|
||||
return prepareDataResponse(investigator,
|
||||
piGrants,
|
||||
yearToGrantCount);
|
||||
*/
|
||||
}
|
||||
SparklineData sparklineData = visualizationCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
return prepareDynamicResponse(vitroRequest,
|
||||
sparklineData,
|
||||
shouldVIVOrenderVis);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseValues generateStandardVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
String personURI = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
|
||||
String visMode = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
||||
String visContainer = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
|
||||
|
||||
QueryRunner<Set<Grant>> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log );
|
||||
|
||||
Set<Grant> piGrants = queryManager.getQueryResult();
|
||||
|
||||
/*
|
||||
* For now we are disabling the capability to render pdf file.
|
||||
* Create a map from the year to number of grants. Use the Grant's
|
||||
* parsedGrantYear to populate the data.
|
||||
* */
|
||||
/*
|
||||
if (VisualizationFrameworkConstants.PDF_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
preparePDFResponse(investigator,
|
||||
piGrants,
|
||||
yearToGrantCount,
|
||||
response);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
Map<String, Integer> yearToGrantCount =
|
||||
UtilityFunctions.getYearToGrantCount(piGrants);
|
||||
|
||||
/*
|
||||
* Computations required to generate HTML for the sparkline & related context.
|
||||
* */
|
||||
PersonGrantCountVisCodeGenerator visualizationCodeGenerator =
|
||||
new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(),
|
||||
personURI,
|
||||
new PersonGrantCountVisCodeGenerator(personURI,
|
||||
visMode,
|
||||
visContainer,
|
||||
piGrants,
|
||||
|
@ -124,30 +164,9 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
SparklineData sparklineData = visualizationCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
/*
|
||||
* This is side-effecting because the response of this method is just to redirect to
|
||||
* a page with visualization on it.
|
||||
* */
|
||||
RequestDispatcher requestDispatcher = null;
|
||||
|
||||
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
return prepareDynamicResponse(vitroRequest,
|
||||
sparklineData,
|
||||
yearToGrantCount);
|
||||
|
||||
} else {
|
||||
return prepareStandaloneResponse(vitroRequest,
|
||||
sparklineData);
|
||||
}
|
||||
} catch (MalformedQueryParametersException e) {
|
||||
return UtilityFunctions.handleMalformedParameters(
|
||||
"Visualization Query Error - Individual Grant Count",
|
||||
e.getMessage(),
|
||||
vitroRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private String getGrantsOverTimeCSVContent(Map<String, Integer> yearToGrantCount) {
|
||||
|
||||
|
@ -199,13 +218,15 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
String outputFileName = UtilityFunctions.slugify(piName)
|
||||
+ "_grants-per-year" + ".csv";
|
||||
|
||||
Map<String, String> fileData = new HashMap<String, String>();
|
||||
fileData.put(DataVisualizationController.FILE_NAME_KEY,
|
||||
outputFileName);
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY,
|
||||
"application/octet-stream");
|
||||
fileData.put(DataVisualizationController.FILE_CONTENT_KEY,
|
||||
getGrantsOverTimeCSVContent(yearToGrantCount));
|
||||
|
||||
Map<String, Object> fileContents = new HashMap<String, Object>();
|
||||
fileContents.put("fileContent", getGrantsOverTimeCSVContent(yearToGrantCount));
|
||||
|
||||
// return new FileResponseValues(new ContentType(), outputFileName, fileContents);
|
||||
|
||||
return new HashMap<String, String>();
|
||||
return fileData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,11 +247,6 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
body.put("title", "Individual Grant Count visualization");
|
||||
body.put("sparklineVO", valueObjectContainer);
|
||||
|
||||
/*
|
||||
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
|
||||
* */
|
||||
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
return new TemplateResponseValues(standaloneTemplate, body);
|
||||
|
||||
}
|
||||
|
@ -246,7 +262,7 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
private TemplateResponseValues prepareDynamicResponse(
|
||||
VitroRequest vreq,
|
||||
SparklineData valueObjectContainer,
|
||||
Map<String, Integer> yearToGrantCount) {
|
||||
boolean shouldVIVOrenderVis) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
|
@ -256,102 +272,10 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl
|
|||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("portalBean", portal);
|
||||
body.put("sparklineVO", valueObjectContainer);
|
||||
|
||||
/*
|
||||
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
|
||||
* */
|
||||
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
body.put("shouldVIVOrenderVis", true);
|
||||
} else {
|
||||
body.put("shouldVIVOrenderVis", false);
|
||||
}
|
||||
body.put("shouldVIVOrenderVis", shouldVIVOrenderVis);
|
||||
|
||||
return new TemplateResponseValues(dynamicTemplate, body);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void preparePDFResponse(Individual investigator,
|
||||
Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount,
|
||||
HttpServletResponse response) {
|
||||
|
||||
String piName = null;
|
||||
|
||||
// To protect against cases where there are no PI grants
|
||||
// associated with the
|
||||
// / individual.
|
||||
if (piGrants.size() > 0) {
|
||||
piName = investigator.getIndividualLabel();
|
||||
}
|
||||
|
||||
// To make sure that null/empty records for PI names do not cause
|
||||
// any mischief.
|
||||
if (StringUtils.isBlank(piName)) {
|
||||
piName = "no-principal-investigator";
|
||||
}
|
||||
|
||||
String outputFileName = UtilityFunctions.slugify(piName)
|
||||
+ "_report" + ".pdf";
|
||||
|
||||
response.setContentType("application/pdf");
|
||||
response.setHeader("Content-Disposition", "attachment;filename="
|
||||
+ outputFileName);
|
||||
|
||||
ServletOutputStream responseOutputStream;
|
||||
try {
|
||||
responseOutputStream = response.getOutputStream();
|
||||
|
||||
Document document = new Document();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
|
||||
document.open();
|
||||
|
||||
PDFDocument pdfDocument = new PDFDocument(piName,
|
||||
yearToGrantCount, document, pdfWriter);
|
||||
|
||||
document.close();
|
||||
|
||||
// setting some response headers & content type
|
||||
response.setHeader("Expires", "0");
|
||||
response.setHeader("Cache-Control",
|
||||
"must-revalidate, post-check=0, pre-check=0");
|
||||
response.setHeader("Pragma", "public");
|
||||
response.setContentLength(baos.size());
|
||||
// write ByteArrayOutputStream to the ServletOutputStream
|
||||
baos.writeTo(responseOutputStream);
|
||||
responseOutputStream.flush();
|
||||
responseOutputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object generateAjaxVisualization(VitroRequest vitroRequest, Log log,
|
||||
DataSource dataSource) throws MalformedQueryParametersException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> generateDataVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseValues generateStandardVisualization(
|
||||
VitroRequest vitroRequest, Log log, DataSource dataSource)
|
||||
throws MalformedQueryParametersException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.persongrantcount;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
|
@ -11,13 +9,14 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.StandardVisualizationController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||
|
@ -26,7 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Sp
|
|||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearGrantCountDataElement;
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PersonGrantCountVisCodeGenerator {
|
||||
|
||||
/*
|
||||
|
@ -38,6 +37,7 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
* spanning the career of the person & last 10 years at the minimum, in case if
|
||||
* the person started his career in the last 10 yeras.
|
||||
* */
|
||||
|
||||
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
|
||||
|
||||
put("SHORT_SPARK", "grant_count_short_sparkline_vis");
|
||||
|
@ -55,16 +55,13 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
private SparklineData sparklineData;
|
||||
|
||||
private String contextPath;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
public PersonGrantCountVisCodeGenerator(String contextPath,
|
||||
String individualURIParam, String visMode, String visContainer,
|
||||
Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount, Log log) {
|
||||
public PersonGrantCountVisCodeGenerator(String individualURIParam,
|
||||
String visMode, String visContainer, Set<Grant> piGrants,
|
||||
Map<String, Integer> yearToGrantCount,
|
||||
Log log) {
|
||||
|
||||
this.contextPath = contextPath;
|
||||
this.individualURI = individualURIParam;
|
||||
|
||||
this.yearToGrantCount = yearToGrantCount;
|
||||
|
@ -198,8 +195,7 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
for (int grantYear = minGrantYearConsidered; grantYear <= currentYear; grantYear++) {
|
||||
|
||||
String stringInvestigatedYear = String.valueOf(grantYear);
|
||||
Integer currentGrants = yearToGrantCount
|
||||
.get(stringInvestigatedYear);
|
||||
Integer currentGrants = yearToGrantCount.get(stringInvestigatedYear);
|
||||
|
||||
if (currentGrants == null) {
|
||||
currentGrants = 0;
|
||||
|
@ -385,17 +381,12 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
|
@ -505,18 +496,13 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
} else {
|
||||
|
@ -533,34 +519,18 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
}
|
||||
|
||||
|
||||
private String getCSVDownloadURL()
|
||||
throws UnsupportedEncodingException {
|
||||
private String getCSVDownloadURL() {
|
||||
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
ParamMap CSVDownloadURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_GRANT_COUNT_VIS);
|
||||
|
||||
return UrlBuilder.getUrl(VisualizationFrameworkConstants.DATA_VISUALIZATION_SERVICE_URL_PREFIX,
|
||||
CSVDownloadURLParams);
|
||||
|
||||
String downloadURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode(
|
||||
VisualizationFrameworkConstants
|
||||
.PERSON_GRANT_COUNT_VIS,
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.DATA_RENDER_MODE,
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString();
|
||||
return downloadURL;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -571,46 +541,30 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToGrantCount.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
ParamMap fullTimelineNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY,
|
||||
individualURI,
|
||||
VisualizationFrameworkConstants.VIS_TYPE_KEY,
|
||||
VisualizationFrameworkConstants.PERSON_LEVEL_VIS);
|
||||
|
||||
String fullTimelineNetworkURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?"
|
||||
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode("person_level",
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
StandardVisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
String fullTimelineNetworkURL = UrlBuilder.getUrl(
|
||||
VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX,
|
||||
fullTimelineNetworkURLParams);
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
|
||||
+ "grants and corresponding co-pi network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
|
@ -618,13 +572,9 @@ public class PersonGrantCountVisCodeGenerator {
|
|||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.Set;
|
|||
import java.util.HashSet;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
|
|
|
@ -128,7 +128,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner<Set<Grant>>{
|
|||
+ "?Grant rdfs:label ?GrantLabel ; core:startDate ?GrantStartDate ; core:endDate ?GrantEndDate ."
|
||||
+ "}";
|
||||
|
||||
System.out.println("SPARQL query for person grant count -> \n"+ sparqlQuery);
|
||||
log.debug("SPARQL query for person grant count -> \n"+ sparqlQuery);
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ public class PersonPublicationCountQueryRunner implements QueryRunner<Set<BiboDo
|
|||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE
|
||||
+ "}";
|
||||
|
||||
System.out.println("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||
log.debug("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue