1. Code cleanup & refactor.

2. More code documentation.
3. Minor change in wordings.
This commit is contained in:
cdtank 2010-08-03 23:04:44 +00:00
parent fc6da3a68f
commit 0846299deb
34 changed files with 1127 additions and 1173 deletions

View file

@ -2,34 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.visualization;
/*
Copyright (c) 2010, Cornell University
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Cornell University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.IOException;
import java.util.Map;
@ -51,7 +23,6 @@ import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelMaker;
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
@ -69,8 +40,6 @@ public class VisualizationController extends BaseEditController {
private Map<String, VisualizationRequestHandler> visualizationIDsToClass;
private static final String VIS_TYPE_URL_HANDLE = "vis";
public static final String URL_ENCODING_SCHEME = "UTF-8";
private static final long serialVersionUID = 1L;
@ -79,25 +48,11 @@ public class VisualizationController extends BaseEditController {
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
//TODO: For later, might want to improve these names for clarity.
public static final String PERSON_PUBLICATION_COUNT_VIS_URL_VALUE
= "person_pub_count";
public static final String PDF_REPORT_VIS_URL_VALUE
= "pdf_report";
public static final String COLLEGE_PUBLICATION_COUNT_VIS_URL_VALUE
= "college_pub_count";
public static final String COAUTHORSHIP_VIS_URL_VALUE
= "coauthorship";
public static final String PERSON_LEVEL_VIS_URL_VALUE
= "person_level";
public static final String UTILITIES_URL_VALUE
= "utilities";
/* This method is overridden to inject vis dependencies i.e. the vis algorithms that are
* being implemented into the vis controller. Modified Dependency Injection pattern is
* used here. XML file containing the location of all the vis is saved in accessible folder.
* @see javax.servlet.GenericServlet#init()
*/
@Override
public void init() throws ServletException {
super.init();
@ -135,36 +90,42 @@ public class VisualizationController extends BaseEditController {
throws ServletException, IOException {
super.doGet(request, response);
VitroRequest vreq = handleLoginAuthentication(request, response);
VitroRequest vitroRequest = new VitroRequest(request);
String visTypeURLHandle = vreq.getParameter(VIS_TYPE_URL_HANDLE);
/*
* Based on the query parameters passed via URI get the appropriate visualization
* request handler.
* */
VisualizationRequestHandler visRequestHandler =
getVisualizationRequestHandler(request, response, vitroRequest);
VisualizationRequestHandler visRequestHandler = null;
try {
visRequestHandler = visualizationIDsToClass.get(visTypeURLHandle);
} catch (NullPointerException nullKey) {
/*
* Pass the query to the selected visualization request handler & render the visualization.
* Since the visualization content is directly added to the response object we are side-
* effecting this method.
* */
renderVisualization(request, response, vitroRequest, visRequestHandler);
/*
* This is side-effecting because the error content is directly
* added to the request object. From where it is redirected to
* the error page.
* */
handleMalformedParameters("Inappropriate query parameters were submitted. ",
request,
response);
}
return;
}
DataSource dataSource = setupJENADataSource(request,
private void renderVisualization(HttpServletRequest request,
HttpServletResponse response,
VitroRequest vitroRequest,
VisualizationRequestHandler visRequestHandler)
throws ServletException, IOException {
DataSource dataSource = setupJENADataSource(request,
response,
vreq);
vitroRequest);
if (dataSource != null && visRequestHandler != null) {
/*
* This is side-effecting because the visualization content is added
* to the request object.
* */
visRequestHandler.generateVisualization(vreq, request, response, log, dataSource);
visRequestHandler.generateVisualization(vitroRequest,
request,
response,
log,
dataSource);
} else {
@ -177,46 +138,31 @@ public class VisualizationController extends BaseEditController {
log.error(errorMessage);
}
}
return;
}
private VisualizationRequestHandler getVisualizationRequestHandler(
HttpServletRequest request,
HttpServletResponse response,
VitroRequest vitroRequest)
throws ServletException, IOException {
private VitroRequest handleLoginAuthentication(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// This might not be required
/*
* why are there multiple places where the login is checked? shud be abtracted into
* new methoid?
* */
// if( !checkLoginStatus(request, response) )
// return null;
String visType = vitroRequest.getParameter(VisualizationFrameworkConstants
.VIS_TYPE_KEY);
VisualizationRequestHandler visRequestHandler = null;
try {
visRequestHandler = visualizationIDsToClass.get(visType);
} catch (NullPointerException nullKeyException) {
VitroRequest vreq = new VitroRequest(request);
Object obj = vreq.getSession().getAttribute("loginHandler");
LoginFormBean loginHandler = null;
if (obj != null && obj instanceof LoginFormBean) {
loginHandler = ((LoginFormBean) obj);
}
/*
* what is the speciality of 5 in the conditions?
*
if( loginHandler == null ||
! "authenticated".equalsIgnoreCase(loginHandler.getLoginStatus()) ||
Integer.parseInt(loginHandler.getLoginRole()) <= 5 ){
HttpSession session = request.getSession(true);
session.setAttribute("postLoginRequest",
vreq.getRequestURI()+( vreq.getQueryString()!=null?('?' + vreq.getQueryString()):"" ));
String redirectURL = request.getContextPath() + Controllers.SITE_ADMIN + "?login=block";
response.sendRedirect(redirectURL);
return null;
}
*/
return vreq;
/*
* This is side-effecting because the error content is directly
* added to the request object. From where it is redirected to
* the error page.
* */
handleMalformedParameters("Inappropriate query parameters were submitted. ",
request,
response);
}
return visRequestHandler;
}
private DataSource setupJENADataSource(HttpServletRequest request,

View file

@ -5,37 +5,65 @@ package edu.cornell.mannlib.vitro.webapp.controller.visualization;
public class VisualizationFrameworkConstants {
/*
* Contains the location of bean containing info on all the visualizations available
* in that instance. Currently it is stored under "productMods/WEB-INF..."
* */
* Contains the location of bean containing info on all the visualizations
* available in that instance. Currently it is stored under
* "productMods/WEB-INF..."
*/
public static final String RELATIVE_LOCATION_OF_VISUALIZATIONS_BEAN =
"/WEB-INF/visualization/visualizations-beans-injection.xml";
"/WEB-INF/visualization/visualizations-beans-injection.xml";
/*
* Vis URL prefix that is seen by all the users
* */
*/
public static final String VISUALIZATION_URL_PREFIX = "/visualization";
public static final String INDIVIDUAL_URL_PREFIX = "/individual";
public static final String VIS_TYPE_URL_HANDLE = "vis";
public static final String VIS_CONTAINER_URL_HANDLE = "container";
public static final String INDIVIDUAL_URI_URL_HANDLE = "uri";
public static final String VIS_MODE_URL_HANDLE = "vis_mode";
public static final String RENDER_MODE_URL_HANDLE = "render_mode";
/*
* These represent possible query keys in a URI for visualization purposes.
* Examples,
* 1. http://vivo.indiana.edu/visualization?uri=http://vivoweb.org/ontology/core/Person10979&vis=person_level&render_mode=standalone
* 2. http://vivo.indiana.edu/visualization?uri=http://vivoweb.org/ontology/core/Person72&vis=person_pub_count&render_mode=dynamic&container=vis_container
* */
public static final String VIS_TYPE_KEY = "vis";
public static final String VIS_CONTAINER_KEY = "container";
public static final String INDIVIDUAL_URI_KEY = "uri";
public static final String VIS_MODE_KEY = "vis_mode";
public static final String RENDER_MODE_KEY = "render_mode";
public static final String STANDALONE_RENDER_MODE_URL_VALUE = "standalone";
public static final String DYNAMIC_RENDER_MODE_URL_VALUE = "dynamic";
public static final String DATA_RENDER_MODE_URL_VALUE = "data";
public static final String PDF_RENDER_MODE_URL_VALUE = "pdf";
public static final String IMAGE_VIS_MODE_URL_VALUE = "image";
public static final String SPARKLINE_VIS_MODE_URL_VALUE = "sparkline";
public static final String COAUTHORSLIST_VIS_MODE_URL_VALUE = "coauthors";
/*
* These values represent possible render modes.
* */
public static final String STANDALONE_RENDER_MODE = "standalone";
public static final String DYNAMIC_RENDER_MODE = "dynamic";
public static final String DATA_RENDER_MODE = "data";
public static final String PDF_RENDER_MODE = "pdf";
/*
* These values represent possible sub-vis modes.
* */
public static final String IMAGE_VIS_MODE = "image";
public static final String SPARKLINE_VIS_MODE = "sparkline";
public static final String COAUTHORSLIST_VIS_MODE = "coauthors";
public static final String SHORT_SPARKLINE_VIS_MODE = "short";
public static final String FULL_SPARKLINE_VIS_MODE = "full";
/*
* These values represent possible utilities vis modes.
* */
public static final String PROFILE_INFO_UTILS_VIS_MODE = "PROFILE_INFO";
public static final String PROFILE_UTILS_VIS_MODE = "PROFILE_URL";
public static final String COAUTHOR_UTILS_VIS_MODE = "COAUTHORSHIP_URL";
public static final String PERSON_LEVEL_UTILS_VIS_MODE = "PERSON_LEVEL_URL";
public static final String IMAGE_UTILS_VIS_MODE = "IMAGE_URL";
/*
* These values represent possible visualizations provided as values to the "vis" url key.
* */
public static final String PERSON_PUBLICATION_COUNT_VIS = "person_pub_count";
public static final String PDF_REPORT_VIS = "pdf_report";
public static final String COLLEGE_PUBLICATION_COUNT_VIS = "college_pub_count";
public static final String COAUTHORSHIP_VIS = "coauthorship";
public static final String PERSON_LEVEL_VIS = "person_level";
public static final String UTILITIES_VIS = "utilities";
}

View file

@ -12,7 +12,7 @@ import java.util.Set;
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.valueobjects.CoAuthorshipVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
@ -28,7 +28,7 @@ public class CoAuthorshipGraphMLWriter {
private final String GRAPHML_FOOTER = "</graphml>";
public CoAuthorshipGraphMLWriter(CoAuthorshipVOContainer visVOContainer) {
public CoAuthorshipGraphMLWriter(CoAuthorshipData visVOContainer) {
coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer);
@ -39,7 +39,7 @@ public class CoAuthorshipGraphMLWriter {
}
private StringBuilder createCoAuthorshipGraphMLContent(
CoAuthorshipVOContainer visVOContainer) {
CoAuthorshipData coAuthorshipData) {
StringBuilder graphMLContent = new StringBuilder();
@ -50,30 +50,30 @@ public class CoAuthorshipGraphMLWriter {
* another String object to hold key definition data will be redundant & will
* not serve the purpose.
* */
generateKeyDefinitionContent(visVOContainer, graphMLContent);
generateKeyDefinitionContent(coAuthorshipData, graphMLContent);
/*
* Used to generate graph content. It will contain both the nodes & edge information.
* We are side-effecting "graphMLContent".
* */
generateGraphContent(visVOContainer, graphMLContent);
generateGraphContent(coAuthorshipData, graphMLContent);
graphMLContent.append(GRAPHML_FOOTER);
return graphMLContent;
}
private void generateGraphContent(CoAuthorshipVOContainer visVOContainer,
private void generateGraphContent(CoAuthorshipData coAuthorshipData,
StringBuilder graphMLContent) {
graphMLContent.append("\n<graph edgedefault=\"undirected\">\n");
if (visVOContainer.getNodes() != null & visVOContainer.getNodes().size() > 0) {
generateNodeSectionContent(visVOContainer, graphMLContent);
if (coAuthorshipData.getNodes() != null & coAuthorshipData.getNodes().size() > 0) {
generateNodeSectionContent(coAuthorshipData, graphMLContent);
}
if (visVOContainer.getEdges() != null & visVOContainer.getEdges().size() > 0) {
generateEdgeSectionContent(visVOContainer, graphMLContent);
if (coAuthorshipData.getEdges() != null & coAuthorshipData.getEdges().size() > 0) {
generateEdgeSectionContent(coAuthorshipData, graphMLContent);
}
graphMLContent.append("</graph>\n");
@ -83,12 +83,12 @@ public class CoAuthorshipGraphMLWriter {
}
private void generateEdgeSectionContent(CoAuthorshipVOContainer visVOContainer,
private void generateEdgeSectionContent(CoAuthorshipData coAuthorshipData,
StringBuilder graphMLContent) {
graphMLContent.append("<!-- edges -->\n");
Set<Edge> edges = visVOContainer.getEdges();
Set<Edge> edges = coAuthorshipData.getEdges();
List<Edge> orderedEdges = new ArrayList<Edge>(edges);
@ -108,11 +108,6 @@ public class CoAuthorshipGraphMLWriter {
private void getEdgeContent(StringBuilder graphMLContent, Edge currentEdge) {
/*
System.out.print("EDGE_ID:" + currentEdge.getEdgeID() + "|");
System.out.print("EDGE_SOURCE:" + currentEdge.getSourceNode().getNodeURL() + "|");
System.out.println("EDGE_TARGET:" + currentEdge.getTargetNode().getNodeURL());
*/
graphMLContent.append("<edge "
+ "id=\"" + currentEdge.getEdgeID() + "\" "
+ "source=\"" + currentEdge.getSourceNode().getNodeID() + "\" "
@ -136,7 +131,6 @@ public class CoAuthorshipGraphMLWriter {
/*
* 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
: currentEdge.getEarliestCollaborationYearCount().entrySet()) {
@ -148,8 +142,6 @@ public class CoAuthorshipGraphMLWriter {
graphMLContent.append("\t<data key=\"num_earliest_collaboration\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
@ -179,17 +171,15 @@ public class CoAuthorshipGraphMLWriter {
}
graphMLContent.append("</edge>\n");
}
private void generateNodeSectionContent(CoAuthorshipVOContainer visVOContainer,
private void generateNodeSectionContent(CoAuthorshipData coAuthorshipData,
StringBuilder graphMLContent) {
graphMLContent.append("<!-- nodes -->\n");
Node egoNode = visVOContainer.getEgoNode();
Set<Node> authorNodes = visVOContainer.getNodes();
Node egoNode = coAuthorshipData.getEgoNode();
Set<Node> authorNodes = coAuthorshipData.getNodes();
/*
* This method actually creates the XML code for a single node. "graphMLContent"
@ -224,21 +214,17 @@ public class CoAuthorshipGraphMLWriter {
String profileURL = null;
try {
profileURL = "/individual?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(node.getNodeURL(),
profileURL = VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX + "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(node.getNodeURI(),
VisualizationController
.URL_ENCODING_SCHEME).toString();
} catch (UnsupportedEncodingException e) {
System.err.println("URL Encoding ERRor. Move this to use log.error ASAP");
}
// System.out.print("NODE_ID:" + node.getNodeID() + "|");
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURL() + "</data>\n");
// graphMLContent.append("\t<data key=\"name\">" + node.getNodeName() + "</data>\n");
// System.out.println("NODE_NAME:" + node.getNodeURL());
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");
graphMLContent.append("\t<data key=\"label\">" + node.getNodeName() + "</data>\n");
if (profileURL != null) {
@ -267,8 +253,6 @@ public class CoAuthorshipGraphMLWriter {
graphMLContent.append("\t<data key=\"num_earliest_publication\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
@ -285,8 +269,6 @@ public class CoAuthorshipGraphMLWriter {
graphMLContent.append("\t<data key=\"num_latest_publication\">"
+ publicationInfo.getValue()
+ "</data>\n");
}
}
@ -302,7 +284,7 @@ public class CoAuthorshipGraphMLWriter {
graphMLContent.append("</node>\n");
}
private void generateKeyDefinitionContent(CoAuthorshipVOContainer visVOContainer,
private void generateKeyDefinitionContent(CoAuthorshipData visVOContainer,
StringBuilder graphMLContent) {
/*
@ -345,8 +327,6 @@ public class CoAuthorshipGraphMLWriter {
} else {
graphMLContent.append("/>\n");
}
}
}
}

View file

@ -30,25 +30,27 @@ 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.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
/**
* This query runner is used to execute a sparql query to get all the publications
* for a particular individual. It will also fetch all the authors that worked
* on that particular publication.
*
* @author cdtank
*/
public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOContainer> {
public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
private static final int MAX_AUTHORS_PER_PAPER_ALLOWED = 100;
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
private String egoURLParam;
private String egoURI;
private Map<String, VivoCollegeOrSchool> collegeURLToVO =
new HashMap<String, VivoCollegeOrSchool>();
@ -60,10 +62,10 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
private UniqueIDGenerator edgeIDGenerator;
public CoAuthorshipQueryHandler(String egoURLParam,
public CoAuthorshipQueryRunner(String egoURI,
DataSource dataSource, Log log) {
this.egoURLParam = egoURLParam;
this.egoURI = egoURI;
this.dataSource = dataSource;
this.log = log;
@ -72,7 +74,7 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
}
private CoAuthorshipVOContainer createJavaValueObjects(ResultSet resultSet) {
private CoAuthorshipData createQueryResult(ResultSet resultSet) {
Set<Node> nodes = new HashSet<Node>();
@ -149,11 +151,6 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
}
}
/*
System.out.print("PERSON_URL:" + egoAuthorURLNode.toString() + "|");
System.out.print("DOCUMENT_URL:" + documentNode.toString() + "|");
System.out.println("CO_AUTHOR_URL:" + coAuthorURLNode.toString());
*/
coAuthorNode.addAuthorDocument(biboDocument);
Set<Node> coAuthorsForCurrentBiboDocument;
@ -190,11 +187,49 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
}
/*
* This code snippet takes out all the edges belong to documents that have more than
* 100 authors. We conjecture that these papers do not provide much insight. However,
* we have left the documents be, just the edges are removed.
* This method takes out all the authors & edges between authors that belong to documents
* that have more than 100 authors. We conjecture that these papers do not provide much
* insight. However, we have left the documents be.
*
* This method side-effects "nodes" & "edges".
* */
removeLowQualityNodesAndEdges(nodes,
biboDocumentURLToVO,
biboDocumentURLToCoAuthors,
edges);
/*
* We need to create edges between 2 co-authors. E.g. On a paper there were 3 authors
* 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-authors on all the publications considered so far. The
* other reason being we dont want to compare against 2 sets of edges (edges created before
* & co-author edges created during the course of this method) when we are creating a new
* edge.
* */
createCoAuthorEdges(biboDocumentURLToVO,
biboDocumentURLToCoAuthors,
edges,
edgeUniqueIdentifierToVO);
return new CoAuthorshipData(egoNode, nodes, edges);
}
private void removeLowQualityNodesAndEdges(Set<Node> nodes,
Map<String, BiboDocument> biboDocumentURLToVO,
Map<String, Set<Node>> biboDocumentURLToCoAuthors,
Set<Edge> edges) {
Set<Node> nodesToBeRemoved = new HashSet<Node>();
for (Map.Entry<String, Set<Node>> currentBiboDocumentEntry
: biboDocumentURLToCoAuthors.entrySet()) {
@ -219,30 +254,15 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
edges.removeAll(edgesToBeRemoved);
for (Node currentCoAuthor : currentBiboDocumentEntry.getValue()) {
currentCoAuthor.getAuthorDocuments().remove(currentBiboDocument);
if (currentCoAuthor.getAuthorDocuments().isEmpty()) {
nodesToBeRemoved.add(currentCoAuthor);
}
}
}
}
/*
* We need to create edges between 2 co-authors. E.g. On a paper there were 3 authors
* 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-authors on all the publications considered so far. The
* other reason being we dont want to compare against 2 sets of edges (edges created before
* & co-author edges created during the course of this method) when we are creating a new
* edge.
* */
createCoAuthorEdges(biboDocumentURLToVO,
biboDocumentURLToCoAuthors,
edges,
edgeUniqueIdentifierToVO);
return new CoAuthorshipVOContainer(egoNode, nodes, edges);
nodes.removeAll(nodesToBeRemoved);
}
private void createCoAuthorEdges(
@ -252,6 +272,7 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
for (Map.Entry<String, Set<Node>> currentBiboDocumentEntry
: biboDocumentURLToCoAuthors.entrySet()) {
/*
* If there was only one co-author (other than ego) then we dont have to create any
* edges. so the below condition will take care of that.
@ -312,9 +333,9 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
}
private Edge getExistingEdge(
Node collaboratingNode1,
Node collaboratingNode2,
Map<String, Edge> edgeUniqueIdentifierToVO) {
Node collaboratingNode1,
Node collaboratingNode2,
Map<String, Edge> edgeUniqueIdentifierToVO) {
String edgeUniqueIdentifier = getEdgeUniqueIdentifier(collaboratingNode1.getNodeID(),
collaboratingNode2.getNodeID());
@ -438,25 +459,21 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
+ "} "
+ "ORDER BY ?document ?coAuthorPerson";
System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
// System.out.println("COAUTHORSHIP QUERY - " + sparqlQuery);
return sparqlQuery;
}
public CoAuthorshipVOContainer getVisualizationJavaValueObjects()
public CoAuthorshipData getQueryResult()
throws MalformedQueryParametersException {
/*
System.out.println("***************************************************************************************");
System.out.println("Entered into coauthorship query handler at " + System.currentTimeMillis());
System.out.println("***************************************************************************************");
*/
if (StringUtils.isNotBlank(this.egoURLParam)) {
if (StringUtils.isNotBlank(this.egoURI)) {
/*
* To test for the validity of the URI submitted.
* */
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
IRI iri = iRIFactory.create(this.egoURLParam);
IRI iri = iRIFactory.create(this.egoURI);
if (iri.hasViolation(false)) {
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
log.error("Ego Co-Authorship Vis Query " + errorMsg);
@ -467,13 +484,9 @@ public class CoAuthorshipQueryHandler implements QueryHandler<CoAuthorshipVOCont
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
}
ResultSet resultSet = executeQuery(generateEgoCoAuthorshipSparqlQuery(this.egoURLParam),
ResultSet resultSet = executeQuery(generateEgoCoAuthorshipSparqlQuery(this.egoURI),
this.dataSource);
/*
System.out.println("***************************************************************************************");
System.out.println("***************************************************************************************");
*/
return createJavaValueObjects(resultSet);
return createQueryResult(resultSet);
}
}

View file

@ -4,13 +4,11 @@ package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -20,17 +18,24 @@ 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.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
/**
* This request handler is used when information related to co-authorship network
* for an individual is requested. It currently provides 2 outputs,
* 1. Graphml content representing the individual's co-authorship network
* 1. CSV file containing the list(& count) of unique co-authors with which
* the individual has worked over the years. This data powers the related sparkline.
*
* @author cdtank
*/
public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
public void generateVisualization(VitroRequest vitroRequest,
@ -39,51 +44,41 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
Log log,
DataSource dataSource) {
String egoURIParam = vitroRequest.getParameter(
String egoURI = vitroRequest.getParameter(
VisualizationFrameworkConstants
.INDIVIDUAL_URI_URL_HANDLE);
.INDIVIDUAL_URI_KEY);
String renderMode = vitroRequest.getParameter(
VisualizationFrameworkConstants
.RENDER_MODE_URL_HANDLE);
.RENDER_MODE_KEY);
String visMode = vitroRequest.getParameter(
VisualizationFrameworkConstants
.VIS_MODE_URL_HANDLE);
.VIS_MODE_KEY);
QueryHandler<CoAuthorshipVOContainer> queryManager =
new CoAuthorshipQueryHandler(egoURIParam,
dataSource,
log);
QueryRunner<CoAuthorshipData> queryManager =
new CoAuthorshipQueryRunner(egoURI, dataSource, log);
try {
CoAuthorshipData authorNodesAndEdges =
queryManager.getQueryResult();
CoAuthorshipVOContainer authorNodesAndEdges =
queryManager.getVisualizationJavaValueObjects();
/*
* In order to avoid unneeded computations we have pushed this "if" condition up.
* This case arises when the render mode is data. In that case we dont want to generate
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
* It is ugly!
* */
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
/*
* We will be using the same visualization package for both sparkline & coauthorship
* flash vis. We will use "VIS_MODE_URL_HANDLE" as a modifier to differentiate
* between these two. The defualt will be to render the coauthorship network vis.
* flash vis. We will use "VIS_MODE_KEY" as a modifier to differentiate
* between these two. The default will be to render the coauthorship network vis.
* */
if (VisualizationFrameworkConstants.SPARKLINE_VIS_MODE_URL_VALUE
if (VisualizationFrameworkConstants.SPARKLINE_VIS_MODE
.equalsIgnoreCase(visMode)) {
/*
* When the csv file is required - based on which sparkline visualization will
* be rendered.
* */
prepareVisualizationQuerySparklineDataResponse(authorNodesAndEdges,
prepareSparklineDataResponse(authorNodesAndEdges,
response);
return;
@ -92,14 +87,20 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
* When the graphML file is required - based on which coauthorship network
* visualization will be rendered.
* */
prepareVisualizationQueryNetworkDataResponse(authorNodesAndEdges, response);
prepareNetworkDataResponse(authorNodesAndEdges, response);
return;
}
}
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(), vitroRequest, request, response, log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - Co-authorship Network",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -110,8 +111,89 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
}
private void prepareVisualizationQueryNetworkDataResponse(
CoAuthorshipVOContainer authorNodesAndEdges, HttpServletResponse response) {
private void writeCoauthorsPerYearCSV(Map<String, Set<Node>> yearToCoauthors,
PrintWriter printWriter) {
// printWriter.append("\"Year\", \"Count\", \"Co-Author(s)\"\n");
printWriter.append("Year, Count, Co-Author(s)\n");
for (Entry<String, Set<Node>> currentEntry : yearToCoauthors.entrySet()) {
printWriter.append("\"" + currentEntry.getKey() + "\","
+ "\"" + currentEntry.getValue().size() + "\","
+ "\"" + getCoauthorNamesAsString(currentEntry.getValue())
+ "\"\n");
}
printWriter.flush();
}
private String getCoauthorNamesAsString(Set<Node> coAuthors) {
StringBuilder coAuthorsMerged = new StringBuilder();
String coAuthorSeparator = "; ";
for (Node currCoAuthor : coAuthors) {
coAuthorsMerged.append(currCoAuthor.getNodeName() + coAuthorSeparator);
}
return StringUtils.removeEnd(coAuthorsMerged.toString(), coAuthorSeparator);
}
/**
* Provides response when a csv file containing number & names of unique co-authors per
* year is requested.
* @param authorNodesAndEdges
* @param response
*/
private void prepareSparklineDataResponse(CoAuthorshipData authorNodesAndEdges,
HttpServletResponse response) {
String outputFileName;
Map<String, Set<Node>> yearToCoauthors = new TreeMap<String, Set<Node>>();
if (authorNodesAndEdges.getNodes() != null && authorNodesAndEdges.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(authorNodesAndEdges
.getEgoNode().getNodeName())
+ "_coauthors-per-year" + ".csv";
yearToCoauthors = UtilityFunctions.getPublicationYearToCoAuthors(authorNodesAndEdges);
} else {
outputFileName = "no_coauthors-per-year" + ".csv";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
writeCoauthorsPerYearCSV(yearToCoauthors, responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Provides a response when graphml formatted co-authorship network is requested, typically by
* the flash vis.
* @param authorNodesAndEdges
* @param response
*/
private void prepareNetworkDataResponse(
CoAuthorshipData authorNodesAndEdges, HttpServletResponse response) {
response.setContentType("text/xml");
@ -135,138 +217,4 @@ public class CoAuthorshipRequestHandler implements VisualizationRequestHandler {
}
}
private void prepareVisualizationQuerySparklineDataResponse(
CoAuthorshipVOContainer authorNodesAndEdges, HttpServletResponse response) {
String outputFileName;
Map<String, Set<Node>> yearToCoauthors = new TreeMap<String, Set<Node>>();
if (authorNodesAndEdges.getNodes() != null && authorNodesAndEdges.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(authorNodesAndEdges
.getEgoNode().getNodeName())
+ "_coauthors-per-year" + ".csv";
yearToCoauthors = getCoAuthorsStats(authorNodesAndEdges);
} else {
outputFileName = "no_coauthors-per-year" + ".csv";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
generateCsvFileBuffer(yearToCoauthors,
responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void generateCsvFileBuffer(Map<String, Set<Node>> yearToCoauthors,
PrintWriter printWriter) {
printWriter.append("\"Year\", \"Number of Co-Authors\", \"Co-Author(s)\"\n");
for (Entry<String, Set<Node>> currentEntry : yearToCoauthors.entrySet()) {
printWriter.append("\"" + currentEntry.getKey() + "\","
+ "\"" + currentEntry.getValue().size() + "\","
+ "\"" + getCoauthorsString(currentEntry.getValue()) + "\"\n"
);
}
printWriter.flush();
}
private String getCoauthorsString(Set<Node> coAuthors) {
StringBuilder coAuthorsMerged = new StringBuilder();
String coAuthorSeparator = "; ";
for (Node currCoAuthor : coAuthors) {
coAuthorsMerged.append(currCoAuthor.getNodeName() + coAuthorSeparator);
}
return StringUtils.removeEnd(coAuthorsMerged.toString(), coAuthorSeparator);
}
private Map<String, Set<Node>> getCoAuthorsStats(CoAuthorshipVOContainer authorNodesAndEdges) {
Map<String, Set<Node>> yearToCoAuthors = new TreeMap<String, Set<Node>>();
Node egoNode = authorNodesAndEdges.getEgoNode();
for (Node currNode : authorNodesAndEdges.getNodes()) {
/*
* We have already printed the Ego Node info.
* */
if (currNode != egoNode) {
for (String year : currNode.getYearToPublicationCount().keySet()) {
Set<Node> coAuthorNodes;
if (yearToCoAuthors.containsKey(year)) {
coAuthorNodes = yearToCoAuthors.get(year);
coAuthorNodes.add(currNode);
} else {
coAuthorNodes = new HashSet<Node>();
coAuthorNodes.add(currNode);
yearToCoAuthors.put(year, coAuthorNodes);
}
}
}
}
return yearToCoAuthors;
}
private void handleMalformedParameters(String errorMessage,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher =
request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp",
"/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title",
"Visualization Query Error - Individual Publication Count");
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -18,14 +18,23 @@ 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.Node;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
@SuppressWarnings("serial")
public class CoAuthorshipVisCodeGenerator {
private static final int MINIMUM_YEARS_CONSIDERED = 10;
/*
* 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 coauthors 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 yeras.
* */
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
put("SHORT_SPARK", "unique_coauthors_short_sparkline_vis");
@ -37,47 +46,52 @@ public class CoAuthorshipVisCodeGenerator {
private static final String DEFAULT_VISCONTAINER_DIV_ID = "unique_coauthors_vis_container";
public static final String SHORT_SPARKLINE_MODE_URL_HANDLE = "short";
public static final String FULL_SPARKLINE_MODE_URL_HANDLE = "full";
private Map<String, Set<Node>> yearToUniqueCoauthors;
private Log log;
private SparklineVOContainer valueObjectContainer;
private SparklineData sparklineData;
private String contextPath;
private String individualURIParam;
private String individualURI;
public CoAuthorshipVisCodeGenerator(String contextPath,
String individualURIParam,
String individualURI,
String visMode,
String visContainer,
Map<String, Set<Node>> yearToUniqueCoauthors,
SparklineVOContainer valueObjectContainer,
Log log) {
this.contextPath = contextPath;
this.individualURIParam = individualURIParam;
this.individualURI = individualURI;
this.yearToUniqueCoauthors = yearToUniqueCoauthors;
this.valueObjectContainer = valueObjectContainer;
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) {
valueObjectContainer.setSparklineContent(getMainVisualizationCode(visMode,
sparklineData.setSparklineContent(getMainVisualizationCode(visMode,
visContainer));
valueObjectContainer.setSparklineContext(getVisualizationContextCode(visMode));
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
}
@ -86,13 +100,15 @@ public class CoAuthorshipVisCodeGenerator {
int numOfYearsToBeRendered = 0;
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int shortSparkMinYear = currentYear - MINIMUM_YEARS_CONSIDERED + 1;
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_PUBLICATION_YEAR".
* */
Set<String> publishedYears = new HashSet(yearToUniqueCoauthors.keySet());
Set<String> publishedYears = new HashSet<String>(yearToUniqueCoauthors.keySet());
publishedYears.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
/*
@ -159,7 +175,6 @@ public class CoAuthorshipVisCodeGenerator {
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
int uniqueCoAuthorCounter = 0;
int totalUniqueCoAuthors = 0;
int renderedFullSparks = 0;
Set<Node> allCoAuthorsWithKnownAuthorshipYears = new HashSet<Node>();
@ -167,8 +182,8 @@ public class CoAuthorshipVisCodeGenerator {
publicationYear <= currentYear;
publicationYear++) {
String stringPublishedYear = String.valueOf(publicationYear);
Set<Node> currentCoAuthors = yearToUniqueCoauthors.get(stringPublishedYear);
String publicationYearAsString = String.valueOf(publicationYear);
Set<Node> currentCoAuthors = yearToUniqueCoauthors.get(publicationYearAsString);
Integer currentUniqueCoAuthors = null;
@ -182,7 +197,7 @@ public class CoAuthorshipVisCodeGenerator {
visualizationCode.append("data.setValue("
+ uniqueCoAuthorCounter
+ ", 0, '"
+ stringPublishedYear
+ publicationYearAsString
+ "');\n");
visualizationCode.append("data.setValue("
@ -193,22 +208,20 @@ public class CoAuthorshipVisCodeGenerator {
uniqueCoAuthorCounter++;
}
totalUniqueCoAuthors = allCoAuthorsWithKnownAuthorshipYears.size();
/*
* Sparks that will be rendered in full mode will always be the one's which has any year
* 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 = totalUniqueCoAuthors;
renderedFullSparks = allCoAuthorsWithKnownAuthorshipYears.size();
/*
* Total publications will also consider publications that have no year associated with
* it. Hence.
* them. Hence.
* */
Integer unknownYearCoauthors = 0;
if (yearToUniqueCoauthors.get(VOConstants.DEFAULT_PUBLICATION_YEAR) != null) {
totalUniqueCoAuthors += yearToUniqueCoauthors
.get(VOConstants.DEFAULT_PUBLICATION_YEAR).size();
unknownYearCoauthors = yearToUniqueCoauthors
.get(VOConstants.DEFAULT_PUBLICATION_YEAR).size();
}
@ -228,12 +241,12 @@ public class CoAuthorshipVisCodeGenerator {
* "short" sparkline mode we will set the Earliest RenderedPublication year to
* "currentYear - 10".
* */
valueObjectContainer.setEarliestRenderedPublicationYear(minPublishedYear);
valueObjectContainer.setLatestRenderedPublicationYear(currentYear);
sparklineData.setEarliestRenderedPublicationYear(minPublishedYear);
sparklineData.setLatestRenderedPublicationYear(currentYear);
/*
* The Full Sparkline will be rendered by default. Only if the url has specific mention of
* SHORT_SPARKLINE_MODE_URL_HANDLE then we render the short sparkline and not otherwise.
* SHORT_SPARKLINE_MODE_KEY then we render the short sparkline and not otherwise.
* */
@ -242,15 +255,14 @@ public class CoAuthorshipVisCodeGenerator {
* essentially a side-effecting process, we have both the activators method as
* side-effecting. They both side-effect "visualizationCode"
* */
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
valueObjectContainer.setEarliestRenderedPublicationYear(shortSparkMinYear);
sparklineData.setEarliestRenderedPublicationYear(shortSparkMinYear);
generateShortSparklineVisualizationContent(currentYear,
shortSparkMinYear,
visContainerID,
visualizationCode,
unknownYearCoauthors,
totalUniqueCoAuthors,
sparklineDisplayOptions);
} else {
generateFullSparklineVisualizationContent(currentYear,
@ -268,9 +280,11 @@ public class CoAuthorshipVisCodeGenerator {
}
private void generateShortSparklineVisualizationContent(int currentYear,
int shortSparkMinYear, String visContainerID,
StringBuilder visualizationCode, int unknownYearCoauthors,
int totalUniqueCoAuthors, String sparklineDisplayOptions) {
int shortSparkMinYear,
String visContainerID,
StringBuilder visualizationCode,
int unknownYearCoauthors,
String sparklineDisplayOptions) {
/*
* Create a view of the data containing only the column pertaining to publication count.
@ -345,27 +359,22 @@ public class CoAuthorshipVisCodeGenerator {
}
private void generateFullSparklineVisualizationContent(
int currentYear,
int minPubYearConsidered,
String visContainerID,
StringBuilder visualizationCode,
int unknownYearCoauthors,
int renderedFullSparks,
String sparklineDisplayOptions) {
private void generateFullSparklineVisualizationContent(int currentYear,
int minPubYearConsidered,
String visContainerID,
StringBuilder visualizationCode,
int unknownYearCoauthors,
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) {
@ -454,7 +463,7 @@ public class CoAuthorshipVisCodeGenerator {
private String getVisualizationContextCode(String visMode) {
String visualizationContextCode = "";
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
visualizationContextCode = generateShortVisContext();
} else {
visualizationContextCode = generateFullVisContext();
@ -478,12 +487,10 @@ public class CoAuthorshipVisCodeGenerator {
csvDownloadURLHref = "Download data as <a href='"
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
valueObjectContainer.setDownloadDataLink(getCSVDownloadURL());
sparklineData.setDownloadDataLink(getCSVDownloadURL());
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
@ -496,16 +503,14 @@ public class CoAuthorshipVisCodeGenerator {
String tableCode = generateDataTable();
divContextCode.append("<p>" + tableCode
+ csvDownloadURLHref + "</p>");
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
valueObjectContainer.setTable(tableCode);
sparklineData.setTable(tableCode);
return divContextCode.toString();
}
private String getCSVDownloadURL()
throws UnsupportedEncodingException {
private String getCSVDownloadURL() throws UnsupportedEncodingException {
if (yearToUniqueCoauthors.size() > 0) {
@ -517,25 +522,24 @@ public class CoAuthorshipVisCodeGenerator {
String downloadURL = contextPath
+ secondaryContextPath
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ "=" + URLEncoder.encode(VisualizationController
.COAUTHORSHIP_VIS_URL_VALUE,
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.COAUTHORSHIP_VIS,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE
+ "&" + VisualizationFrameworkConstants.VIS_MODE_KEY
+ "=" + URLEncoder.encode("sparkline",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE,
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
return downloadURL;
} else {
return null;
}
}
private String generateShortVisContext() {
@ -555,33 +559,31 @@ public class CoAuthorshipVisCodeGenerator {
String fullTimelineNetworkURL = contextPath
+ secondaryContextPath
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("person_level",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE
+ VisualizationFrameworkConstants.VIS_CONTAINER_KEY
+ "=" + URLEncoder.encode("ego_sparkline",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(
VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE_URL_VALUE,
.STANDALONE_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
fullTimelineLink = "<a href='" + fullTimelineNetworkURL
+ "'>View full timeline and co-author network</a><br />";
valueObjectContainer.setFullTimelineNetworkLink(fullTimelineNetworkURL);
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
} else {
fullTimelineLink = "No data available to render full timeline.<br />";
}
divContextCode.append("<p>" + fullTimelineLink + "</p>");
@ -619,4 +621,8 @@ public class CoAuthorshipVisCodeGenerator {
return dataTable.toString();
}
public SparklineData getValueObjectContainer() {
return sparklineData;
}
}

View file

@ -7,6 +7,11 @@ import java.util.Comparator;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
/**
* This Comparator is used to sort the edges based on their IDs in ascending order.
* @author cdtank
*
*/
public class EdgeComparator implements Comparator<Edge> {
@Override

View file

@ -7,6 +7,10 @@ import java.util.Comparator;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
/**
* This Comparator is used to sort the nodes based on their IDs in ascending order.
* @author cdtank
*/
public class NodeComparator implements Comparator<Node> {
@Override

View file

@ -31,29 +31,28 @@ import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoDepartmentOrDivision;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoEmployee;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
/**
* @author cdtank
*
*/
public class CollegePublicationCountQueryHandler implements QueryHandler<Set<VivoEmployee>> {
public class CollegePublicationCountQueryRunner implements QueryRunner<Set<VivoEmployee>> {
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
private String collegeURIParam;
private String collegeURI;
private Map<String, VivoCollegeOrSchool> collegeURLToVO =
new HashMap<String, VivoCollegeOrSchool>();
private DataSource dataSource;
private Log log;
public CollegePublicationCountQueryHandler(String collegeURIParam,
public CollegePublicationCountQueryRunner(String collegeURI,
DataSource dataSource, Log log) {
this.collegeURIParam = collegeURIParam;
this.collegeURI = collegeURI;
this.dataSource = dataSource;
this.log = log;
@ -296,15 +295,15 @@ public class CollegePublicationCountQueryHandler implements QueryHandler<Set<Viv
}
public Set<VivoEmployee> getVisualizationJavaValueObjects()
public Set<VivoEmployee> getQueryResult()
throws MalformedQueryParametersException {
if (StringUtils.isNotBlank(this.collegeURIParam)) {
if (StringUtils.isNotBlank(this.collegeURI)) {
/*
* To test for the validity of the URI submitted.
* */
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
IRI iri = iRIFactory.create(this.collegeURIParam);
IRI iri = iRIFactory.create(this.collegeURI);
if (iri.hasViolation(false)) {
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
log.error("Pub Count Vis Query " + errorMsg);
@ -315,7 +314,7 @@ public class CollegePublicationCountQueryHandler implements QueryHandler<Set<Viv
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
}
ResultSet resultSet = executeQuery(generateCollegeEmployeeSparqlQuery(this.collegeURIParam),
ResultSet resultSet = executeQuery(generateCollegeEmployeeSparqlQuery(this.collegeURI),
this.dataSource);
return createJavaValueObjects(resultSet);

View file

@ -14,10 +14,8 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -31,7 +29,6 @@ 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.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
@ -42,7 +39,7 @@ import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOr
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoDepartmentOrDivision;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoEmployee;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
@ -55,25 +52,25 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
DataSource dataSource) {
String collegeURIParam = vitroRequest.getParameter(
VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String renderMode = vitroRequest.getParameter(
VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
VisualizationFrameworkConstants.RENDER_MODE_KEY);
String visMode = vitroRequest.getParameter(
VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
VisualizationFrameworkConstants.VIS_MODE_KEY);
String visContainer = vitroRequest.getParameter(
VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE);
VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
QueryHandler<Set<VivoEmployee>> queryManager =
new CollegePublicationCountQueryHandler(collegeURIParam,
QueryRunner<Set<VivoEmployee>> queryManager =
new CollegePublicationCountQueryRunner(collegeURIParam,
dataSource,
log);
try {
Set<VivoEmployee> employees = queryManager.getVisualizationJavaValueObjects();
Set<VivoEmployee> employees = queryManager.getQueryResult();
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime =
new HashMap<VivoDepartmentOrDivision, Map<String, Integer>>();
@ -111,10 +108,10 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
* It is ugly!
* */
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
prepareVisualizationQueryDataResponse(
if (VisualizationFrameworkConstants.DATA_RENDER_MODE.equalsIgnoreCase(renderMode)) {
prepareDataResponse(
departmentToPublicationsOverTime,
((CollegePublicationCountQueryHandler) queryManager).getCollegeURLToVO(),
((CollegePublicationCountQueryRunner) queryManager).getCollegeURLToVO(),
response);
log.debug(publishedYearsForCollege);
@ -143,7 +140,13 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(), vitroRequest, request, response, log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - College Publication Count",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -204,7 +207,7 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
return departmentYearToPublicationCount;
}
private void prepareVisualizationQueryPDFResponse(Individual college,
private void preparePDFResponse(Individual college,
List<BiboDocument> authorDocuments,
Map<String, Integer> yearToPublicationCount,
HttpServletResponse response) {
@ -264,7 +267,7 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
}
}
private void prepareVisualizationQueryDataResponse(
private void prepareDataResponse(
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime,
Map<String, VivoCollegeOrSchool> collegeURLToVO, HttpServletResponse response) {
@ -358,7 +361,7 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
}
private void prepareVisualizationQueryStandaloneResponse(HttpServletRequest request,
private void prepareStandaloneResponse(HttpServletRequest request,
HttpServletResponse response, VitroRequest vreq,
String visContentCode, String visContextCode) {
@ -374,7 +377,7 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
}
private void prepareVisualizationQueryDynamicResponse(HttpServletRequest request,
private void prepareDynamicResponse(HttpServletRequest request,
HttpServletResponse response, VitroRequest vreq,
String visContentCode, String visContextCode) {
@ -388,29 +391,4 @@ public class CollegePublicationCountRequestHandler implements VisualizationReque
}
private void handleMalformedParameters(String errorMessage,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.visualization.constants;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("serial")
public class QueryConstants {
public static final Map<String, String> PREFIX_TO_NAMESPACE = new HashMap<String, String>() { {
@ -47,17 +48,12 @@ public class QueryConstants {
StringBuilder prefixSection = new StringBuilder();
for (Map.Entry prefixEntry : PREFIX_TO_NAMESPACE.entrySet()) {
for (Map.Entry<String, String> prefixEntry : PREFIX_TO_NAMESPACE.entrySet()) {
prefixSection.append("PREFIX " + prefixEntry.getKey()
+ ": <" + prefixEntry.getValue() + ">\n");
}
return prefixSection.toString();
}
}

View file

@ -2,6 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
/**
* Thsi contains the sparql fields which are used to capture data for the value objects.
* @author cdtank
*/
public class QueryFieldLabels {
/*
@ -23,7 +27,6 @@ public class QueryFieldLabels {
public static final String DOCUMENT_PUBLICATION_YEAR_MONTH = "publicationYearMonthLit";
public static final String DOCUMENT_PUBLICATION_DATE = "publicationDateLit";
/*
* Image related field labels
* */

View file

@ -2,6 +2,12 @@
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
import java.util.Calendar;
/**
* This contains the constants related to all the value objects.
* @author cdtank
*/
public class VOConstants {
public static final String DEFAULT_PUBLICATION_YEAR = "Unknown";
@ -13,4 +19,9 @@ public class VOConstants {
ACADEMIC_FACULTY_EMPLOYEE, ACADEMIC_STAFF_EMPLOYEE
}
public static final int NUM_CHARS_IN_YEAR_FORMAT = 4;
public static final int MINIMUM_PUBLICATION_YEAR = 1800;
public static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
}

View file

@ -2,12 +2,16 @@
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
/**
* This contains constants related to the visualization code.
* @author cdtank
*/
public class VisConstants {
public static final int MAX_NAME_TEXT_LENGTH = 20;
public static final int MINIMUM_YEARS_CONSIDERED_FOR_SPARKLINE = 10;
public static final String RESULT_FORMAT_PARAM = "RS_TEXT";
public static final String RDF_RESULT_FORMAT_PARAM = "RDF/XML-ABBREV";
}

View file

@ -4,8 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.visualization.personlevel;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@ -25,19 +23,29 @@ import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipGraphMLWriter;
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipQueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipVisCodeGenerator;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountQueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountVisCodeGenerator;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
/**
* This request handler is used to serve content rendered on the person level vis page
* like,
* 1. Front end of the vis including the co-author & publication sparkline.
* 2. Downloadable file having the co-author network in graphml format.
* 3. Downloadable file having the list of co-authors that the individual has
* worked with & count of such co-authorships.
*
* @author cdtank
*/
public class PersonLevelRequestHandler implements VisualizationRequestHandler {
private static final String EGO_PUB_SPARKLINE_VIS_CONTAINER_ID = "ego_pub_sparkline";
@ -50,55 +58,42 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
Log log,
DataSource dataSource) {
String egoURIParam = vitroRequest.getParameter(
VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
String egoURI = vitroRequest.getParameter(
VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String renderMode = vitroRequest.getParameter(
VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
VisualizationFrameworkConstants.RENDER_MODE_KEY);
String visMode = vitroRequest.getParameter(
VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
VisualizationFrameworkConstants.VIS_MODE_KEY);
QueryHandler<CoAuthorshipVOContainer>
coAuthorshipQueryManager =
new CoAuthorshipQueryHandler(egoURIParam,
dataSource,
log);
QueryRunner<CoAuthorshipData> coAuthorshipQueryManager =
new CoAuthorshipQueryRunner(egoURI, dataSource, log);
QueryHandler<Set<BiboDocument>> publicationQueryManager =
new PersonPublicationCountQueryHandler(egoURIParam,
dataSource,
log);
QueryRunner<Set<BiboDocument>> publicationQueryManager =
new PersonPublicationCountQueryRunner(egoURI, dataSource, log);
try {
CoAuthorshipVOContainer coAuthorshipVO = coAuthorshipQueryManager
.getVisualizationJavaValueObjects();
CoAuthorshipData coAuthorshipData = coAuthorshipQueryManager.getQueryResult();
/*
* In order to avoid unneeded computations we have pushed this "if" condition up.
* This case arises when the render mode is data. In that case we dont want to generate
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
* It is ugly!
* */
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
/*
* We will be using the same visualization package for providing data for both
* list of unique coauthors & network of coauthors (used in the flash vis).
* We will use "VIS_MODE_URL_HANDLE" as a modifier to differentiate between
* these two. The defualt will be to provide data used to render the co-
* We will use "VIS_MODE_KEY" as a modifier to differentiate between
* these two. The default will be to provide data used to render the co-
* authorship network vis.
* */
if (VisualizationFrameworkConstants.COAUTHORSLIST_VIS_MODE_URL_VALUE
if (VisualizationFrameworkConstants.COAUTHORSLIST_VIS_MODE
.equalsIgnoreCase(visMode)) {
/*
* When the csv file is required - containing the unique co-authors vs how
* When the csv file is required - containing the co-authors & how
* many times they have co-authored with the ego.
* */
prepareVisualizationQueryListCoauthorsDataResponse(coAuthorshipVO,
prepareListCoauthorsDataResponse(coAuthorshipData,
response);
return;
@ -107,15 +102,21 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
* When the graphML file is required - based on which co-authorship
* network visualization will be rendered.
* */
prepareVisualizationQueryNetworkDataResponse(coAuthorshipVO, response);
prepareNetworkDataResponse(coAuthorshipData,
response);
return;
}
}
Set<BiboDocument> authorDocuments = publicationQueryManager
.getVisualizationJavaValueObjects();
/*
* When the front-end for the person level vis has to be displayed we render couple of
* sparklines. This will prepare all the data for the sparklines & other requested
* files.
* */
Set<BiboDocument> authorDocuments = publicationQueryManager.getQueryResult();
/*
* Create a map from the year to number of publications. Use the BiboDocument's
* parsedPublicationYear to populate the data.
@ -126,39 +127,39 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
/*
* Computations required to generate HTML for the sparklines & related context.
* */
SparklineVOContainer publicationSparklineVO = new SparklineVOContainer();
SparklineVOContainer uniqueCoauthorsSparklineVO = new SparklineVOContainer();
PersonPublicationCountVisCodeGenerator personPubCountVisCodeGenerator =
new PersonPublicationCountVisCodeGenerator(
vitroRequest.getRequestURI(),
egoURIParam,
PersonPublicationCountVisCodeGenerator.FULL_SPARKLINE_MODE_URL_HANDLE,
egoURI,
VisualizationFrameworkConstants.FULL_SPARKLINE_VIS_MODE,
EGO_PUB_SPARKLINE_VIS_CONTAINER_ID,
authorDocuments,
yearToPublicationCount,
publicationSparklineVO,
log);
SparklineData publicationSparklineVO = personPubCountVisCodeGenerator
.getValueObjectContainer();
CoAuthorshipVisCodeGenerator uniqueCoauthorsVisCodeGenerator =
new CoAuthorshipVisCodeGenerator(
vitroRequest.getRequestURI(),
egoURIParam,
PersonPublicationCountVisCodeGenerator.FULL_SPARKLINE_MODE_URL_HANDLE,
egoURI,
VisualizationFrameworkConstants.FULL_SPARKLINE_VIS_MODE,
UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID,
getUniqueCoAuthorsPerYear(coAuthorshipVO),
uniqueCoauthorsSparklineVO,
UtilityFunctions.getPublicationYearToCoAuthors(coAuthorshipData),
log);
SparklineData uniqueCoauthorsSparklineVO = uniqueCoauthorsVisCodeGenerator
.getValueObjectContainer();
RequestDispatcher requestDispatcher = null;
prepareVisualizationQueryStandaloneResponse(
egoURIParam,
prepareStandaloneResponse(
egoURI,
publicationSparklineVO,
uniqueCoauthorsSparklineVO,
coAuthorshipVO,
coAuthorshipData,
EGO_PUB_SPARKLINE_VIS_CONTAINER_ID,
UNIQUE_COAUTHORS_SPARKLINE_VIS_CONTAINER_ID,
vitroRequest,
@ -176,11 +177,14 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(),
vitroRequest,
request,
response,
log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - Person Level Visualization",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -190,124 +194,7 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
}
}
private Map<String, Set<Node>> getUniqueCoAuthorsPerYear(
CoAuthorshipVOContainer authorNodesAndEdges) {
Map<String, Set<Node>> yearToCoAuthors = new TreeMap<String, Set<Node>>();
Node egoNode = authorNodesAndEdges.getEgoNode();
for (Node currNode : authorNodesAndEdges.getNodes()) {
/*
* We have already printed the Ego Node info.
* */
if (currNode != egoNode) {
for (String year : currNode.getYearToPublicationCount().keySet()) {
Set<Node> coAuthorNodes;
if (yearToCoAuthors.containsKey(year)) {
coAuthorNodes = yearToCoAuthors.get(year);
coAuthorNodes.add(currNode);
} else {
coAuthorNodes = new HashSet<Node>();
coAuthorNodes.add(currNode);
yearToCoAuthors.put(year, coAuthorNodes);
}
}
}
}
return yearToCoAuthors;
}
private void prepareVisualizationQueryNetworkDataResponse(
CoAuthorshipVOContainer coAuthorsipVO, HttpServletResponse response) {
String outputFileName = "";
if (coAuthorsipVO.getNodes() != null && coAuthorsipVO.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(coAuthorsipVO.getEgoNode().getNodeName())
+ "_coauthor-network.graphml" + ".xml";
} else {
outputFileName = "no_coauthor-network.graphml" + ".xml";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
CoAuthorshipGraphMLWriter coAuthorShipGraphMLWriter =
new CoAuthorshipGraphMLWriter(coAuthorsipVO);
responseWriter.append(coAuthorShipGraphMLWriter.getCoAuthorshipGraphMLContent());
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void prepareVisualizationQueryListCoauthorsDataResponse(
CoAuthorshipVOContainer coAuthorshipVO, HttpServletResponse response) {
String outputFileName = "";
Map<String, Integer> coAuthorsToCount = new TreeMap<String, Integer>();
if (coAuthorshipVO.getNodes() != null && coAuthorshipVO.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(coAuthorshipVO.getEgoNode().getNodeName())
+ "_coauthors" + ".csv";
coAuthorsToCount = getCoAuthorsList(coAuthorshipVO);
} else {
outputFileName = "no_coauthors" + ".csv";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
generateCsvFileBuffer(coAuthorsToCount,
responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private Map<String, Integer> getCoAuthorsList(CoAuthorshipVOContainer coAuthorsipVO) {
private Map<String, Integer> getCoAuthorsList(CoAuthorshipData coAuthorsipVO) {
Map<String, Integer> coAuthorsToCount = new TreeMap<String, Integer>();
@ -325,10 +212,11 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
return coAuthorsToCount;
}
private void generateCsvFileBuffer(Map<String, Integer> coAuthorsToCount,
PrintWriter printWriter) {
private void writeCoAuthorsToWorksCSV(Map<String, Integer> coAuthorsToCount,
PrintWriter printWriter) {
printWriter.append("\"Co-Author\", \"Count\"\n");
// printWriter.append("\"Co-Author\", \"Count\"\n");
printWriter.append("Co-Author, Count\n");
for (Entry<String, Integer> currentEntry : coAuthorsToCount.entrySet()) {
@ -340,11 +228,106 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
printWriter.flush();
}
private void prepareVisualizationQueryStandaloneResponse(
String egoURIParam,
SparklineVOContainer egoPubSparklineVO,
SparklineVOContainer uniqueCoauthorsSparklineVO,
CoAuthorshipVOContainer coAuthorshipVO,
/**
* Provide response when graphml file for the co-authorship network is requested.
* @param coAuthorsipData
* @param response
*/
private void prepareNetworkDataResponse(
CoAuthorshipData coAuthorsipData, HttpServletResponse response) {
String outputFileName = "";
if (coAuthorsipData.getNodes() != null && coAuthorsipData.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(coAuthorsipData.getEgoNode().getNodeName())
+ "_coauthor-network.graphml" + ".xml";
} else {
outputFileName = "no_coauthor-network.graphml" + ".xml";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
CoAuthorshipGraphMLWriter coAuthorShipGraphMLWriter =
new CoAuthorshipGraphMLWriter(coAuthorsipData);
responseWriter.append(coAuthorShipGraphMLWriter.getCoAuthorshipGraphMLContent());
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Provides response when a csv file containing co-author names & number of co-authored works
* is requested.
* @param coAuthorshipData
* @param response
*/
private void prepareListCoauthorsDataResponse(
CoAuthorshipData coAuthorshipData, HttpServletResponse response) {
String outputFileName = "";
Map<String, Integer> coAuthorsToCount = new TreeMap<String, Integer>();
if (coAuthorshipData.getNodes() != null && coAuthorshipData.getNodes().size() > 0) {
outputFileName = UtilityFunctions.slugify(coAuthorshipData.getEgoNode().getNodeName())
+ "_coauthors" + ".csv";
coAuthorsToCount = getCoAuthorsList(coAuthorshipData);
} else {
outputFileName = "no_coauthors" + ".csv";
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
writeCoAuthorsToWorksCSV(coAuthorsToCount, responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* When the page for person level visualization is requested.
* @param egoURI
* @param egoPubSparklineVO
* @param uniqueCoauthorsSparklineVO
* @param coAuthorshipVO
* @param egoPubSparklineVisContainer
* @param uniqueCoauthorsSparklineVisContainer
* @param vitroRequest
* @param request
*/
private void prepareStandaloneResponse (
String egoURI,
SparklineData egoPubSparklineVO,
SparklineData uniqueCoauthorsSparklineVO,
CoAuthorshipData coAuthorshipVO,
String egoPubSparklineVisContainer,
String uniqueCoauthorsSparklineVisContainer,
VitroRequest vitroRequest,
@ -352,12 +335,12 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
Portal portal = vitroRequest.getPortal();
request.setAttribute("egoURIParam", egoURIParam);
request.setAttribute("egoURIParam", egoURI);
String title = "";
if (coAuthorshipVO.getNodes() != null && coAuthorshipVO.getNodes().size() > 0) {
request.setAttribute("numOfAuthors", coAuthorshipVO.getNodes().size());
title = "for " + coAuthorshipVO.getEgoNode().getNodeName();
title = coAuthorshipVO.getEgoNode().getNodeName() + " - ";
}
if (coAuthorshipVO.getEdges() != null && coAuthorshipVO.getEdges().size() > 0) {
@ -372,36 +355,9 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
request.setAttribute("uniqueCoauthorsSparklineVisContainerID",
uniqueCoauthorsSparklineVisContainer);
request.setAttribute("title", "Person Level Visualization " + title);
request.setAttribute("title", title + "Person Level Visualization");
request.setAttribute("portalBean", portal);
request.setAttribute("scripts", "/templates/visualization/person_level_inject_head.jsp");
request.setAttribute("bodyJsp", "/templates/visualization/person_level.jsp");
}
private void handleMalformedParameters(String errorMessage,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -2,12 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.visualization.personpubcount;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@ -30,19 +26,21 @@ 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.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Individual;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
/**
* @author cdtank
* This query runner is used to execute a sparql query that will fetch all the publications
* defined by bibo:Document property for a particular individual.
*
* @author cdtank
*/
public class PersonPublicationCountQueryHandler implements QueryHandler<Set<BiboDocument>> {
public class PersonPublicationCountQueryRunner implements QueryRunner<Set<BiboDocument>> {
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
private String queryParam;
private String personURI;
private DataSource dataSource;
private Individual author;
@ -74,10 +72,10 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
+ "OPTIONAL { ?document vitro:blurb ?documentBlurb } ."
+ "OPTIONAL { ?document vitro:description ?documentDescription }";
public PersonPublicationCountQueryHandler(String queryParam,
public PersonPublicationCountQueryRunner(String personURI,
DataSource dataSource, Log log) {
this.queryParam = queryParam;
this.personURI = personURI;
this.dataSource = dataSource;
this.log = log;
@ -143,7 +141,6 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
if (authorLabelNode != null) {
author.setIndividualLabel(authorLabelNode.toString());
}
}
authorDocuments.add(biboDocument);
@ -156,7 +153,7 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
QueryExecution queryExecution = null;
try {
Query query = QueryFactory.create(generateSparqlQuery(queryURI), SYNTAX);
Query query = QueryFactory.create(getSparqlQuery(queryURI), SYNTAX);
// QuerySolutionMap qs = new QuerySolutionMap();
// qs.add("authPerson", queryParam); // bind resource to s
@ -175,7 +172,7 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
return null;
}
private String generateSparqlQuery(String queryURI) {
private String getSparqlQuery(String queryURI) {
// Resource uri1 = ResourceFactory.createResource(queryURI);
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
@ -194,16 +191,16 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
return sparqlQuery;
}
public Set<BiboDocument> getVisualizationJavaValueObjects()
public Set<BiboDocument> getQueryResult()
throws MalformedQueryParametersException {
if (StringUtils.isNotBlank(this.queryParam)) {
if (StringUtils.isNotBlank(this.personURI)) {
/*
* To test for the validity of the URI submitted.
* */
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
IRI iri = iRIFactory.create(this.queryParam);
IRI iri = iRIFactory.create(this.personURI);
if (iri.hasViolation(false)) {
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
log.error("Pub Count vis Query " + errorMsg);
@ -215,7 +212,7 @@ public class PersonPublicationCountQueryHandler implements QueryHandler<Set<Bibo
throw new MalformedQueryParametersException("URL parameter is either null or empty.");
}
ResultSet resultSet = executeQuery(this.queryParam,
ResultSet resultSet = executeQuery(this.personURI,
this.dataSource);
return createJavaValueObjects(resultSet);

View file

@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.visualization.personpubcount;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
@ -16,6 +15,7 @@ import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.skife.csv.CSVWriter;
import org.skife.csv.SimpleWriter;
@ -32,12 +32,26 @@ import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFr
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.Individual;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
/**
*
* This request handler is used to serve the content related to an individual's
* publications over the years like,
* 1. Sprakline representing this
* 2. An entire page dedicated to the sparkline vis which will also have links to
* download the data using which the sparkline was rendered & its tabular representation etc.
* 3. Downloadable CSV file containing number of publications over the years.
* 4. Downloadable PDf file containing the publications content, among other things.
* Currently this is disabled because the feature is half-baked. We plan to activate this in
* the next major release.
*
* @author cdtank
*/
public class PersonPublicationCountRequestHandler implements VisualizationRequestHandler {
public void generateVisualization(VitroRequest vitroRequest,
@ -46,29 +60,27 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
Log log,
DataSource dataSource) {
String individualURIParam = vitroRequest.getParameter(
String peronURI = vitroRequest.getParameter(
VisualizationFrameworkConstants
.INDIVIDUAL_URI_URL_HANDLE);
.INDIVIDUAL_URI_KEY);
String renderMode = vitroRequest.getParameter(
VisualizationFrameworkConstants
.RENDER_MODE_URL_HANDLE);
.RENDER_MODE_KEY);
String visMode = vitroRequest.getParameter(
VisualizationFrameworkConstants
.VIS_MODE_URL_HANDLE);
.VIS_MODE_KEY);
String visContainer = vitroRequest.getParameter(
VisualizationFrameworkConstants
.VIS_CONTAINER_URL_HANDLE);
.VIS_CONTAINER_KEY);
QueryHandler<Set<BiboDocument>> queryManager =
new PersonPublicationCountQueryHandler(individualURIParam,
dataSource,
log);
QueryRunner<Set<BiboDocument>> queryManager =
new PersonPublicationCountQueryRunner(peronURI, dataSource, log);
try {
Set<BiboDocument> authorDocuments = queryManager.getVisualizationJavaValueObjects();
Set<BiboDocument> authorDocuments = queryManager.getQueryResult();
/*
* Create a map from the year to number of publications. Use the BiboDocument's
@ -77,17 +89,12 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
Map<String, Integer> yearToPublicationCount =
UtilityFunctions.getYearToPublicationCount(authorDocuments);
/*
* In order to avoid unneeded computations we have pushed this "if" condition up.
* This case arises when the render mode is data. In that case we dont want to generate
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
* It is ugly!
* */
Individual author = ((PersonPublicationCountQueryHandler) queryManager).getAuthor();
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE
Individual author = ((PersonPublicationCountQueryRunner) queryManager).getAuthor();
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
prepareVisualizationQueryDataResponse(author,
prepareDataResponse(author,
authorDocuments,
yearToPublicationCount,
response);
@ -95,32 +102,35 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
}
if (VisualizationFrameworkConstants.PDF_RENDER_MODE_URL_VALUE
/*
* For now we are disabling the capability to render pdf file.
* */
/*
if (VisualizationFrameworkConstants.PDF_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
prepareVisualizationQueryPDFResponse(author,
preparePDFResponse(author,
authorDocuments,
yearToPublicationCount,
response);
return;
}
*/
/*
* Computations required to generate HTML for the sparklines & related context.
* Computations required to generate HTML for the sparkline & related context.
* */
SparklineVOContainer valueObjectContainer = new SparklineVOContainer();
PersonPublicationCountVisCodeGenerator visualizationCodeGenerator =
new PersonPublicationCountVisCodeGenerator(vitroRequest.getContextPath(),
individualURIParam,
peronURI,
visMode,
visContainer,
authorDocuments,
yearToPublicationCount,
valueObjectContainer,
log);
SparklineData sparklineData = visualizationCodeGenerator
.getValueObjectContainer();
/*
* This is side-effecting because the response of this method is just to redirect to
@ -128,17 +138,21 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
* */
RequestDispatcher requestDispatcher = null;
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE_URL_VALUE
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE
.equalsIgnoreCase(renderMode)) {
prepareVisualizationQueryDynamicResponse(request, response, vitroRequest,
valueObjectContainer, yearToPublicationCount);
prepareDynamicResponse(request,
response,
vitroRequest,
sparklineData,
yearToPublicationCount);
requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
} else {
prepareVisualizationQueryStandaloneResponse(request, response, vitroRequest,
valueObjectContainer);
prepareStandaloneResponse(request,
response,
vitroRequest,
sparklineData);
requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
}
@ -152,7 +166,13 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(), vitroRequest, request, response, log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - Individual Publication Count",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -160,10 +180,133 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
}
return;
}
}
private void writePublicationsOverTimeCSV(Map<String, Integer> yearToPublicationCount,
PrintWriter responseWriter) {
CSVWriter csvWriter = new SimpleWriter(responseWriter);
try {
csvWriter.append(new String[]{"Year", "Publications"});
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
csvWriter.append(new Object[]{currentEntry.getKey(), currentEntry.getValue()});
}
} catch (IOException e) {
e.printStackTrace();
}
responseWriter.flush();
}
private void prepareVisualizationQueryPDFResponse(
/**
* Provides response when csv file containing the publication count over the years
* is requested.
* @param author
* @param authorDocuments
* @param yearToPublicationCount
* @param response
*/
private void prepareDataResponse(
Individual author,
Set<BiboDocument> authorDocuments,
Map<String, Integer> yearToPublicationCount,
HttpServletResponse response) {
String authorName = null;
/*
* To protect against cases where there are no author documents associated with the
* individual.
* */
if (authorDocuments.size() > 0) {
authorName = author.getIndividualLabel();
}
/*
* To make sure that null/empty records for author names do not cause any mischief.
* */
if (StringUtils.isBlank(authorName)) {
authorName = "no-author";
}
String outputFileName = UtilityFunctions.slugify(authorName)
+ "_publications-per-year" + ".csv";
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
writePublicationsOverTimeCSV(yearToPublicationCount, responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Provides response when an entire page dedicated to publication sparkline is requested.
* @param request
* @param response
* @param vreq
* @param valueObjectContainer
*/
private void prepareStandaloneResponse(HttpServletRequest request,
HttpServletResponse response, VitroRequest vreq,
SparklineData valueObjectContainer) {
Portal portal = vreq.getPortal();
request.setAttribute("sparklineVO", valueObjectContainer);
request.setAttribute("bodyJsp", "/templates/visualization/publication_count.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Individual Publication Count visualization");
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
}
/**
* Provides response when the publication sparkline has to be rendered in already existing
* page, e.g. profile page.
* @param request
* @param response
* @param vreq
* @param valueObjectContainer
* @param yearToPublicationCount
*/
private void prepareDynamicResponse(
HttpServletRequest request,
HttpServletResponse response,
VitroRequest vreq,
SparklineData valueObjectContainer,
Map<String, Integer> yearToPublicationCount) {
Portal portal = vreq.getPortal();
request.setAttribute("sparklineVO", valueObjectContainer);
if (yearToPublicationCount.size() > 0) {
request.setAttribute("shouldVIVOrenderVis", true);
} else {
request.setAttribute("shouldVIVOrenderVis", false);
}
request.setAttribute("portalBean", portal);
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
}
private void preparePDFResponse(
Individual author,
Set<BiboDocument> authorDocuments,
Map<String, Integer> yearToPublicationCount,
@ -182,8 +325,8 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
/*
* To make sure that null/empty records for author names do not cause any mischief.
* */
if (authorName == null) {
authorName = "no";
if (StringUtils.isBlank(authorName)) {
authorName = "no-author";
}
String outputFileName = UtilityFunctions.slugify(authorName) + "_report" + ".pdf";
@ -224,133 +367,4 @@ public class PersonPublicationCountRequestHandler implements VisualizationReques
e.printStackTrace();
}
}
private void prepareVisualizationQueryDataResponse(
Individual author,
Set<BiboDocument> authorDocuments,
Map<String, Integer> yearToPublicationCount,
HttpServletResponse response) {
String authorName = null;
/*
* To protect against cases where there are no author documents associated with the
* individual.
* */
if (authorDocuments.size() > 0) {
authorName = author.getIndividualLabel();
}
/*
* To make sure that null/empty records for author names do not cause any mischief.
* */
if (authorName == null) {
authorName = "no-author";
}
String outputFileName = UtilityFunctions.slugify(authorName)
+ "_publications-per-year" + ".csv";
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
try {
PrintWriter responseWriter = response.getWriter();
/*
* We are side-effecting responseWriter since we are directly manipulating the response
* object of the servlet.
* */
generateCsvFileBuffer(yearToPublicationCount,
responseWriter);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void generateCsvFileBuffer(Map<String, Integer> yearToPublicationCount,
PrintWriter responseWriter) {
CSVWriter csvWriter = new SimpleWriter(responseWriter);
try {
csvWriter.append(new String[]{"Year", "Publications"});
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
csvWriter.append(new Object[]{currentEntry.getKey(), currentEntry.getValue()});
}
} catch (IOException e) {
e.printStackTrace();
}
responseWriter.flush();
}
private void prepareVisualizationQueryStandaloneResponse(HttpServletRequest request,
HttpServletResponse response, VitroRequest vreq,
SparklineVOContainer valueObjectContainer) {
Portal portal = vreq.getPortal();
request.setAttribute("sparklineVO", valueObjectContainer);
request.setAttribute("bodyJsp", "/templates/visualization/publication_count.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Individual Publication Count visualization");
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
}
private void prepareVisualizationQueryDynamicResponse(
HttpServletRequest request,
HttpServletResponse response,
VitroRequest vreq,
SparklineVOContainer valueObjectContainer,
Map<String, Integer> yearToPublicationCount) {
Portal portal = vreq.getPortal();
request.setAttribute("sparklineVO", valueObjectContainer);
if (yearToPublicationCount.size() > 0) {
request.setAttribute("shouldVIVOrenderVis", true);
} else {
request.setAttribute("shouldVIVOrenderVis", false);
}
request.setAttribute("portalBean", portal);
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
}
private void handleMalformedParameters(String errorMessage,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -18,14 +18,23 @@ 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.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineData;
@SuppressWarnings("serial")
public class PersonPublicationCountVisCodeGenerator {
private static final int MINIMUM_YEARS_CONSIDERED = 10;
/*
* 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 publications 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 yeras.
* */
private static final Map<String, String> VIS_DIV_NAMES = new HashMap<String, String>() { {
put("SHORT_SPARK", "pub_count_short_sparkline_vis");
@ -37,19 +46,15 @@ public class PersonPublicationCountVisCodeGenerator {
private static final String DEFAULT_VIS_CONTAINER_DIV_ID = "pub_count_vis_container";
public static final String SHORT_SPARKLINE_MODE_URL_HANDLE = "short";
public static final String FULL_SPARKLINE_MODE_URL_HANDLE = "full";
private Map<String, Integer> yearToPublicationCount;
private Log log;
private SparklineVOContainer valueObjectContainer;
private SparklineData sparklineData;
private String contextPath;
private String individualURIParam;
private String individualURI;
public PersonPublicationCountVisCodeGenerator(String contextPath,
String individualURIParam,
@ -57,35 +62,41 @@ public class PersonPublicationCountVisCodeGenerator {
String visContainer,
Set<BiboDocument> authorDocuments,
Map<String, Integer> yearToPublicationCount,
SparklineVOContainer valueObjectContainer,
Log log) {
this.contextPath = contextPath;
this.individualURIParam = individualURIParam;
this.individualURI = individualURIParam;
this.yearToPublicationCount = yearToPublicationCount;
this.valueObjectContainer = valueObjectContainer;
this.sparklineData = new SparklineData();
this.log = log;
generateVisualizationCode(visMode,
visContainer,
authorDocuments);
generateVisualizationCode(visMode, visContainer, authorDocuments);
}
/**
* 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
* @param authorDocuments
*/
private void generateVisualizationCode(String visMode,
String visContainer,
Set<BiboDocument> authorDocuments) {
valueObjectContainer.setSparklineContent(getMainVisualizationCode(authorDocuments,
visMode,
visContainer));
sparklineData.setSparklineContent(getMainVisualizationCode(authorDocuments,
visMode,
visContainer));
valueObjectContainer.setSparklineContext(getVisualizationContextCode(visMode));
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
}
@ -95,13 +106,15 @@ public class PersonPublicationCountVisCodeGenerator {
int numOfYearsToBeRendered = 0;
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
int shortSparkMinYear = currentYear - MINIMUM_YEARS_CONSIDERED + 1;
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_PUBLICATION_YEAR".
* */
Set<String> publishedYears = new HashSet(yearToPublicationCount.keySet());
Set<String> publishedYears = new HashSet<String>(yearToPublicationCount.keySet());
publishedYears.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
/*
@ -175,7 +188,13 @@ public class PersonPublicationCountVisCodeGenerator {
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
int publicationCounter = 0;
int totalPublications = 0;
/*
* 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.
* */
int renderedFullSparks = 0;
@ -202,23 +221,20 @@ public class PersonPublicationCountVisCodeGenerator {
+ currentPublications
+ ");\n");
totalPublications += currentPublications;
/*
* Sparks that will be rendered in full mode will always be the one's which has
* any year associated with it. Hence.
* */
renderedFullSparks += currentPublications;
publicationCounter++;
}
/*
* Sparks that will be rendered in full mode will always be the one's which has any year
* associated with it. Hence.
* */
renderedFullSparks = totalPublications;
/*
* Total publications will also consider publications that have no year associated with
* it. Hence.
* */
Integer unknownYearPublications = 0;
if (yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR) != null) {
totalPublications += yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
unknownYearPublications = yearToPublicationCount
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
}
@ -238,8 +254,8 @@ public class PersonPublicationCountVisCodeGenerator {
* "short" sparkline mode we will set the Earliest RenderedPublication year to
* "currentYear - 10".
* */
valueObjectContainer.setEarliestRenderedPublicationYear(minPublishedYear);
valueObjectContainer.setLatestRenderedPublicationYear(currentYear);
sparklineData.setEarliestRenderedPublicationYear(minPublishedYear);
sparklineData.setLatestRenderedPublicationYear(currentYear);
/*
* The Full Sparkline will be rendered by default. Only if the url has specific mention of
@ -252,9 +268,9 @@ public class PersonPublicationCountVisCodeGenerator {
* essentially a side-effecting process, we have both the activators method as side-
* effecting. They both side-effect "visualizationCode"
* */
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
valueObjectContainer.setEarliestRenderedPublicationYear(shortSparkMinYear);
sparklineData.setEarliestRenderedPublicationYear(shortSparkMinYear);
generateShortSparklineVisualizationContent(currentYear,
shortSparkMinYear,
visContainerID,
@ -370,9 +386,7 @@ public class PersonPublicationCountVisCodeGenerator {
+ "\" class=\"inline_href\">(.CSV File)</a>";
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
@ -464,7 +478,7 @@ public class PersonPublicationCountVisCodeGenerator {
private String getVisualizationContextCode(String visMode) {
String visualizationContextCode = "";
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
visualizationContextCode = generateShortVisContext();
} else {
visualizationContextCode = generateFullVisContext();
@ -488,19 +502,15 @@ public class PersonPublicationCountVisCodeGenerator {
csvDownloadURLHref = "Download data as <a href='"
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
valueObjectContainer.setDownloadDataLink(getCSVDownloadURL());
sparklineData.setDownloadDataLink(getCSVDownloadURL());
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
} else {
csvDownloadURLHref = "No data available to export.<br />";
}
@ -509,10 +519,9 @@ public class PersonPublicationCountVisCodeGenerator {
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
valueObjectContainer.setTable(tableCode);
sparklineData.setTable(tableCode);
return divContextCode.toString();
}
private String getCSVDownloadURL()
@ -525,22 +534,21 @@ public class PersonPublicationCountVisCodeGenerator {
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
}
String downloadURL = contextPath
+ secondaryContextPath
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME)
.toString()
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode(
VisualizationController
.PERSON_PUBLICATION_COUNT_VIS_URL_VALUE,
VisualizationFrameworkConstants
.PERSON_PUBLICATION_COUNT_VIS,
VisualizationController.URL_ENCODING_SCHEME)
.toString()
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.DATA_RENDER_MODE_URL_VALUE,
.DATA_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME)
.toString();
return downloadURL;
@ -566,28 +574,26 @@ public class PersonPublicationCountVisCodeGenerator {
String fullTimelineNetworkURL = contextPath
+ secondaryContextPath
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("person_level",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE_URL_VALUE,
.STANDALONE_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
+ "publications and corresponding co-author network</a>.<br />";
valueObjectContainer.setFullTimelineNetworkLink(fullTimelineNetworkURL);
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
} else {
fullTimelineLink = "No data available to render full timeline.<br />";
}
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
@ -595,9 +601,7 @@ public class PersonPublicationCountVisCodeGenerator {
} catch (UnsupportedEncodingException e) {
log.error(e);
}
return divContextCode.toString();
}
private String generateDataTable() {
@ -606,15 +610,10 @@ public class PersonPublicationCountVisCodeGenerator {
try {
if (getCSVDownloadURL() != null) {
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
} else {
csvDownloadURLHref = "";
}
} catch (UnsupportedEncodingException e) {
csvDownloadURLHref = "";
}
@ -643,7 +642,7 @@ public class PersonPublicationCountVisCodeGenerator {
return dataTable.toString();
}
public SparklineData getValueObjectContainer() {
return sparklineData;
}
}

View file

@ -9,7 +9,6 @@ import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -22,8 +21,6 @@ import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.RDFNode;
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.controller.visualization.VisualizationController;
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
@ -31,11 +28,22 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.FileServingHelper;
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.valueobjects.GenericQueryMap;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.AllPropertiesQueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.GenericQueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryHandler;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.AllPropertiesQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.GenericQueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
/**
* This request handler is used when you need helpful information to add more context
* to the visualization. It does not have any code for generating the visualization,
* just fires sparql queries to get info for specific cases like,
* 1. thumbnail/image location for a particular individual
* 2. profile information for a particular individual like label, moniker etc
* 3. person level vis url for a particular individual
* etc.
* @author cdtank
*/
public class UtilitiesRequestHandler implements VisualizationRequestHandler {
public void generateVisualization(VitroRequest vitroRequest,
@ -44,12 +52,11 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
Log log,
DataSource dataSource) {
String individualURIParam = vitroRequest.getParameter(
VisualizationFrameworkConstants
.INDIVIDUAL_URI_URL_HANDLE);
String individualURI = vitroRequest.getParameter(
VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants
.VIS_MODE_URL_HANDLE);
String visMode = vitroRequest.getParameter(
VisualizationFrameworkConstants.VIS_MODE_KEY);
String preparedURL = "";
@ -67,8 +74,8 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
+ "|| ?predicate = vitro:moniker "
+ "|| ?predicate = rdfs:label";
QueryHandler<GenericQueryMap> profileQueryHandler =
new AllPropertiesQueryHandler(individualURIParam,
QueryRunner<GenericQueryMap> profileQueryHandler =
new AllPropertiesQueryRunner(individualURI,
filterRule,
dataSource,
log);
@ -76,14 +83,14 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
try {
GenericQueryMap profilePropertiesToValues =
profileQueryHandler.getVisualizationJavaValueObjects();
profileQueryHandler.getQueryResult();
profilePropertiesToValues.addEntry("imageContextPath",
request.getContextPath());
Gson profileInformation = new Gson();
prepareVisualizationQueryResponse(
prepareUtilitiesResponse(
profileInformation.toJson(profilePropertiesToValues),
response);
@ -92,11 +99,13 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(),
vitroRequest,
request,
response,
log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - Utilities Profile Info",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -104,8 +113,6 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
}
return;
}
} else if (VisualizationFrameworkConstants.IMAGE_UTILS_VIS_MODE
.equalsIgnoreCase(visMode)) {
/*
@ -118,15 +125,15 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
QueryFieldLabels.THUMBNAIL_LOCATION_URL);
fieldLabelToOutputFieldLabel.put("fileName", QueryFieldLabels.THUMBNAIL_FILENAME);
String whereClause = "<" + individualURIParam
String whereClause = "<" + individualURI
+ "> j.2:thumbnailImage ?thumbnailImage . "
+ "?thumbnailImage j.2:downloadLocation "
+ "?downloadLocation ; j.2:filename ?fileName .";
QueryHandler<ResultSet> imageQueryHandler =
new GenericQueryHandler(individualURIParam,
QueryRunner<ResultSet> imageQueryHandler =
new GenericQueryRunner(individualURI,
fieldLabelToOutputFieldLabel,
whereClause,
dataSource,
@ -136,20 +143,22 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
String thumbnailAccessURL =
getThumbnailInformation(
imageQueryHandler.getVisualizationJavaValueObjects(),
imageQueryHandler.getQueryResult(),
fieldLabelToOutputFieldLabel);
prepareVisualizationQueryResponse(thumbnailAccessURL, response);
prepareUtilitiesResponse(thumbnailAccessURL, response);
return;
} catch (MalformedQueryParametersException e) {
try {
handleMalformedParameters(e.getMessage(),
vitroRequest,
request,
response,
log);
UtilityFunctions.handleMalformedParameters(
e.getMessage(),
"Visualization Query Error - Utilities Image Info",
vitroRequest,
request,
response,
log);
} catch (ServletException e1) {
log.error(e1.getStackTrace());
} catch (IOException e1) {
@ -157,76 +166,69 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
}
return;
}
} else if (VisualizationFrameworkConstants.COAUTHOR_UTILS_VIS_MODE
.equalsIgnoreCase(visMode)) {
/*
* By default we will be generating profile url else some specific url like
* coAuthorShip vis url for that individual.
* */
preparedURL += request.getContextPath()
+ VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("coauthorship",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE_URL_VALUE,
.STANDALONE_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME)
.toString();
prepareVisualizationQueryResponse(preparedURL, response);
prepareUtilitiesResponse(preparedURL, response);
return;
} else if (VisualizationFrameworkConstants.PERSON_LEVEL_UTILS_VIS_MODE
.equalsIgnoreCase(visMode)) {
/*
* By default we will be generating profile url else some specific url like
* coAuthorShip vis url for that individual.
* */
preparedURL += request.getContextPath()
+ VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
+ "=" + URLEncoder.encode("person_level",
VisualizationController.URL_ENCODING_SCHEME).toString()
+ "&"
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
.STANDALONE_RENDER_MODE_URL_VALUE,
.STANDALONE_RENDER_MODE,
VisualizationController.URL_ENCODING_SCHEME).toString();
prepareVisualizationQueryResponse(preparedURL, response);
prepareUtilitiesResponse(preparedURL, response);
return;
} else {
preparedURL += request.getContextPath()
+ "/individual"
+ VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX
+ "?"
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
+ "=" + URLEncoder.encode(individualURIParam,
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
+ "=" + URLEncoder.encode(individualURI,
VisualizationController.URL_ENCODING_SCHEME).toString();
prepareVisualizationQueryResponse(preparedURL, response);
prepareUtilitiesResponse(preparedURL, response);
return;
}
} catch (UnsupportedEncodingException e) {
log.error(e.getLocalizedMessage());
}
@ -253,53 +255,22 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler {
.getBytestreamAliasUrl(downloadLocationNode.toString(),
fileNameNode.toString());
}
}
return finalThumbNailLocation;
}
private void prepareVisualizationQueryResponse(String preparedURL,
private void prepareUtilitiesResponse(String preparedURL,
HttpServletResponse response) {
response.setContentType("text/plain");
try {
PrintWriter responseWriter = response.getWriter();
responseWriter.append(preparedURL);
responseWriter.close();
PrintWriter responseWriter = response.getWriter();
responseWriter.append(preparedURL);
responseWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleMalformedParameters(String errorMessage,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -2,7 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -14,10 +13,6 @@ import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
*/
public class BiboDocument extends Individual {
private static final int NUM_CHARS_IN_YEAR_FORMAT = 4;
public static final int MINIMUM_PUBLICATION_YEAR = 1800;
private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
private String documentMoniker;
private String documentBlurb;
private String documentDescription;
@ -31,7 +26,7 @@ public class BiboDocument extends Individual {
}
public String getDocumentURL() {
return this.getIndividualURL();
return this.getIndividualURI();
}
public String getDocumentMoniker() {
@ -68,7 +63,6 @@ public class BiboDocument extends Individual {
* This pattern will match all group of numbers which have only 4 digits
* delimited by the word boundary.
* */
// String pattern = "\\b\\d{4}\\b";
String pattern = "(?<!-)\\b\\d{4}\\b(?=[^-])";
Pattern yearPattern = Pattern.compile(pattern);
@ -86,8 +80,8 @@ public class BiboDocument extends Individual {
* Published year has to be equal or less than the current year
* and more than a minimum default year.
* */
if (candidateYearInteger <= CURRENT_YEAR
&& candidateYearInteger >= MINIMUM_PUBLICATION_YEAR) {
if (candidateYearInteger <= VOConstants.CURRENT_YEAR
&& candidateYearInteger >= VOConstants.MINIMUM_PUBLICATION_YEAR) {
publishedYear = candidateYearInteger.toString();
}
@ -117,20 +111,22 @@ public class BiboDocument extends Individual {
* core:yearMonth points to internally.
* */
if (publicationYearMonth != null
&& publicationYearMonth.length() >= NUM_CHARS_IN_YEAR_FORMAT
&& publicationYearMonth.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
&& isValidPublicationYear(publicationYearMonth.substring(
0,
NUM_CHARS_IN_YEAR_FORMAT))) {
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
return publicationYearMonth.substring(0, NUM_CHARS_IN_YEAR_FORMAT);
return publicationYearMonth.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
}
if (publicationDate != null
&& publicationDate.length() >= NUM_CHARS_IN_YEAR_FORMAT
&& isValidPublicationYear(publicationDate.substring(0, NUM_CHARS_IN_YEAR_FORMAT))) {
&& publicationDate.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
&& isValidPublicationYear(publicationDate
.substring(0,
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
return publicationDate.substring(0, NUM_CHARS_IN_YEAR_FORMAT);
return publicationDate.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
}
/*
@ -175,9 +171,9 @@ public class BiboDocument extends Individual {
private boolean isValidPublicationYear(String testPublicationYear) {
if (testPublicationYear.length() != 0
&& testPublicationYear.trim().length() == NUM_CHARS_IN_YEAR_FORMAT
&& testPublicationYear.trim().length() == VOConstants.NUM_CHARS_IN_YEAR_FORMAT
&& testPublicationYear.matches("\\d+")
&& Integer.parseInt(testPublicationYear) >= MINIMUM_PUBLICATION_YEAR) {
&& Integer.parseInt(testPublicationYear) >= VOConstants.MINIMUM_PUBLICATION_YEAR) {
return true;
}

View file

@ -7,8 +7,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class CoAuthorshipVOContainer {
public class CoAuthorshipData {
private Set<Node> nodes;
private Set<Edge> edges;
@ -16,7 +15,7 @@ public class CoAuthorshipVOContainer {
private Set<Map<String, String>> NODE_SCHEMA;
private Set<Map<String, String>> EDGE_SCHEMA;
public CoAuthorshipVOContainer(Node egoNode, Set<Node> nodes, Set<Edge> edges) {
public CoAuthorshipData(Node egoNode, Set<Node> nodes, Set<Edge> edges) {
this.egoNode = egoNode;
this.nodes = nodes;
this.edges = edges;

View file

@ -14,7 +14,8 @@ import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
/**
*
* This is the Value Object for storing edge information mainly for co-author vis.
* This is stores edge information mainly for co-author vis.
*
* @author cdtank
*
*/
@ -129,7 +130,6 @@ public class Edge {
}
}
@SuppressWarnings("serial")
public Integer getUnknownCollaborationYearCount() {
if (yearToPublicationCount == null) {
yearToPublicationCount = UtilityFunctions

View file

@ -10,8 +10,8 @@ import java.util.Set;
* Right now this is just acting as a hashmap but in future we would want to provide
* more detailed info other than just what properties had what values. E.g. we
* could parse properties (& its values) to look for what namespaces are used.
* @author cdtank
*
* @author cdtank
*/
@SuppressWarnings("serial")
public class GenericQueryMap extends HashMap<String, Set<String>> {

View file

@ -5,15 +5,15 @@ package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
public class Individual {
private String individualLabel;
private String individualURL;
private String individualURI;
public Individual(String individualURL, String individualLabel) {
this.individualURL = individualURL;
public Individual(String individualURI, String individualLabel) {
this.individualURI = individualURI;
this.individualLabel = individualLabel;
}
public Individual(String individualURL) {
this(individualURL, "");
public Individual(String individualURI) {
this(individualURI, "");
}
public String getIndividualLabel() {
@ -24,8 +24,8 @@ public class Individual {
this.individualLabel = individualLabel;
}
public String getIndividualURL() {
return individualURL;
public String getIndividualURI() {
return individualURI;
}

View file

@ -14,9 +14,9 @@ import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
/**
*
* This is the Value Object for storing node information mainly for co-author vis.
* @author cdtank
* This stores node information mainly for co-author vis.
*
* @author cdtank
*/
public class Node extends Individual {
@ -25,9 +25,9 @@ public class Node extends Individual {
private Set<BiboDocument> authorDocuments = new HashSet<BiboDocument>();
public Node(String nodeURL,
public Node(String nodeURI,
UniqueIDGenerator uniqueIDGenerator) {
super(nodeURL);
super(nodeURI);
nodeID = uniqueIDGenerator.getNextNumericID();
}
@ -35,8 +35,8 @@ public class Node extends Individual {
return nodeID;
}
public String getNodeURL() {
return this.getIndividualURL();
public String getNodeURI() {
return this.getIndividualURI();
}
public String getNodeName() {
@ -59,13 +59,13 @@ public class Node extends Individual {
this.authorDocuments.add(authorDocument);
}
public Map<String, Integer> getYearToPublicationCount() {
if (yearToPublicationCount == null) {
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
}
return yearToPublicationCount;
}
/*
* getEarliest, Latest & Unknown Publication YearCount should only be used after
* the parsing of the entire sparql is done. Else it will give results based on
@ -153,6 +153,4 @@ public class Node extends Individual {
return null;
}
}
}

View file

@ -2,7 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
public class SparklineVOContainer {
public class SparklineData {
/*
* For now sparklineNumPublicationsText & sparklinePublicationRangeText is left
@ -26,45 +26,58 @@ public class SparklineVOContainer {
public String getSparklineNumPublicationsText() {
return sparklineNumPublicationsText;
}
public void setSparklineNumPublicationsText(String sparklineNumPublicationsText) {
this.sparklineNumPublicationsText = sparklineNumPublicationsText;
}
public String getSparklinePublicationRangeText() {
return sparklinePublicationRangeText;
}
public void setSparklinePublicationRangeText(
String sparklinePublicationRangeText) {
this.sparklinePublicationRangeText = sparklinePublicationRangeText;
}
public Integer getEarliestRenderedPublicationYear() {
return earliestRenderedPublicationYear;
}
public void setEarliestRenderedPublicationYear(
Integer earliestRenderedPublicationYear) {
this.earliestRenderedPublicationYear = earliestRenderedPublicationYear;
}
public Integer getLatestRenderedPublicationYear() {
return latestRenderedPublicationYear;
}
public void setLatestRenderedPublicationYear(
Integer latestRenderedPublicationYear) {
this.latestRenderedPublicationYear = latestRenderedPublicationYear;
}
public String getTable() {
return table;
}
public void setTable(String table) {
this.table = table;
}
public String getDownloadDataLink() {
return downloadDataLink;
}
public void setDownloadDataLink(String downloadDataLink) {
this.downloadDataLink = downloadDataLink;
}
public String getFullTimelineNetworkLink() {
return fullTimelineNetworkLink;
}
public void setFullTimelineNetworkLink(String fullTimelineNetworkLink) {
this.fullTimelineNetworkLink = fullTimelineNetworkLink;
}
@ -72,6 +85,7 @@ public class SparklineVOContainer {
public String getSparklineContent() {
return sparklineContent;
}
public void setSparklineContent(String shortSparklineContent) {
this.sparklineContent = shortSparklineContent;
}
@ -79,8 +93,8 @@ public class SparklineVOContainer {
public String getSparklineContext() {
return sparklineContext;
}
public void setSparklineContext(String shortSparklineContext) {
this.sparklineContext = shortSparklineContext;
}
}

View file

@ -7,16 +7,16 @@ import java.util.Set;
/**
*
* This is the Value Object equivalent for vivo:CollegeOrSchoolWithinUniversity object type.
* @author cdtank
* This is equivalent for vivo:CollegeOrSchoolWithinUniversity object type.
*
* @author cdtank
*/
public class VivoCollegeOrSchool extends Individual {
private Set<VivoDepartmentOrDivision> departments = new HashSet<VivoDepartmentOrDivision>();
public VivoCollegeOrSchool(String collegeURL) {
super(collegeURL);
public VivoCollegeOrSchool(String collegeURI) {
super(collegeURI);
}
public Set<VivoDepartmentOrDivision> getDepartments() {
@ -27,8 +27,8 @@ public class VivoCollegeOrSchool extends Individual {
this.departments.add(department);
}
public String getCollegeURL() {
return this.getIndividualURL();
public String getCollegeURI() {
return this.getIndividualURI();
}
public String getCollegeLabel() {

View file

@ -7,16 +7,16 @@ import java.util.Set;
/**
*
* This is the Value Object equivalent for vivo:AcademicDepartmentOrDivision object type.
* @author cdtank
* This is equivalent for vivo:AcademicDepartmentOrDivision object type.
*
* @author cdtank
*/
public class VivoDepartmentOrDivision extends Individual {
private Set<VivoCollegeOrSchool> parentColleges = new HashSet<VivoCollegeOrSchool>();
public VivoDepartmentOrDivision(String departmentURL, VivoCollegeOrSchool parentCollege) {
super(departmentURL);
public VivoDepartmentOrDivision(String departmentURI, VivoCollegeOrSchool parentCollege) {
super(departmentURI);
addParentCollege(parentCollege);
}
@ -28,8 +28,8 @@ public class VivoDepartmentOrDivision extends Individual {
this.parentColleges.add(parentCollege);
}
public String getDepartmentURL() {
return this.getIndividualURL();
public String getDepartmentURI() {
return this.getIndividualURI();
}
public String getDepartmentLabel() {

View file

@ -9,9 +9,9 @@ import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants.Empl
/**
*
* This is the Value Object equivalent for vivo's Employee object type.
* @author cdtank
* This is the equivalent for vivo's Employee object type.
*
* @author cdtank
*/
public class VivoEmployee extends Individual {
@ -27,8 +27,8 @@ public class VivoEmployee extends Individual {
addParentDepartment(parentDepartment);
}
public String getEmployeeURL() {
return this.getIndividualURL();
public String getEmployeeURI() {
return this.getIndividualURI();
}
public String getEmployeeName() {

View file

@ -26,25 +26,26 @@ import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.GenericQueryM
/**
* Very dumb name of the class. change it.
* @author cdtank
* This query runner is used to execute a sparql query that will fetch all the
* properties available for the provided individual URI.
*
* @author cdtank
*/
public class AllPropertiesQueryHandler implements QueryHandler<GenericQueryMap> {
public class AllPropertiesQueryRunner implements QueryRunner<GenericQueryMap> {
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
private String filterRule, individualURLParam;
private String filterRule, individualURI;
private DataSource dataSource;
private Log log;
public AllPropertiesQueryHandler(String individualURLParam,
public AllPropertiesQueryRunner(String individualURI,
String filterRule,
DataSource dataSource,
Log log) {
this.individualURLParam = individualURLParam;
this.individualURI = individualURI;
this.filterRule = filterRule;
this.dataSource = dataSource;
this.log = log;
@ -53,7 +54,7 @@ public class AllPropertiesQueryHandler implements QueryHandler<GenericQueryMap>
private GenericQueryMap createJavaValueObjects(ResultSet resultSet) {
GenericQueryMap queryResultVO = new GenericQueryMap();
GenericQueryMap queryResult = new GenericQueryMap();
while (resultSet.hasNext()) {
QuerySolution solution = resultSet.nextSolution();
@ -63,16 +64,15 @@ public class AllPropertiesQueryHandler implements QueryHandler<GenericQueryMap>
RDFNode objectNode = solution.get(QueryFieldLabels.OBJECT);
if (predicateNode != null && objectNode != null) {
queryResultVO.addEntry(predicateNode.toString(),
queryResult.addEntry(predicateNode.toString(),
objectNode.toString());
}
}
return queryResultVO;
return queryResult;
}
private ResultSet executeQuery(String queryText,
DataSource dataSource) {
@ -119,15 +119,14 @@ public class AllPropertiesQueryHandler implements QueryHandler<GenericQueryMap>
return sparqlQuery;
}
public GenericQueryMap getVisualizationJavaValueObjects()
public GenericQueryMap getQueryResult()
throws MalformedQueryParametersException {
if (StringUtils.isNotBlank(this.individualURLParam)) {
if (StringUtils.isNotBlank(this.individualURI)) {
/*
* To test for the validity of the URI submitted.
* */
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
IRI iri = iRIFactory.create(this.individualURLParam);
IRI iri = iRIFactory.create(this.individualURI);
if (iri.hasViolation(false)) {
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
log.error("Generic Query " + errorMsg);
@ -140,12 +139,10 @@ public class AllPropertiesQueryHandler implements QueryHandler<GenericQueryMap>
}
ResultSet resultSet = executeQuery(generateGenericSparqlQuery(
this.individualURLParam,
this.individualURI,
this.filterRule),
this.dataSource);
return createJavaValueObjects(resultSet);
}
}

View file

@ -24,10 +24,12 @@ import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryP
/**
* @author cdtank
* This query runner is used to run a generic sparql query based on the "select",
* "where" & "filter" rules provided to it.
*
* @author cdtank
*/
public class GenericQueryHandler implements QueryHandler<ResultSet> {
public class GenericQueryRunner implements QueryRunner<ResultSet> {
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
@ -38,7 +40,7 @@ public class GenericQueryHandler implements QueryHandler<ResultSet> {
private Map<String, String> fieldLabelToOutputFieldLabel;
public GenericQueryHandler(String individualURLParam,
public GenericQueryRunner(String individualURLParam,
Map<String, String> fieldLabelToOutputFieldLabel,
String whereClause,
DataSource dataSource,
@ -103,8 +105,7 @@ public class GenericQueryHandler implements QueryHandler<ResultSet> {
return sparqlQuery.toString();
}
public ResultSet getVisualizationJavaValueObjects()
public ResultSet getQueryResult()
throws MalformedQueryParametersException {
if (StringUtils.isNotBlank(this.individualURLParam)) {
/*
@ -127,6 +128,4 @@ public class GenericQueryHandler implements QueryHandler<ResultSet> {
return resultSet;
}
}

View file

@ -4,8 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
public interface QueryHandler<QueryResponse> {
public interface QueryRunner<QueryResult> {
QueryResponse getVisualizationJavaValueObjects() throws MalformedQueryParametersException;
QueryResult getQueryResult() throws MalformedQueryParametersException;
}

View file

@ -2,14 +2,27 @@
package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import 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.VisConstants;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
public class UtilityFunctions {
@ -31,8 +44,8 @@ public class UtilityFunctions {
* I am pushing the logic to check for validity of year in "getPublicationYear" itself
* because,
* 1. We will be using getPub... multiple times & this will save us duplication of code
* 2. If we change the logic of validity of a pub year we would not have to make changes
* all throughout the codebase.
* 2. If we change the logic of validity of a pub year we would not have to make
* changes all throughout the codebase.
* 3. We are asking for a publication year & we should get a proper one or NOT at all.
* */
String publicationYear;
@ -56,6 +69,49 @@ public class UtilityFunctions {
return yearToPublicationCount;
}
/**
* This method is used to return a mapping between publication year & all the co-authors
* that published with ego in that year.
* @param authorNodesAndEdges
* @return
*/
public static Map<String, Set<Node>> getPublicationYearToCoAuthors(
CoAuthorshipData authorNodesAndEdges) {
Map<String, Set<Node>> yearToCoAuthors = new TreeMap<String, Set<Node>>();
Node egoNode = authorNodesAndEdges.getEgoNode();
for (Node currNode : authorNodesAndEdges.getNodes()) {
/*
* We have already printed the Ego Node info.
* */
if (currNode != egoNode) {
for (String year : currNode.getYearToPublicationCount().keySet()) {
Set<Node> coAuthorNodes;
if (yearToCoAuthors.containsKey(year)) {
coAuthorNodes = yearToCoAuthors.get(year);
coAuthorNodes.add(currNode);
} else {
coAuthorNodes = new HashSet<Node>();
coAuthorNodes.add(currNode);
yearToCoAuthors.put(year, coAuthorNodes);
}
}
}
}
return yearToCoAuthors;
}
/**
* Currently the approach for slugifying filenames is naive. In future if there is need,
* we can write more sophisticated method.
@ -71,4 +127,31 @@ public class UtilityFunctions {
textBlockSeparator);
}
public static void handleMalformedParameters(String errorMessage,
String errorPageTitle,
VitroRequest vitroRequest,
HttpServletRequest request,
HttpServletResponse response,
Log log)
throws ServletException, IOException {
Portal portal = vitroRequest.getPortal();
request.setAttribute("error", errorMessage);
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
request.setAttribute("portalBean", portal);
request.setAttribute("title", errorPageTitle);
try {
requestDispatcher.forward(request, response);
} catch (Exception e) {
log.error("EntityEditController could not forward to view.");
log.error(e.getMessage());
log.error(e.getStackTrace());
}
}
}

View file

@ -10,6 +10,16 @@ import com.hp.hpl.jena.query.DataSource;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* This interface is being implemented by all the visualization request handlers like
* PersonLevelRequestHandler, PersonPublicationCountRequestHandler, UtilitiesRequestHandler
* etc. All the future visualizations <b>must</b> implement this because the ability of
* a visualization to be served to the users is dependent on it. We have implemented
* dependency injection mechanism & one of the conditions that is used to enable a visualization
* handler is its implementation of VisualizationRequestHandler.
*
* @author cdtank
*/
public interface VisualizationRequestHandler {
void generateVisualization(VitroRequest vitroRequest,