diff --git a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml index 0700f430..d64c994f 100644 --- a/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml +++ b/productMods/WEB-INF/visualization/visualizations-beans-injection-fm.xml @@ -15,12 +15,18 @@ - @@ -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 diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipQueryRunner.java index e72c8ab5..7e86005f 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipQueryRunner.java @@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner { 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 { + "} " + "ORDER BY ?document ?coAuthorPerson"; - System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery); + log.debug("COAUTHORSHIP QUERY - " + sparqlQuery); return sparqlQuery; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGrantCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGrantCountQueryRunner.java index 7a6134aa..b53f410a 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGrantCountQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGrantCountQueryRunner.java @@ -92,7 +92,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner { + "?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 { 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 { ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI), this.dataSource); - System.out.println("ResultSet "); return createQueryResult(resultSet); } @@ -202,8 +191,7 @@ public class CoPIGrantCountQueryRunner implements QueryRunner { 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 { } 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 { } } - System.out.println("Adding CO-PI: "+ coPINode.getIndividualLabel()); + log.debug("Adding CO-PI: "+ coPINode.getIndividualLabel()); coPINode.addGrant(grant); Set coPIsForCurrentGrant; @@ -262,10 +250,9 @@ public class CoPIGrantCountQueryRunner implements QueryRunner { } 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 diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountQueryRunner.java index 0116339c..90c4335c 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountQueryRunner.java @@ -166,22 +166,11 @@ public class EntityPublicationCountQueryRunner implements QueryRunner { 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 { + SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}" + "}"; - System.out.println("\nThe sparql query is :\n" + sparqlQuery); + log.debug("\nThe sparql query is :\n" + sparqlQuery); return sparqlQuery; diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountRequestHandler.java index efc9752b..9955855a 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntityPublicationCountRequestHandler.java @@ -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 subentities, - Map> subOrganizationTypesResult, HttpServletResponse response) { + Map> 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> subOrganizationTypesResult) { + HttpServletResponse response, VitroRequest vreq, Entity entity, Map> 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 subentities, Map> subOrganizationTypesResult) { + private String writePublicationsOverTimeJSON(Set subentities, Map> 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 subEntitiesJson = new HashSet(); @@ -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: " diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntitySubOrganizationTypesQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntitySubOrganizationTypesQueryRunner.java index ab0d892c..325d9029 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntitySubOrganizationTypesQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/EntitySubOrganizationTypesQueryRunner.java @@ -74,20 +74,10 @@ public class EntitySubOrganizationTypesQueryRunner implements QueryRunner\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) { @@ -211,17 +202,12 @@ 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("\n"); graphMLContent.append("\t" + node.getNodeURI() + "\n"); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipQueryRunner.java index 0644a497..e81dbd05 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipQueryRunner.java @@ -399,23 +399,10 @@ public class CoAuthorshipQueryRunner implements QueryRunner { 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) { diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java index 0dfbe7d5..30eb7b10 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coauthorship/CoAuthorshipRequestHandler.java @@ -190,10 +190,6 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler { */ private Map prepareNetworkDataResponse(CoAuthorshipData authorNodesAndEdges) { - /* - * We are side-effecting responseWriter since we are directly manipulating the response - * object of the servlet. - * */ CoAuthorshipGraphMLWriter coAuthorshipGraphMLWriter = new CoAuthorshipGraphMLWriter(authorNodesAndEdges); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIEdgeComparator.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIEdgeComparator.java new file mode 100644 index 00000000..bd827ce8 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIEdgeComparator.java @@ -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 { + + @Override + public int compare(CoPIEdge arg0, CoPIEdge arg1) { + return arg0.getEdgeID() - arg1.getEdgeID(); + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountQueryRunner.java new file mode 100644 index 00000000..446bd544 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountQueryRunner.java @@ -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 { + + 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 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 nodes = new HashSet(); + + Map grantURLToVO = new HashMap(); + Map> grantURLToCoPIs = new HashMap>(); + Map nodeURLToVO = new HashMap(); + Map edgeUniqueIdentifierToVO = new HashMap(); + + CoPINode egoNode = null; + + Set edges = new HashSet(); + + 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 coPIsForCurrentGrant; + + if (grantURLToCoPIs.containsKey(grant.getGrantURL())) { + coPIsForCurrentGrant = grantURLToCoPIs + .get(grant.getGrantURL()); + } else { + coPIsForCurrentGrant = new HashSet(); + 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 grantURLToVO, + Map> grantURLToCoPIs, Set edges, + Map edgeUniqueIdentifierToVO) { + + for (Map.Entry> 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 newlyAddedEdges = new HashSet(); + + /* + * 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 coPINodes = new ArrayList(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 nodes, + Map grantURLToVO, + Map> grantURLToCoPIs, Set edges) { + + Set nodesToBeRemoved = new HashSet(); + for (Map.Entry> currentGrantEntry + : grantURLToCoPIs.entrySet()) { + + if (currentGrantEntry.getValue().size() > MAX_PI_PER_GRANT_ALLOWED) { + + Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey()); + + Set edgesToBeRemoved = new HashSet(); + + for (CoPIEdge currentEdge : edges) { + Set 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; + } +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java new file mode 100644 index 00000000..f6263d73 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGrantCountRequestHandler.java @@ -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 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 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 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 body = new HashMap(); + + + 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 prepareNetworkDataResponse(CoPIData pINodesAndEdges) { + + CoPIGraphMLWriter coPIGraphMLWriter = + new CoPIGraphMLWriter(pINodesAndEdges); + + Map fileData = new HashMap(); + 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 prepareCoPIDataResponse(CoPIData pINodesAndEdges) { + + String outputFileName; + Map> yearToCoPI = new TreeMap>(); + + 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 fileData = new HashMap(); + 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> yearToCoPI) { + + StringBuilder csvFileContent = new StringBuilder(); + + csvFileContent.append("Year, Count, Co-PI(s)\n"); + + for (Map.Entry> 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 CoPIs) { + + StringBuilder coPIsMerged = new StringBuilder(); + + String coPISeparator = ";"; + for(CoPINode currentCoPI : CoPIs){ + coPIsMerged.append(currentCoPI.getNodeName() + coPISeparator); + } + + return StringUtils.removeEnd(coPIsMerged.toString(), coPISeparator); + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGraphMLWriter.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGraphMLWriter.java new file mode 100644 index 00000000..31d6dd56 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIGraphMLWriter.java @@ -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 = "\n" + + " \n\n"; + + private final String GRAPHML_FOOTER = ""; + + 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\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("\n"); + } + + private void generateEdgeSectionContent(CoPIData coPIData, + StringBuilder graphMLContent) { + + graphMLContent.append("\n"); + + Set edges = coPIData.getEdges(); + + List orderedEdges = new ArrayList(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("\n"); + + graphMLContent.append("\t" + + currentEdge.getSourceNode().getNodeName() + + "\n"); + + graphMLContent.append("\t" + + currentEdge.getTargetNode().getNodeName() + + "\n"); + + graphMLContent.append("\t" + + currentEdge.getNumberOfCoInvestigatedGrants() + + "\n"); + + if (currentEdge.getEarliestCollaborationYearCount() != null) { + + /* + * There is no clean way of getting the map contents in java even though + * we are sure to have only one entry on the map. So using the for loop. + * */ + for (Map.Entry publicationInfo + : currentEdge.getEarliestCollaborationYearCount().entrySet()) { + + graphMLContent.append("\t" + + publicationInfo.getKey() + + "\n"); + + graphMLContent.append("\t" + + publicationInfo.getValue() + + "\n"); + } + + } + + if (currentEdge.getLatestCollaborationYearCount() != null) { + + for (Map.Entry publicationInfo + : currentEdge.getLatestCollaborationYearCount().entrySet()) { + + graphMLContent.append("\t" + + publicationInfo.getKey() + + "\n"); + + graphMLContent.append("\t" + + publicationInfo.getValue() + + "\n"); + } + + } + + if (currentEdge.getUnknownCollaborationYearCount() != null) { + + graphMLContent.append("\t" + + currentEdge.getUnknownCollaborationYearCount() + + "\n"); + + } + + graphMLContent.append("\n"); + } + + + private void generateNodeSectionContent(CoPIData coPIData, + StringBuilder graphMLContent) { + + graphMLContent.append("\n"); + + CoPINode egoNode = coPIData.getEgoNode(); + Set 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 orderedPINodes = new ArrayList(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("\n"); + graphMLContent.append("\t" + node.getNodeURI() + "\n"); + graphMLContent.append("\t" + node.getNodeName() + "\n"); + + if (profileURL != null) { + graphMLContent.append("\t" + profileURL + "\n"); + } + + + graphMLContent.append("\t" + + node.getNumberOfInvestigatedGrants() + + "\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 publicationInfo + : node.getEarliestGrantYearCount().entrySet()) { + + graphMLContent.append("\t" + + publicationInfo.getKey() + + "\n"); + + graphMLContent.append("\t" + + publicationInfo.getValue() + + "\n"); + } + + } + + if (node.getLatestGrantYearCount() != null) { + + for (Map.Entry publicationInfo + : node.getLatestGrantYearCount().entrySet()) { + + graphMLContent.append("\t" + + publicationInfo.getKey() + + "\n"); + + graphMLContent.append("\t" + + publicationInfo.getValue() + + "\n"); + } + + } + + if (node.getUnknownGrantYearCount() != null) { + + graphMLContent.append("\t" + + node.getUnknownGrantYearCount() + + "\n"); + + } + + graphMLContent.append("\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> schema, + StringBuilder graphMLContent) { + + for (Map currentNodeSchemaAttribute : schema) { + + graphMLContent.append("\n currentAttributeKey + : currentNodeSchemaAttribute.entrySet()) { + + graphMLContent.append(currentAttributeKey.getKey() + + "=\"" + currentAttributeKey.getValue() + + "\" "); + + } + + if (currentNodeSchemaAttribute.containsKey("default")) { + + graphMLContent.append(">\n"); + graphMLContent.append(""); + graphMLContent.append(currentNodeSchemaAttribute.get("default")); + graphMLContent.append("\n"); + graphMLContent.append("\n"); + + } else { + graphMLContent.append("/>\n"); + } + } + } + +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPINodeComparator.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPINodeComparator.java new file mode 100644 index 00000000..edae83ca --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPINodeComparator.java @@ -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{ + @Override + public int compare(CoPINode arg0, CoPINode arg1) { + return arg0.getNodeID() - arg1.getNodeID(); + } +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIVisCodeGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIVisCodeGenerator.java new file mode 100644 index 00000000..c6c77fa8 --- /dev/null +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/coprincipalinvestigator/CoPIVisCodeGenerator.java @@ -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 VIS_DIV_NAMES = new HashMap() { { + + 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> yearToUniqueCoPIs; + + private Log log; + + private SparklineData sparklineData; + + private String contextPath; + + private String individualURI; + + public CoPIVisCodeGenerator(String contextPath, + String individualURI, + String visMode, + String visContainer, + Map> 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 investigatedYears = new HashSet(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("\n"); + + visualizationCode + .append("\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 .csv file."; + sparklineData.setDownloadDataLink(getCSVDownloadURL()); + + } else { + csvDownloadURLHref = ""; + } + + } catch (UnsupportedEncodingException e) { + csvDownloadURLHref = ""; + } + + } else { + csvDownloadURLHref = "No data available to export."; + } + + String tableCode = generateDataTable(); + + divContextCode.append("" + tableCode + csvDownloadURLHref + ""); + + 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 = "View full timeline and co-pi network."; + + sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL); + + } else { + fullTimelineLink = "No data available to render full timeline."; + } + + divContextCode.append("" + fullTimelineLink + ""); + + } catch (UnsupportedEncodingException e) { + log.error(e); + } + + return divContextCode.toString(); + } + + private String generateDataTable() { + + StringBuilder dataTable = new StringBuilder(); + + dataTable.append("" + + "Unique Co-PIs per year" + + "" + + "" + + "Year" + + "Count" + + "" + + "" + + ""); + + for (Entry> currentEntry : yearToUniqueCoPIs.entrySet()) { + dataTable.append("" + + "" + currentEntry.getKey() + "" + + "" + currentEntry.getValue().size() + "" + + ""); + } + + dataTable.append("\n \n"); + + return dataTable.toString(); + } + + public SparklineData getValueObjectContainer() { + return sparklineData; + } +} diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountQueryRunner.java index 448f14eb..aab9ecac 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountQueryRunner.java @@ -129,7 +129,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner>{ + "?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; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountRequestHandler.java index 5a235cf5..5868f7ea 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountRequestHandler.java @@ -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,24 +45,102 @@ 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 generateDataVisualization( + VitroRequest vitroRequest, Log log, DataSource dataSource) + throws MalformedQueryParametersException { + + + String personURI = vitroRequest + .getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY); + + QueryRunner> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log ); + + Set piGrants = queryManager.getQueryResult(); + + /* + * Create a map from the year to number of grants. Use the Grant's + * parsedGrantYear to populate the data. + * */ + Map 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); + + String visContainer = vitroRequest + .getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY); + + QueryRunner> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log ); + + Set piGrants = queryManager.getQueryResult(); + + /* + * Create a map from the year to number of grants. Use the Grant's + * parsedGrantYear to populate the data. + * */ + Map yearToGrantCount = + UtilityFunctions.getYearToGrantCount(piGrants); + + + 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); + + + 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 renderMode = vitroRequest - .getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY); - String visMode = vitroRequest .getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY); String visContainer = vitroRequest .getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY); - QueryRunner> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log ); + QueryRunner> queryManager = new PersonGrantCountQueryRunner(personURI, dataSource, log ); - try{ Set piGrants = queryManager.getQueryResult(); /* @@ -81,73 +150,23 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl Map yearToGrantCount = UtilityFunctions.getYearToGrantCount(piGrants); - Individual investigator = ((PersonGrantCountQueryRunner) queryManager).getPrincipalInvestigator(); - - if (VisualizationFrameworkConstants.DATA_RENDER_MODE - .equalsIgnoreCase(renderMode)) { - - - /* - return prepareDataResponse(investigator, - piGrants, - yearToGrantCount); - */ - } - - /* - * For now we are disabling the capability to render pdf file. - * */ - /* - if (VisualizationFrameworkConstants.PDF_RENDER_MODE - .equalsIgnoreCase(renderMode)) { - - preparePDFResponse(investigator, - piGrants, - yearToGrantCount, - response); - return; - } - */ - /* * Computations required to generate HTML for the sparkline & related context. * */ PersonGrantCountVisCodeGenerator visualizationCodeGenerator = - new PersonGrantCountVisCodeGenerator(vitroRequest.getContextPath(), - personURI, + new PersonGrantCountVisCodeGenerator(personURI, visMode, visContainer, piGrants, - yearToGrantCount, + yearToGrantCount, log); 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 yearToGrantCount) { @@ -199,13 +218,15 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl String outputFileName = UtilityFunctions.slugify(piName) + "_grants-per-year" + ".csv"; - - Map fileContents = new HashMap(); - fileContents.put("fileContent", getGrantsOverTimeCSVContent(yearToGrantCount)); - -// return new FileResponseValues(new ContentType(), outputFileName, fileContents); - - return new HashMap(); + Map fileData = new HashMap(); + 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)); + + 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 yearToGrantCount) { + boolean shouldVIVOrenderVis) { Portal portal = vreq.getPortal(); @@ -256,102 +272,10 @@ public class PersonGrantCountRequestHandler implements VisualizationRequestHandl Map body = new HashMap(); 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 piGrants, - Map 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 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; - } } \ No newline at end of file diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountVisCodeGenerator.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountVisCodeGenerator.java index ae7c9f08..655fff12 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountVisCodeGenerator.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/persongrantcount/PersonGrantCountVisCodeGenerator.java @@ -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 VIS_DIV_NAMES = new HashMap() { { 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 piGrants, - Map yearToGrantCount, Log log) { + public PersonGrantCountVisCodeGenerator(String individualURIParam, + String visMode, String visContainer, Set piGrants, + Map 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) { - - csvDownloadURLHref = "(.CSV File)"; - - } else { - csvDownloadURLHref = ""; - } - - } catch (UnsupportedEncodingException e) { + if (getCSVDownloadURL() != null) { + + csvDownloadURLHref = "(.CSV File)"; + + } else { csvDownloadURLHref = ""; } @@ -505,18 +496,13 @@ public class PersonGrantCountVisCodeGenerator { if (yearToGrantCount.size() > 0) { - try { - if (getCSVDownloadURL() != null) { - - csvDownloadURLHref = "Download data as .csv file."; - sparklineData.setDownloadDataLink(getCSVDownloadURL()); - - } else { - csvDownloadURLHref = ""; - } - - } catch (UnsupportedEncodingException e) { + if (getCSVDownloadURL() != null) { + + csvDownloadURLHref = "Download data as .csv file."; + sparklineData.setDownloadDataLink(getCSVDownloadURL()); + + } 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; - } - - 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; + 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); + } 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; - } - - 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(); - + ParamMap fullTimelineNetworkURLParams = new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY, + individualURI, + VisualizationFrameworkConstants.VIS_TYPE_KEY, + VisualizationFrameworkConstants.PERSON_LEVEL_VIS); + + String fullTimelineNetworkURL = UrlBuilder.getUrl( + VisualizationFrameworkConstants.FREEMARKERIZED_VISUALIZATION_URL_PREFIX, + fullTimelineNetworkURLParams); + fullTimelineLink = "View all VIVO " + "grants and corresponding co-pi network."; sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL); + + } else { fullTimelineLink = "No data available to render full timeline."; } divContextCode.append("" + fullTimelineLink + ""); - - } catch (UnsupportedEncodingException e) { - log.error(e); - } return divContextCode.toString(); } @@ -618,13 +572,9 @@ public class PersonGrantCountVisCodeGenerator { String csvDownloadURLHref = ""; - try { - if (getCSVDownloadURL() != null) { - csvDownloadURLHref = "(.CSV File)"; - } else { - csvDownloadURLHref = ""; - } - } catch (UnsupportedEncodingException e) { + if (getCSVDownloadURL() != null) { + csvDownloadURLHref = "(.CSV File)"; + } else { csvDownloadURLHref = ""; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/valueobjects/CoPINode.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/valueobjects/CoPINode.java index 3aedffbf..20fa8a3e 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/valueobjects/CoPINode.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/freemarker/valueobjects/CoPINode.java @@ -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; /** diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/persongrantcount/PersonGrantCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/persongrantcount/PersonGrantCountQueryRunner.java index 15f0e910..56a1f938 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/persongrantcount/PersonGrantCountQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/persongrantcount/PersonGrantCountQueryRunner.java @@ -128,7 +128,7 @@ public class PersonGrantCountQueryRunner implements QueryRunner>{ + "?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; } diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/PersonPublicationCountQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/PersonPublicationCountQueryRunner.java index 3c978559..661b3c35 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/PersonPublicationCountQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/personpubcount/PersonPublicationCountQueryRunner.java @@ -186,7 +186,7 @@ public class PersonPublicationCountQueryRunner implements QueryRunner \n" + sparqlQuery); + log.debug("SPARQL query for person pub count -> \n" + sparqlQuery); return sparqlQuery; }
" + tableCode + csvDownloadURLHref + "
" + fullTimelineLink + "