1. Created folder structure for the theme components (css, images, js) so that visualizations can become theme agnostic.
2. Modified FreeMarkerized (FM) sparklines on the profile page to actually make calls to freemarker version of person publication count sparkline. (TODO: currently the code to replace "/visualization" with "/visualizationfm" is hard coded. Thsi will be resolved once change is made in IndividualController to call FM personPubCount controller.) 3. Added new templates for FM version of visualizations. 4. Added a new bean which recognized FM versions of visualizations. 5. Created FM branch of the visualization architecture & Person publication count visualization. 6. For Person pub count abstracted out the html/javascript code creator to be on the front end itself. (TODO: refactor SparklineData VO to remove attributes that save the html/js code.)
This commit is contained in:
parent
72e24bb661
commit
7e9bcdaab2
38 changed files with 4302 additions and 1 deletions
|
@ -0,0 +1,59 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
|
||||
<bean id="person_pub_count"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.personpubcount.PersonPublicationCountRequestHandler" />
|
||||
|
||||
<!--
|
||||
<bean id="coauthorship"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.CoAuthorshipRequestHandler" />
|
||||
<bean id="person_level"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.personlevel.PersonLevelRequestHandler" />
|
||||
<bean id="utilities"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.utilities.UtilitiesRequestHandler" />
|
||||
<bean id="entity_comparison"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison.EntityPublicationCountRequestHandler" />
|
||||
<bean id="coprincipalinvestigator"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator.CoPIGrantCountRequestHandler" />
|
||||
|
||||
-->
|
||||
<bean id="visualizationInjector"
|
||||
class="edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationInjector">
|
||||
<property name="visualizations">
|
||||
<map>
|
||||
<entry key="person_pub_count">
|
||||
<ref bean="person_pub_count"></ref>
|
||||
</entry>
|
||||
|
||||
<!--
|
||||
<entry key="coauthorship">
|
||||
<ref bean="coauthorship"></ref>
|
||||
</entry>
|
||||
<entry key="person_level">
|
||||
<ref bean="person_level"></ref>
|
||||
</entry>
|
||||
<entry key="utilities">
|
||||
<ref bean="utilities"></ref>
|
||||
</entry>
|
||||
<entry key="entity_comparison">
|
||||
<ref bean="entity_comparison"></ref>
|
||||
</entry>
|
||||
<entry key="coprincipalinvestigator">
|
||||
<ref bean="coprincipalinvestigator"></ref>
|
||||
</entry>
|
||||
|
||||
-->
|
||||
</map>
|
||||
</property>
|
||||
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -1251,7 +1251,7 @@
|
|||
|
||||
<servlet>
|
||||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.DummyVisClientController</servlet-class>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.DummyVisClientController</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
|
@ -1271,6 +1271,17 @@
|
|||
<url-pattern>/visualization</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>VisualizationControllerFM</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.VisualizationController</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>VisualizationControllerFM</servlet-name>
|
||||
<url-pattern>/visualizationfm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>authtest</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.auth.AuthTestController</servlet-class>
|
||||
|
|
|
@ -26,5 +26,6 @@ var visualization = {
|
|||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
visualizationUrl = visualizationUrl.replace("/visualization", "/visualizationfm");
|
||||
visualization.render(visualizationUrl);
|
||||
});
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
<#-- Template for sparkline visualization on individual profile page -->
|
||||
|
||||
<#if individual.visualizationUrl??>
|
||||
|
||||
<#assign googleJSAPI = 'http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
|
||||
|
||||
<div id="vis_container"> </div>
|
||||
|
||||
${stylesheets.addFromTheme("/visualization/visualization.css")}
|
||||
${scripts.add(googleJSAPI)}
|
||||
${scripts.add("/js/visualization/sparkline.js")}
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
${headScripts.add("http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js")}
|
||||
${headScripts.add("http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D")}
|
||||
|
||||
This is Dummy Vis Client. For Real!
|
||||
Really Re!
|
||||
|
||||
${urls.base}
|
||||
|
||||
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||
|
||||
<#assign loadingImageLink = '/${themeDir}site_icons/visualization/ajax-loader.gif'>
|
||||
|
||||
<#assign uri="http://vivo-trunk.indiana.edu/individual/n6079">
|
||||
<#assign testURL = '${urls.base}/visualization?vis=person_pub_count&container=ajax_recipient&render_mode=dynamic&vis_mode=wth&uri=${uri?url}'>
|
||||
|
||||
<style type="text/css">
|
||||
.get_vis {
|
||||
background-color:Yellow;
|
||||
color:blue;
|
||||
cursor:pointer;
|
||||
height:36px;
|
||||
width:225px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
function renderVisualization(visualizationURL) {
|
||||
|
||||
$("#ajax_recipient").empty().html('<img src="${loadingImageLink?url}" />');
|
||||
|
||||
$.ajax({
|
||||
url: visualizationURL,
|
||||
dataType: "html",
|
||||
success:function(data){
|
||||
$("#ajax_recipient").html(data);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$("#ajax_activator").click(function() {
|
||||
$.ajax({
|
||||
url: '${testURL}',
|
||||
dataType: "html",
|
||||
success:function(data){
|
||||
|
||||
|
||||
$("#ajax_recipient").html(data);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
//-->
|
||||
</script>
|
||||
|
||||
<div class="staticPageBackground">
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
#test-bed {
|
||||
background-color:red;
|
||||
color:white;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<h1 id="test-bed">Visualization Testbed (Not to be seen by eventual end users)</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
<h2 id="ajax_activator">Hello World!</h2>
|
||||
|
||||
<c:url var="staticHref" value="/visualization">
|
||||
<c:param name="vis" value="person_pub_count"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="vis_mode" value="wth"/>
|
||||
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5156"/>
|
||||
</c:url>
|
||||
|
||||
<a href="${testURL}">vis query for person -> "Crane, Brian"</a>
|
||||
|
||||
|
||||
<div id="ajax_recipient">iioio</div>
|
|
@ -0,0 +1,7 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#assign googleJSAPI = 'http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D'>
|
||||
|
||||
${headScripts.add(googleJSAPI)}
|
||||
|
||||
<#include "/visualization/publicationSparklineContent.ftl">
|
|
@ -0,0 +1,247 @@
|
|||
<#assign visContainerID = '${sparklineVO.visContainerDivID}'>
|
||||
|
||||
<#if sparklineVO.shortVisMode>
|
||||
<#assign sparklineContainerID = 'pub_count_short_sparkline_vis'>
|
||||
<#else>
|
||||
<#assign sparklineContainerID = 'pub_count_full_sparkline_vis'>
|
||||
</#if>
|
||||
|
||||
<#-- This is used to prevent collision between sparkline & visualization conatiner div ids. -->
|
||||
<#if visContainerID?upper_case == sparklineContainerID?upper_case>
|
||||
<#assign sparklineContainerID = visContainerID + "_spark">
|
||||
</#if>
|
||||
|
||||
<div class="staticPageBackground">
|
||||
|
||||
<div id="${visContainerID}">
|
||||
|
||||
<style type='text/css'>
|
||||
.sparkline_style table {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: auto;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
vertical-align: inherit;
|
||||
}
|
||||
|
||||
table.sparkline_wrapper_table
|
||||
td,th {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.vis_link a {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
td.sparkline_number {
|
||||
text-align: right;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
td.sparkline_text {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.incomplete-data-holder {
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function drawPubCountVisualization(providedSparklineImgTD) {
|
||||
|
||||
var data = new google.visualization.DataTable();
|
||||
data.addColumn('string', 'Year');
|
||||
data.addColumn('number', 'Publications');
|
||||
data.addRows(${sparklineVO.numOfYearsToBeRendered});
|
||||
|
||||
<#list sparklineVO.yearToPublicationCountDataTable as yearToPublicationCountDataElement>
|
||||
data.setValue(${yearToPublicationCountDataElement.publicationCounter}, 0, '${yearToPublicationCountDataElement.publishedYear}');
|
||||
data.setValue(${yearToPublicationCountDataElement.publicationCounter}, 1, ${yearToPublicationCountDataElement.currentPublications});
|
||||
</#list>
|
||||
|
||||
<#-- Create a view of the data containing only the column pertaining to publication count. -->
|
||||
var sparklineDataView = new google.visualization.DataView(data);
|
||||
sparklineDataView.setColumns([1]);
|
||||
|
||||
<#if sparklineVO.shortVisMode>
|
||||
|
||||
console.log("Yay! Short Vis Mode!");
|
||||
|
||||
<#-- For the short view we only want the last 10 year's view of publication count, hence we filter
|
||||
the data we actually want to use for render. -->
|
||||
|
||||
sparklineDataView.setRows(data.getFilteredRows([{
|
||||
column: 0,
|
||||
minValue: '${sparklineVO.earliestRenderedPublicationYear?c}',
|
||||
maxValue: '${sparklineVO.latestRenderedPublicationYear?c}'
|
||||
/*minValue: '2001',
|
||||
maxValue: '2011'*/
|
||||
}]));
|
||||
|
||||
|
||||
<#else>
|
||||
|
||||
console.log("Yay! Full Vis Mode!");
|
||||
|
||||
</#if>
|
||||
|
||||
|
||||
<#-- Create the vis object and draw it in the div pertaining to sparkline. -->
|
||||
var sparkline = new google.visualization.ImageSparkLine(providedSparklineImgTD[0]);
|
||||
sparkline.draw(sparklineDataView, {
|
||||
width: 65,
|
||||
height: 30,
|
||||
showAxisLines: false,
|
||||
showValueLabels: false,
|
||||
labelPosition: 'none'
|
||||
});
|
||||
|
||||
<#if sparklineVO.shortVisMode>
|
||||
|
||||
<#-- We want to display how many publication counts were considered, so this is used to calculate this. -->
|
||||
|
||||
var shortSparkRows = sparklineDataView.getViewRows();
|
||||
var renderedShortSparks = 0;
|
||||
$.each(shortSparkRows, function(index, value) {
|
||||
renderedShortSparks += data.getValue(value, 1);
|
||||
});
|
||||
|
||||
$('#${sparklineContainerID} td.sparkline_number').text(parseInt(renderedShortSparks) + parseInt(${sparklineVO.unknownYearPublications}));
|
||||
|
||||
var sparksText = ' publication(s) within the last 10 years <span class="incomplete-data-holder" title="This information'
|
||||
+ ' is based solely on publications which have been loaded into the VIVO system. This may only be a small'
|
||||
+ ' sample of the person\'s total work.">incomplete list</span>';
|
||||
|
||||
<#else>
|
||||
|
||||
/*
|
||||
* Sparks that will be rendered will always be the one's which has
|
||||
* any year associated with it. Hence.
|
||||
* */
|
||||
var renderedSparks = ${sparklineVO.renderedSparks};
|
||||
$('#${sparklineContainerID} td.sparkline_number').text(parseInt(renderedSparks) + parseInt(${sparklineVO.unknownYearPublications}));
|
||||
|
||||
var sparksText = ' publication(s) from <span class="sparkline_range">${sparklineVO.earliestYearConsidered?c}'
|
||||
+ ' to ${sparklineVO.latestRenderedPublicationYear?c}</span> '
|
||||
+ ' <a href="${sparklineVO.downloadDataLink}" class="inline_href">(.CSV File)</a> ';
|
||||
</#if>
|
||||
|
||||
$('#${sparklineContainerID} td.sparkline_text').html(sparksText);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This will activate the visualization. It takes care of creating
|
||||
* div elements to hold the actual sparkline image and then calling the
|
||||
* drawPubCountVisualization function.
|
||||
* */
|
||||
|
||||
$(document).ready(function() {
|
||||
var sparklineImgTD;
|
||||
|
||||
/*
|
||||
* This is a nuclear option (creating the container in which everything goes)
|
||||
* the only reason this will be ever used is the API user never submitted a
|
||||
* container ID in which everything goes. The alternative was to let the
|
||||
* vis not appear in the calling page at all. So now atleast vis appears but
|
||||
* appended at the bottom of the body.
|
||||
* */
|
||||
|
||||
if ($('#${visContainerID}').length === 0) {
|
||||
$('<div/>', {
|
||||
'id': '${visContainerID}'
|
||||
}).appendTo('body');
|
||||
}
|
||||
|
||||
if ($('#${sparklineContainerID}').length === 0) {
|
||||
|
||||
$('<div/>', {
|
||||
'id': '${sparklineContainerID}',
|
||||
'class': 'sparkline_style'
|
||||
}).prependTo('#${visContainerID}');
|
||||
|
||||
var table = $('<table>');
|
||||
table.attr('class', 'sparkline_wrapper_table');
|
||||
var row = $('<tr>');
|
||||
sparklineImgTD = $('<td>');
|
||||
sparklineImgTD.attr('id', '${sparklineContainerID}_img');
|
||||
sparklineImgTD.attr('width', '65');
|
||||
sparklineImgTD.attr('align', 'right');
|
||||
sparklineImgTD.attr('class', 'sparkline_style');
|
||||
|
||||
row.append(sparklineImgTD);
|
||||
|
||||
console.log(sparklineImgTD);
|
||||
|
||||
var sparklineNumberTD = $('<td>');
|
||||
sparklineNumberTD.attr('width', '30');
|
||||
sparklineNumberTD.attr('align', 'right');
|
||||
sparklineNumberTD.attr('class', 'sparkline_number');
|
||||
row.append(sparklineNumberTD);
|
||||
var sparklineTextTD = $('<td>');
|
||||
sparklineTextTD.attr('width', '450');
|
||||
sparklineTextTD.attr('class', 'sparkline_text');
|
||||
row.append(sparklineTextTD);
|
||||
table.append(row);
|
||||
table.prependTo('#${sparklineContainerID}');
|
||||
|
||||
}
|
||||
|
||||
console.log(sparklineImgTD);
|
||||
|
||||
drawPubCountVisualization(sparklineImgTD);
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
<#if sparklineVO.shortVisMode>
|
||||
|
||||
<span class="vis_link">
|
||||
<a href="${sparklineVO.fullTimelineNetworkLink}">View all VIVO publications and corresponding co-author network.</a>
|
||||
|
||||
</span>
|
||||
|
||||
<#else>
|
||||
|
||||
<!-- For Full Sparkline - Print the Table of Publication Counts per Year -->
|
||||
<p>
|
||||
<table id='sparkline_data_table'>
|
||||
<caption>
|
||||
Publications per year <a href="${sparklineVO.downloadDataLink}">(.CSV File)</a>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Year
|
||||
</th>
|
||||
<th>
|
||||
Publications
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<#list sparklineVO.yearToActivityCount?keys as year>
|
||||
<tr>
|
||||
<td>
|
||||
${year}
|
||||
</td>
|
||||
<td>
|
||||
${sparklineVO.yearToActivityCount[year]}
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
Download data as <a href="${sparklineVO.downloadDataLink}">.csv</a> file.
|
||||
<br />
|
||||
</p>
|
||||
|
||||
</#if>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#if shouldVIVOrenderVis>
|
||||
<#include "/visualization/publicationSparklineContent.ftl">
|
||||
</#if>
|
|
@ -0,0 +1,8 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
|
||||
<div class="staticPageBackground">
|
||||
|
||||
${error}
|
||||
|
||||
</div>
|
||||
|
|
@ -11,6 +11,14 @@ public class VisualizationFrameworkConstants {
|
|||
*/
|
||||
public static final String RELATIVE_LOCATION_OF_VISUALIZATIONS_BEAN =
|
||||
"/WEB-INF/visualization/visualizations-beans-injection.xml";
|
||||
|
||||
/*
|
||||
* Freemarker Version
|
||||
* */
|
||||
public static final String RELATIVE_LOCATION_OF_FM_VISUALIZATIONS_BEAN =
|
||||
"/WEB-INF/visualization/visualizations-beans-injection-fm.xml";
|
||||
|
||||
public static final String ERROR_TEMPLATE = "/visualization/visualizationError.ftl";
|
||||
|
||||
/*
|
||||
* Vis URL prefix that is seen by all the users
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
|
||||
|
||||
/*
|
||||
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.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
|
||||
/**
|
||||
* Services a sparql query. This will return a simple error message and a 501 if
|
||||
* there is no jena Model.
|
||||
*
|
||||
* @author bdc34
|
||||
*
|
||||
*/
|
||||
public class DummyVisClientController extends FreemarkerHttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Log log = LogFactory.getLog(DummyVisClientController.class.getName());
|
||||
private static final String TEMPLATE_DEFAULT = "/visualization/dummyVisClient.ftl";
|
||||
|
||||
@Override
|
||||
protected int requiredLoginLevel() {
|
||||
// User must be logged in to view this page.
|
||||
return LoginStatusBean.EDITOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("portalBean", portal);
|
||||
//body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTitle(String siteName) {
|
||||
return "Dummy Visualization Controller";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.DatasetFactory;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
|
||||
import freemarker.template.Configuration;
|
||||
|
||||
/**
|
||||
* Services a visualization request. This will return a simple error message and a 501 if
|
||||
* there is no jena Model.
|
||||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class VisualizationController extends FreemarkerHttpServlet {
|
||||
|
||||
private Map<String, VisualizationRequestHandler> visualizationIDsToClass;
|
||||
|
||||
public static final String URL_ENCODING_SCHEME = "UTF-8";
|
||||
|
||||
private static final Log log = LogFactory.getLog(VisualizationController.class.getName());
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
|
||||
VitroRequest vreq = new VitroRequest(request);
|
||||
|
||||
String renderMode = vreq.getParameter(VisualizationFrameworkConstants
|
||||
.RENDER_MODE_KEY);
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(renderMode, VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE)) {
|
||||
|
||||
System.out.println("inside doing ajax request that is dynamic response");
|
||||
|
||||
Configuration config = getConfig(vreq);
|
||||
TemplateResponseValues trv = (TemplateResponseValues) processRequest(vreq);
|
||||
writeTemplate(trv.getTemplateName(), trv.getMap(), config, request, response);
|
||||
|
||||
} else {
|
||||
System.out.println("inside doing super.doGet that is normal response");
|
||||
super.doGet(request, response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This method is overridden to inject vis dependencies i.e. the vis algorithms that are
|
||||
* being implemented into the vis controller. Modified Dependency Injection pattern is
|
||||
* used here. XML file containing the location of all the vis is saved in accessible folder.
|
||||
* @see javax.servlet.GenericServlet#init()
|
||||
*/
|
||||
@Override
|
||||
public void init() throws ServletException {
|
||||
super.init();
|
||||
try {
|
||||
|
||||
String resourcePath =
|
||||
getServletContext()
|
||||
.getRealPath(VisualizationFrameworkConstants
|
||||
.RELATIVE_LOCATION_OF_FM_VISUALIZATIONS_BEAN);
|
||||
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"file:" + resourcePath);
|
||||
|
||||
BeanFactory factory = context;
|
||||
|
||||
VisualizationInjector visualizationInjector =
|
||||
(VisualizationInjector) factory.getBean("visualizationInjector");
|
||||
|
||||
visualizationIDsToClass = visualizationInjector.getVisualizationIDToClass();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||
|
||||
/*
|
||||
* Based on the query parameters passed via URI get the appropriate visualization
|
||||
* request handler.
|
||||
* */
|
||||
VisualizationRequestHandler visRequestHandler =
|
||||
getVisualizationRequestHandler(vreq);
|
||||
|
||||
if (visRequestHandler != null) {
|
||||
|
||||
/*
|
||||
* Pass the query to the selected visualization request handler & render the visualization.
|
||||
* Since the visualization content is directly added to the response object we are side-
|
||||
* effecting this method.
|
||||
* */
|
||||
return renderVisualization(vreq, visRequestHandler);
|
||||
|
||||
} else {
|
||||
|
||||
return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
|
||||
"Inappropriate query parameters were submitted.",
|
||||
vreq);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private ResponseValues renderVisualization(VitroRequest vitroRequest,
|
||||
VisualizationRequestHandler visRequestHandler) {
|
||||
|
||||
Model model = vitroRequest.getJenaOntModel(); // getModel()
|
||||
if (model == null) {
|
||||
|
||||
String errorMessage = "This service is not supporeted by the current "
|
||||
+ "webapp configuration. A jena model is required in the "
|
||||
+ "servlet context.";
|
||||
|
||||
log.error(errorMessage);
|
||||
|
||||
return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
|
||||
errorMessage,
|
||||
vitroRequest);
|
||||
|
||||
}
|
||||
|
||||
DataSource dataSource = setupJENADataSource(model, vitroRequest);
|
||||
|
||||
if (dataSource != null && visRequestHandler != null) {
|
||||
|
||||
return visRequestHandler.generateVisualization(vitroRequest,
|
||||
log,
|
||||
dataSource);
|
||||
|
||||
} else {
|
||||
|
||||
String errorMessage = "Data Model Empty &/or Inappropriate "
|
||||
+ "query parameters were submitted. ";
|
||||
|
||||
log.error(errorMessage);
|
||||
|
||||
return UtilityFunctions.handleMalformedParameters("Visualization Query Error",
|
||||
errorMessage,
|
||||
vitroRequest);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private VisualizationRequestHandler getVisualizationRequestHandler(
|
||||
VitroRequest vitroRequest) {
|
||||
|
||||
String visType = vitroRequest.getParameter(VisualizationFrameworkConstants
|
||||
.VIS_TYPE_KEY);
|
||||
VisualizationRequestHandler visRequestHandler = null;
|
||||
|
||||
System.out.println(visType + " --> " + visualizationIDsToClass);
|
||||
|
||||
try {
|
||||
visRequestHandler = visualizationIDsToClass.get(visType);
|
||||
} catch (NullPointerException nullKeyException) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return visRequestHandler;
|
||||
}
|
||||
|
||||
private DataSource setupJENADataSource(Model model, VitroRequest vreq) {
|
||||
|
||||
log.debug("rdfResultFormat was: " + VisConstants.RDF_RESULT_FORMAT_PARAM);
|
||||
|
||||
DataSource dataSource = DatasetFactory.create();
|
||||
ModelMaker maker = (ModelMaker) getServletContext().getAttribute("vitroJenaModelMaker");
|
||||
|
||||
dataSource.setDefaultModel(model);
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
|
||||
|
||||
public class VisualizationInjector {
|
||||
private Map<String, VisualizationRequestHandler> visualizationIDToClass;
|
||||
|
||||
public Map<String, VisualizationRequestHandler> getVisualizationIDToClass() {
|
||||
|
||||
System.out.println("giving the vis id class " + visualizationIDToClass);
|
||||
return visualizationIDToClass;
|
||||
}
|
||||
|
||||
public void setVisualizations(Map<String, VisualizationRequestHandler> visualizationIDToClass) {
|
||||
this.visualizationIDToClass = visualizationIDToClass;
|
||||
System.out.println("setting the vis id class " + visualizationIDToClass);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.personpubcount;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.iri.IRI;
|
||||
import com.hp.hpl.jena.iri.IRIFactory;
|
||||
import com.hp.hpl.jena.iri.Violation;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.Query;
|
||||
import com.hp.hpl.jena.query.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||
import com.hp.hpl.jena.query.QueryFactory;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 PersonPublicationCountQueryRunner implements QueryRunner<Set<BiboDocument>> {
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String personURI;
|
||||
private DataSource dataSource;
|
||||
|
||||
private Individual author;
|
||||
|
||||
public Individual getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
private Log log;
|
||||
|
||||
private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = ""
|
||||
+ "SELECT (str(?authorLabel) as ?authorLabelLit) "
|
||||
+ " (str(?document) as ?documentLit) "
|
||||
+ " (str(?documentMoniker) as ?documentMonikerLit) "
|
||||
+ " (str(?documentLabel) as ?documentLabelLit) "
|
||||
+ " (str(?documentBlurb) as ?documentBlurbLit) "
|
||||
+ " (str(?publicationYear) as ?publicationYearLit) "
|
||||
+ " (str(?publicationYearMonth) as ?publicationYearMonthLit) "
|
||||
+ " (str(?publicationDate) as ?publicationDateLit) "
|
||||
+ " (str(?documentDescription) as ?documentDescriptionLit) ";
|
||||
|
||||
private static final String SPARQL_QUERY_COMMON_WHERE_CLAUSE = ""
|
||||
+ "?document rdfs:label ?documentLabel ."
|
||||
+ "OPTIONAL { ?document core:year ?publicationYear } ."
|
||||
+ "OPTIONAL { ?document core:yearMonth ?publicationYearMonth } ."
|
||||
+ "OPTIONAL { ?document core:date ?publicationDate } ."
|
||||
+ "OPTIONAL { ?document vitro:moniker ?documentMoniker } ."
|
||||
+ "OPTIONAL { ?document vitro:blurb ?documentBlurb } ."
|
||||
+ "OPTIONAL { ?document vitro:description ?documentDescription }";
|
||||
|
||||
public PersonPublicationCountQueryRunner(String personURI,
|
||||
DataSource dataSource, Log log) {
|
||||
|
||||
this.personURI = personURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
|
||||
}
|
||||
|
||||
private Set<BiboDocument> createJavaValueObjects(ResultSet resultSet) {
|
||||
Set<BiboDocument> authorDocuments = new HashSet<BiboDocument>();
|
||||
|
||||
while (resultSet.hasNext()) {
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
BiboDocument biboDocument = new BiboDocument(
|
||||
solution.get(QueryFieldLabels.DOCUMENT_URL)
|
||||
.toString());
|
||||
|
||||
RDFNode documentLabelNode = solution.get(QueryFieldLabels.DOCUMENT_LABEL);
|
||||
if (documentLabelNode != null) {
|
||||
biboDocument.setDocumentLabel(documentLabelNode.toString());
|
||||
}
|
||||
|
||||
|
||||
RDFNode documentBlurbNode = solution.get(QueryFieldLabels.DOCUMENT_BLURB);
|
||||
if (documentBlurbNode != null) {
|
||||
biboDocument.setDocumentBlurb(documentBlurbNode.toString());
|
||||
}
|
||||
|
||||
RDFNode documentmonikerNode = solution.get(QueryFieldLabels.DOCUMENT_MONIKER);
|
||||
if (documentmonikerNode != null) {
|
||||
biboDocument.setDocumentMoniker(documentmonikerNode.toString());
|
||||
}
|
||||
|
||||
RDFNode documentDescriptionNode = solution.get(QueryFieldLabels.DOCUMENT_DESCRIPTION);
|
||||
if (documentDescriptionNode != null) {
|
||||
biboDocument.setDocumentDescription(documentDescriptionNode.toString());
|
||||
}
|
||||
|
||||
RDFNode publicationYearNode = solution.get(QueryFieldLabels.DOCUMENT_PUBLICATION_YEAR);
|
||||
if (publicationYearNode != null) {
|
||||
biboDocument.setPublicationYear(publicationYearNode.toString());
|
||||
}
|
||||
|
||||
RDFNode publicationYearMonthNode = solution.get(
|
||||
QueryFieldLabels
|
||||
.DOCUMENT_PUBLICATION_YEAR_MONTH);
|
||||
if (publicationYearMonthNode != null) {
|
||||
biboDocument.setPublicationYearMonth(publicationYearMonthNode.toString());
|
||||
}
|
||||
|
||||
RDFNode publicationDateNode = solution.get(QueryFieldLabels.DOCUMENT_PUBLICATION_DATE);
|
||||
if (publicationDateNode != null) {
|
||||
biboDocument.setPublicationDate(publicationDateNode.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we are getting publication count for just one author at a time we need
|
||||
* to create only one "Individual" instance. We test against the null for "author" to
|
||||
* make sure that it has not already been instantiated.
|
||||
* */
|
||||
RDFNode authorURLNode = solution.get(QueryFieldLabels.AUTHOR_URL);
|
||||
if (authorURLNode != null && author == null) {
|
||||
author = new Individual(authorURLNode.toString());
|
||||
RDFNode authorLabelNode = solution.get(QueryFieldLabels.AUTHOR_LABEL);
|
||||
if (authorLabelNode != null) {
|
||||
author.setIndividualLabel(authorLabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
authorDocuments.add(biboDocument);
|
||||
}
|
||||
return authorDocuments;
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryURI,
|
||||
DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
// try {
|
||||
Query query = QueryFactory.create(getSparqlQuery(queryURI), SYNTAX);
|
||||
|
||||
// QuerySolutionMap qs = new QuerySolutionMap();
|
||||
// qs.add("authPerson", queryParam); // bind resource to s
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
|
||||
|
||||
// if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
// }
|
||||
// } finally {
|
||||
// if (queryExecution != null) {
|
||||
// queryExecution.close();
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
}
|
||||
|
||||
private String getSparqlQuery(String queryURI) {
|
||||
// Resource uri1 = ResourceFactory.createResource(queryURI);
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE
|
||||
+ "(str(<" + queryURI + ">) as ?authPersonLit) "
|
||||
+ "WHERE { "
|
||||
+ "<" + queryURI + "> rdf:type foaf:Person ;"
|
||||
+ " rdfs:label ?authorLabel ;"
|
||||
+ " core:authorInAuthorship ?authorshipNode . "
|
||||
+ " ?authorshipNode rdf:type core:Authorship ;"
|
||||
+ " core:linkedInformationResource ?document . "
|
||||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE
|
||||
+ "}";
|
||||
|
||||
// System.out.println("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getQueryResult()
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.personURI)) {
|
||||
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
* */
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
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);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an individual is malformed.");
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new MalformedQueryParametersException("URL parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(this.personURI,
|
||||
this.dataSource);
|
||||
|
||||
return createJavaValueObjects(resultSet);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,342 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.personpubcount;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.FileResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.VisualizationRequestHandler;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
|
||||
|
||||
/**
|
||||
*
|
||||
* 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 ResponseValues generateVisualization(VitroRequest vitroRequest,
|
||||
Log log,
|
||||
DataSource dataSource) {
|
||||
|
||||
String peronURI = vitroRequest.getParameter(
|
||||
VisualizationFrameworkConstants
|
||||
.INDIVIDUAL_URI_KEY);
|
||||
|
||||
String renderMode = vitroRequest.getParameter(
|
||||
VisualizationFrameworkConstants
|
||||
.RENDER_MODE_KEY);
|
||||
|
||||
String visMode = vitroRequest.getParameter(
|
||||
VisualizationFrameworkConstants
|
||||
.VIS_MODE_KEY);
|
||||
|
||||
String visContainer = vitroRequest.getParameter(
|
||||
VisualizationFrameworkConstants
|
||||
.VIS_CONTAINER_KEY);
|
||||
|
||||
QueryRunner<Set<BiboDocument>> queryManager =
|
||||
new PersonPublicationCountQueryRunner(peronURI, dataSource, log);
|
||||
|
||||
try {
|
||||
Set<BiboDocument> authorDocuments = queryManager.getQueryResult();
|
||||
|
||||
/*
|
||||
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||
* parsedPublicationYear to populate the data.
|
||||
* */
|
||||
Map<String, Integer> yearToPublicationCount =
|
||||
UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||
|
||||
Individual author = ((PersonPublicationCountQueryRunner) queryManager).getAuthor();
|
||||
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
return prepareDataResponse(author,
|
||||
authorDocuments,
|
||||
yearToPublicationCount);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* For now we are disabling the capability to render pdf file.
|
||||
* */
|
||||
/*
|
||||
if (VisualizationFrameworkConstants.PDF_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
preparePDFResponse(author,
|
||||
authorDocuments,
|
||||
yearToPublicationCount,
|
||||
response);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Computations required to generate HTML for the sparkline & related context.
|
||||
* */
|
||||
PersonPublicationCountVisCodeGenerator visualizationCodeGenerator =
|
||||
new PersonPublicationCountVisCodeGenerator(vitroRequest.getContextPath(),
|
||||
peronURI,
|
||||
visMode,
|
||||
visContainer,
|
||||
authorDocuments,
|
||||
yearToPublicationCount,
|
||||
log);
|
||||
|
||||
SparklineData sparklineData = visualizationCodeGenerator
|
||||
.getValueObjectContainer();
|
||||
|
||||
/*
|
||||
* This is side-effecting because the response of this method is just to redirect to
|
||||
* a page with visualization on it.
|
||||
* */
|
||||
RequestDispatcher requestDispatcher = null;
|
||||
|
||||
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
return prepareDynamicResponse(vitroRequest,
|
||||
sparklineData,
|
||||
yearToPublicationCount);
|
||||
|
||||
// requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||
|
||||
} else {
|
||||
return prepareStandaloneResponse(vitroRequest,
|
||||
sparklineData);
|
||||
}
|
||||
|
||||
} catch (MalformedQueryParametersException e) {
|
||||
return UtilityFunctions.handleMalformedParameters(
|
||||
"Visualization Query Error - Individual Publication Count",
|
||||
e.getMessage(),
|
||||
vitroRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private String getPublicationsOverTimeCSVContent(Map<String, Integer> yearToPublicationCount) {
|
||||
|
||||
StringBuilder csvFileContent = new StringBuilder();
|
||||
|
||||
csvFileContent.append("Year, Publications\n");
|
||||
|
||||
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||
csvFileContent.append(StringEscapeUtils.escapeCsv(currentEntry.getKey()));
|
||||
csvFileContent.append(",");
|
||||
csvFileContent.append(currentEntry.getValue());
|
||||
csvFileContent.append("\n");
|
||||
}
|
||||
|
||||
return csvFileContent.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when csv file containing the publication count over the years
|
||||
* is requested.
|
||||
* @param author
|
||||
* @param authorDocuments
|
||||
* @param yearToPublicationCount
|
||||
* @return
|
||||
*/
|
||||
private FileResponseValues prepareDataResponse(
|
||||
Individual author,
|
||||
Set<BiboDocument> authorDocuments,
|
||||
Map<String, Integer> yearToPublicationCount) {
|
||||
|
||||
|
||||
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";
|
||||
|
||||
|
||||
Map<String, Object> fileContents = new HashMap<String, Object>();
|
||||
fileContents.put("fileContent", getPublicationsOverTimeCSVContent(yearToPublicationCount));
|
||||
|
||||
return new FileResponseValues(new ContentType(), outputFileName, fileContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when an entire page dedicated to publication sparkline is requested.
|
||||
* @param vreq
|
||||
* @param valueObjectContainer
|
||||
* @return
|
||||
*/
|
||||
private TemplateResponseValues prepareStandaloneResponse(VitroRequest vreq,
|
||||
SparklineData valueObjectContainer) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
String standaloneTemplate = "/visualization/publicationCount.ftl";
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("portalBean", portal);
|
||||
body.put("title", "Individual Publication Count visualization");
|
||||
body.put("sparklineVO", valueObjectContainer);
|
||||
|
||||
/*
|
||||
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
|
||||
* */
|
||||
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
return new TemplateResponseValues(standaloneTemplate, body);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when the publication sparkline has to be rendered in already existing
|
||||
* page, e.g. profile page.
|
||||
* @param vreq
|
||||
* @param valueObjectContainer
|
||||
* @param yearToPublicationCount
|
||||
* @return
|
||||
*/
|
||||
private TemplateResponseValues prepareDynamicResponse(
|
||||
VitroRequest vreq,
|
||||
SparklineData valueObjectContainer,
|
||||
Map<String, Integer> yearToPublicationCount) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
|
||||
String dynamicTemplate = "/visualization/sparklineAjaxVisContent.ftl";
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("portalBean", portal);
|
||||
body.put("sparklineVO", valueObjectContainer);
|
||||
|
||||
/*
|
||||
* DO NOT DO THIS HERE. Set stylesheets/scripts in the *.ftl instead using $(scripts.add)
|
||||
* */
|
||||
// body.put("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
body.put("shouldVIVOrenderVis", true);
|
||||
} else {
|
||||
body.put("shouldVIVOrenderVis", false);
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(dynamicTemplate, body);
|
||||
|
||||
}
|
||||
|
||||
private void preparePDFResponse(
|
||||
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) + "_report" + ".pdf";
|
||||
|
||||
response.setContentType("application/pdf");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||
|
||||
ServletOutputStream responseOutputStream;
|
||||
try {
|
||||
responseOutputStream = response.getOutputStream();
|
||||
|
||||
|
||||
Document document = new Document();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
|
||||
document.open();
|
||||
|
||||
PDFDocument pdfDocument = new PDFDocument(authorName,
|
||||
yearToPublicationCount,
|
||||
document,
|
||||
pdfWriter);
|
||||
|
||||
document.close();
|
||||
|
||||
// setting some response headers & content type
|
||||
response.setHeader("Expires", "0");
|
||||
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
|
||||
response.setHeader("Pragma", "public");
|
||||
response.setContentLength(baos.size());
|
||||
// write ByteArrayOutputStream to the ServletOutputStream
|
||||
baos.writeTo(responseOutputStream);
|
||||
responseOutputStream.flush();
|
||||
responseOutputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,676 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.personpubcount;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker.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.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.SparklineData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.YearPublicationCountDataElement;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PersonPublicationCountVisCodeGenerator {
|
||||
|
||||
/*
|
||||
* 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");
|
||||
put("FULL_SPARK", "pub_count_full_sparkline_vis");
|
||||
|
||||
} };
|
||||
|
||||
private static final String VISUALIZATION_STYLE_CLASS = "sparkline_style";
|
||||
|
||||
private static final String DEFAULT_VIS_CONTAINER_DIV_ID = "pub_count_vis_container";
|
||||
|
||||
private Map<String, Integer> yearToPublicationCount;
|
||||
|
||||
private Log log;
|
||||
|
||||
private SparklineData sparklineData;
|
||||
|
||||
private String contextPath;
|
||||
|
||||
private String individualURI;
|
||||
|
||||
public PersonPublicationCountVisCodeGenerator(String contextPath,
|
||||
String individualURIParam,
|
||||
String visMode,
|
||||
String visContainer,
|
||||
Set<BiboDocument> authorDocuments,
|
||||
Map<String, Integer> yearToPublicationCount,
|
||||
Log log) {
|
||||
|
||||
this.contextPath = contextPath;
|
||||
this.individualURI = individualURIParam;
|
||||
|
||||
this.yearToPublicationCount = yearToPublicationCount;
|
||||
this.sparklineData = new SparklineData();
|
||||
|
||||
sparklineData.setYearToActivityCount(yearToPublicationCount);
|
||||
|
||||
|
||||
this.log = log;
|
||||
|
||||
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) {
|
||||
|
||||
sparklineData.setSparklineContent(getMainVisualizationCode(authorDocuments,
|
||||
visMode,
|
||||
visContainer));
|
||||
|
||||
|
||||
sparklineData.setSparklineContext(getVisualizationContextCode(visMode));
|
||||
|
||||
}
|
||||
|
||||
private String getMainVisualizationCode(Set<BiboDocument> authorDocuments,
|
||||
String visMode,
|
||||
String providedVisContainerID) {
|
||||
|
||||
int numOfYearsToBeRendered = 0;
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
int shortSparkMinYear = currentYear
|
||||
- VisConstants.MINIMUM_YEARS_CONSIDERED_FOR_SPARKLINE
|
||||
+ 1;
|
||||
|
||||
/*
|
||||
* This is required because when deciding the range of years over which the vis
|
||||
* was rendered we dont want to be influenced by the "DEFAULT_PUBLICATION_YEAR".
|
||||
* */
|
||||
Set<String> publishedYears = new HashSet<String>(yearToPublicationCount.keySet());
|
||||
publishedYears.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* We are setting the default value of minPublishedYear to be 10 years before
|
||||
* the current year (which is suitably represented by the shortSparkMinYear),
|
||||
* this in case we run into invalid set of published years.
|
||||
* */
|
||||
int minPublishedYear = shortSparkMinYear;
|
||||
|
||||
String visContainerID = null;
|
||||
|
||||
StringBuilder visualizationCode = new StringBuilder();
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
try {
|
||||
minPublishedYear = Integer.parseInt(Collections.min(publishedYears));
|
||||
} catch (NoSuchElementException e1) {
|
||||
log.debug("vis: " + e1.getMessage() + " error occurred for "
|
||||
+ yearToPublicationCount.toString());
|
||||
} catch (NumberFormatException e2) {
|
||||
log.debug("vis: " + e2.getMessage() + " error occurred for "
|
||||
+ yearToPublicationCount.toString());
|
||||
}
|
||||
}
|
||||
|
||||
int minPubYearConsidered = 0;
|
||||
|
||||
/*
|
||||
* There might be a case that the author has made his first publication within the
|
||||
* last 10 years but we want to make sure that the sparkline is representative of
|
||||
* at least the last 10 years, so we will set the minPubYearConsidered to
|
||||
* "currentYear - 10" which is also given by "shortSparkMinYear".
|
||||
* */
|
||||
if (minPublishedYear > shortSparkMinYear) {
|
||||
minPubYearConsidered = shortSparkMinYear;
|
||||
} else {
|
||||
minPubYearConsidered = minPublishedYear;
|
||||
}
|
||||
|
||||
numOfYearsToBeRendered = currentYear - minPubYearConsidered + 1;
|
||||
|
||||
sparklineData.setNumOfYearsToBeRendered(numOfYearsToBeRendered);
|
||||
|
||||
visualizationCode.append("<style type='text/css'>"
|
||||
+ "." + VISUALIZATION_STYLE_CLASS + " table{"
|
||||
+ " margin: 0;"
|
||||
+ " padding: 0;"
|
||||
+ " width: auto;"
|
||||
+ " border-collapse: collapse;"
|
||||
+ " border-spacing: 0;"
|
||||
+ " vertical-align: inherit;"
|
||||
+ "}"
|
||||
+ "table.sparkline_wrapper_table td, th {"
|
||||
+ " vertical-align: bottom;"
|
||||
+ "}"
|
||||
+ ".vis_link a{"
|
||||
+ " padding-top: 5px;"
|
||||
+ "}"
|
||||
+ "td.sparkline_number { text-align:right; "
|
||||
+ "padding-right:5px; }"
|
||||
+ "td.sparkline_text {text-align:left;}"
|
||||
+ ".incomplete-data-holder {"
|
||||
+ ""
|
||||
+ "}"
|
||||
+ "</style>\n");
|
||||
|
||||
visualizationCode.append("<script type=\"text/javascript\">\n"
|
||||
+ "function drawPubCountVisualization(providedSparklineImgTD) "
|
||||
+ "{\n"
|
||||
+ "var data = new google.visualization.DataTable();\n"
|
||||
+ "data.addColumn('string', 'Year');\n"
|
||||
+ "data.addColumn('number', 'Publications');\n"
|
||||
+ "data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||
|
||||
int publicationCounter = 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;
|
||||
|
||||
List<YearPublicationCountDataElement> yearToPublicationCountDataTable = new ArrayList<YearPublicationCountDataElement>();
|
||||
|
||||
for (int publicationYear = minPubYearConsidered;
|
||||
publicationYear <= currentYear;
|
||||
publicationYear++) {
|
||||
|
||||
String stringPublishedYear = String.valueOf(publicationYear);
|
||||
Integer currentPublications = yearToPublicationCount.get(stringPublishedYear);
|
||||
|
||||
if (currentPublications == null) {
|
||||
currentPublications = 0;
|
||||
}
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ publicationCounter
|
||||
+ ", 0, '"
|
||||
+ stringPublishedYear
|
||||
+ "');\n");
|
||||
|
||||
visualizationCode.append("data.setValue("
|
||||
+ publicationCounter
|
||||
+ ", 1, "
|
||||
+ currentPublications
|
||||
+ ");\n");
|
||||
|
||||
yearToPublicationCountDataTable.add(new YearPublicationCountDataElement(publicationCounter, stringPublishedYear, currentPublications));
|
||||
|
||||
/*
|
||||
* Sparks that will be rendered will always be the one's which has
|
||||
* any year associated with it. Hence.
|
||||
* */
|
||||
renderedFullSparks += currentPublications;
|
||||
publicationCounter++;
|
||||
|
||||
}
|
||||
|
||||
sparklineData.setYearToPublicationCountDataTable(yearToPublicationCountDataTable);
|
||||
|
||||
|
||||
sparklineData.setRenderedSparks(renderedFullSparks);
|
||||
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
unknownYearPublications = yearToPublicationCount
|
||||
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
}
|
||||
|
||||
|
||||
sparklineData.setUnknownYearPublications(unknownYearPublications);
|
||||
|
||||
String sparklineDisplayOptions = "{width: 65, height: 30, showAxisLines: false, "
|
||||
+ "showValueLabels: false, labelPosition: 'none'}";
|
||||
|
||||
if (providedVisContainerID != null) {
|
||||
visContainerID = providedVisContainerID;
|
||||
} else {
|
||||
visContainerID = DEFAULT_VIS_CONTAINER_DIV_ID;
|
||||
}
|
||||
|
||||
sparklineData.setVisContainerDivID(visContainerID);
|
||||
|
||||
/*
|
||||
* By default these represents the range of the rendered sparks. Only in case of
|
||||
* "short" sparkline mode we will set the Earliest RenderedPublication year to
|
||||
* "currentYear - 10".
|
||||
* */
|
||||
sparklineData.setEarliestYearConsidered(minPubYearConsidered);
|
||||
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.
|
||||
* */
|
||||
|
||||
|
||||
/*
|
||||
* Since building StringBuilder objects (which is being used to store the vis code) is
|
||||
* essentially a side-effecting process, we have both the activators method as side-
|
||||
* effecting. They both side-effect "visualizationCode"
|
||||
* */
|
||||
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
|
||||
|
||||
sparklineData.setEarliestRenderedPublicationYear(shortSparkMinYear);
|
||||
|
||||
sparklineData.setShortVisMode(true);
|
||||
|
||||
generateShortSparklineVisualizationContent(currentYear,
|
||||
shortSparkMinYear,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearPublications,
|
||||
sparklineDisplayOptions);
|
||||
} else {
|
||||
|
||||
sparklineData.setShortVisMode(false);
|
||||
generateFullSparklineVisualizationContent(currentYear,
|
||||
minPubYearConsidered,
|
||||
visContainerID,
|
||||
visualizationCode,
|
||||
unknownYearPublications,
|
||||
renderedFullSparks,
|
||||
sparklineDisplayOptions);
|
||||
}
|
||||
log.debug(visualizationCode);
|
||||
return visualizationCode.toString();
|
||||
}
|
||||
|
||||
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||
int shortSparkMinYear,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearPublications,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
/*
|
||||
* Create a view of the data containing only the column pertaining to publication count.
|
||||
* */
|
||||
visualizationCode.append("var shortSparklineView = "
|
||||
+ "new google.visualization.DataView(data);\n"
|
||||
+ "shortSparklineView.setColumns([1]);\n");
|
||||
|
||||
/*
|
||||
* For the short view we only want the last 10 year's view of publication count,
|
||||
* hence we filter the data we actually want to use for render.
|
||||
* */
|
||||
visualizationCode.append("shortSparklineView.setRows("
|
||||
+ "data.getFilteredRows([{column: 0, "
|
||||
+ "minValue: '" + shortSparkMinYear + "', "
|
||||
+ "maxValue: '" + currentYear + "'}])"
|
||||
+ ");\n");
|
||||
|
||||
/*
|
||||
* Create the vis object and draw it in the div pertaining to short-sparkline.
|
||||
* */
|
||||
visualizationCode.append("var short_spark = new google.visualization.ImageSparkLine("
|
||||
+ "providedSparklineImgTD[0]"
|
||||
+ ");\n"
|
||||
+ "short_spark.draw(shortSparklineView, "
|
||||
+ sparklineDisplayOptions + ");\n");
|
||||
|
||||
/*
|
||||
* We want to display how many publication counts were considered, so this is used
|
||||
* to calculate this.
|
||||
* */
|
||||
visualizationCode.append("var shortSparkRows = shortSparklineView.getViewRows();\n"
|
||||
+ "var renderedShortSparks = 0;\n"
|
||||
+ "$.each(shortSparkRows, function(index, value) {"
|
||||
+ "renderedShortSparks += data.getValue(value, 1);"
|
||||
+ "});\n");
|
||||
|
||||
/*
|
||||
* Generate the text introducing the vis.
|
||||
* */
|
||||
|
||||
|
||||
String imcompleteDataText = "This information is based solely on publications which "
|
||||
+ "have been loaded into the VIVO system. "
|
||||
+ "This may only be a small sample of the person\\'s "
|
||||
+ "total work.";
|
||||
|
||||
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("SHORT_SPARK")
|
||||
+ " td.sparkline_number').text("
|
||||
+ "parseInt(renderedShortSparks) "
|
||||
+ "+ parseInt(" + unknownYearPublications + "));");
|
||||
|
||||
visualizationCode.append("var shortSparksText = ''"
|
||||
+ "+ ' publication(s) within the last 10 years "
|
||||
+ "<span class=\"incomplete-data-holder\" title=\""
|
||||
+ imcompleteDataText + "\">incomplete data</span>'"
|
||||
+ "+ '';"
|
||||
+ "$('#" + VIS_DIV_NAMES.get("SHORT_SPARK") + " "
|
||||
+ "td.sparkline_text').html(shortSparksText);");
|
||||
|
||||
visualizationCode.append("}\n ");
|
||||
|
||||
/*
|
||||
* Generate the code that will activate the visualization. It takes care of creating
|
||||
* div elements to hold the actual sparkline image and then calling the
|
||||
* drawPubCountVisualization function.
|
||||
* */
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("SHORT_SPARK"),
|
||||
visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private void generateFullSparklineVisualizationContent(
|
||||
int currentYear,
|
||||
int minPubYearConsidered,
|
||||
String visContainerID,
|
||||
StringBuilder visualizationCode,
|
||||
int unknownYearPublications,
|
||||
int renderedFullSparks,
|
||||
String sparklineDisplayOptions) {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL()
|
||||
+ "\" class=\"inline_href\">(.CSV File)</a>";
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
|
||||
visualizationCode.append("var fullSparklineView = "
|
||||
+ "new google.visualization.DataView(data);\n"
|
||||
+ "fullSparklineView.setColumns([1]);\n");
|
||||
|
||||
visualizationCode.append("var full_spark = new google.visualization.ImageSparkLine("
|
||||
+ "providedSparklineImgTD[0]"
|
||||
+ ");\n"
|
||||
+ "full_spark.draw(fullSparklineView, "
|
||||
+ sparklineDisplayOptions + ");\n");
|
||||
|
||||
visualizationCode.append("$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
|
||||
+ " td.sparkline_number').text('" + (renderedFullSparks
|
||||
+ unknownYearPublications) + "');");
|
||||
|
||||
visualizationCode.append("var allSparksText = ''"
|
||||
+ "+ ' publication(s) '"
|
||||
+ "+ ' from "
|
||||
+ "<span class=\"sparkline_range\">"
|
||||
+ "" + minPubYearConsidered + " to " + currentYear + ""
|
||||
+ "</span> '"
|
||||
+ "+ ' " + csvDownloadURLHref + " ';"
|
||||
+ "$('#" + VIS_DIV_NAMES.get("FULL_SPARK")
|
||||
+ " td.sparkline_text').html(allSparksText);");
|
||||
|
||||
visualizationCode.append("}\n ");
|
||||
|
||||
visualizationCode.append(generateVisualizationActivator(VIS_DIV_NAMES.get("FULL_SPARK"),
|
||||
visContainerID));
|
||||
|
||||
}
|
||||
|
||||
private String generateVisualizationActivator(String sparklineID, String visContainerID) {
|
||||
|
||||
String sparklineTableWrapper = "\n"
|
||||
+ "var table = $('<table>');"
|
||||
+ "table.attr('class', 'sparkline_wrapper_table');"
|
||||
+ "var row = $('<tr>');"
|
||||
+ "sparklineImgTD = $('<td>');"
|
||||
+ "sparklineImgTD.attr('id', '" + sparklineID + "_img');"
|
||||
+ "sparklineImgTD.attr('width', '65');"
|
||||
+ "sparklineImgTD.attr('align', 'right');"
|
||||
+ "sparklineImgTD.attr('class', '" + VISUALIZATION_STYLE_CLASS + "');"
|
||||
+ "row.append(sparklineImgTD);"
|
||||
+ "var sparklineNumberTD = $('<td>');"
|
||||
+ "sparklineNumberTD.attr('width', '30');"
|
||||
+ "sparklineNumberTD.attr('align', 'right');"
|
||||
+ "sparklineNumberTD.attr('class', 'sparkline_number');"
|
||||
+ "row.append(sparklineNumberTD);"
|
||||
+ "var sparklineTextTD = $('<td>');"
|
||||
+ "sparklineTextTD.attr('width', '450');"
|
||||
+ "sparklineTextTD.attr('class', 'sparkline_text');"
|
||||
+ "row.append(sparklineTextTD);"
|
||||
+ "table.append(row);"
|
||||
+ "table.prependTo('#" + sparklineID + "');\n";
|
||||
|
||||
return "$(document).ready(function() {"
|
||||
+ "var sparklineImgTD; "
|
||||
|
||||
/*
|
||||
* This is a nuclear option (creating the container in which everything goes)
|
||||
* the only reason this will be ever used is the API user never submitted a
|
||||
* container ID in which everything goes. The alternative was to let the
|
||||
* vis not appear in the calling page at all. So now atleast vis appears but
|
||||
* appended at the bottom of the body.
|
||||
* */
|
||||
|
||||
+ "if ($('#" + visContainerID + "').length === 0) {"
|
||||
+ " $('<div/>', {'id': '" + visContainerID + "'"
|
||||
+ " }).appendTo('body');"
|
||||
+ "}"
|
||||
+ "if ($('#" + sparklineID + "').length === 0) {"
|
||||
+ "$('<div/>', {'id': '" + sparklineID + "',"
|
||||
+ "'class': '" + VISUALIZATION_STYLE_CLASS + "'"
|
||||
+ "}).prependTo('#" + visContainerID + "');"
|
||||
+ sparklineTableWrapper
|
||||
+ "}"
|
||||
+ "drawPubCountVisualization(sparklineImgTD);"
|
||||
+ "});"
|
||||
+ "</script>\n";
|
||||
}
|
||||
|
||||
private String getVisualizationContextCode(String visMode) {
|
||||
|
||||
String visualizationContextCode = "";
|
||||
if (VisualizationFrameworkConstants.SHORT_SPARKLINE_VIS_MODE.equalsIgnoreCase(visMode)) {
|
||||
visualizationContextCode = generateShortVisContext();
|
||||
} else {
|
||||
visualizationContextCode = generateFullVisContext();
|
||||
}
|
||||
|
||||
log.debug(visualizationContextCode);
|
||||
|
||||
return visualizationContextCode;
|
||||
}
|
||||
|
||||
private String generateFullVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
|
||||
csvDownloadURLHref = "Download data as <a href='"
|
||||
+ getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||
sparklineData.setDownloadDataLink(getCSVDownloadURL());
|
||||
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
} else {
|
||||
csvDownloadURLHref = "No data available to export.<br />";
|
||||
}
|
||||
|
||||
String tableCode = generateDataTable();
|
||||
|
||||
divContextCode.append("<p>" + tableCode + csvDownloadURLHref + "</p>");
|
||||
|
||||
sparklineData.setTable(tableCode);
|
||||
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String getCSVDownloadURL()
|
||||
throws UnsupportedEncodingException {
|
||||
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
|
||||
String downloadURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode(
|
||||
VisualizationFrameworkConstants
|
||||
.PERSON_PUBLICATION_COUNT_VIS,
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString()
|
||||
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.DATA_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME)
|
||||
.toString();
|
||||
return downloadURL;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String generateShortVisContext() {
|
||||
|
||||
StringBuilder divContextCode = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
String fullTimelineLink;
|
||||
if (yearToPublicationCount.size() > 0) {
|
||||
|
||||
String secondaryContextPath = "";
|
||||
if (!contextPath.contains(VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX)) {
|
||||
secondaryContextPath = VisualizationFrameworkConstants.VISUALIZATION_URL_PREFIX;
|
||||
}
|
||||
|
||||
String fullTimelineNetworkURL = contextPath
|
||||
+ secondaryContextPath
|
||||
+ "?"
|
||||
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(individualURI,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.VIS_TYPE_KEY
|
||||
+ "=" + URLEncoder.encode("person_level",
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||
+ "&"
|
||||
+ VisualizationFrameworkConstants.RENDER_MODE_KEY
|
||||
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants
|
||||
.STANDALONE_RENDER_MODE,
|
||||
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||
|
||||
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View all VIVO "
|
||||
+ "publications and corresponding co-author network.</a>";
|
||||
|
||||
sparklineData.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||
|
||||
} else {
|
||||
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||
}
|
||||
|
||||
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return divContextCode.toString();
|
||||
}
|
||||
|
||||
private String generateDataTable() {
|
||||
|
||||
String csvDownloadURLHref = "";
|
||||
|
||||
try {
|
||||
if (getCSVDownloadURL() != null) {
|
||||
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||
} else {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
csvDownloadURLHref = "";
|
||||
}
|
||||
|
||||
StringBuilder dataTable = new StringBuilder();
|
||||
|
||||
dataTable.append("<table id='sparkline_data_table'>"
|
||||
+ "<caption>Publications per year " + csvDownloadURLHref + "</caption>"
|
||||
+ "<thead>"
|
||||
+ "<tr>"
|
||||
+ "<th>Year</th>"
|
||||
+ "<th>Publications</th>"
|
||||
+ "</tr>"
|
||||
+ "</thead>"
|
||||
+ "<tbody>");
|
||||
|
||||
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||
dataTable.append("<tr>"
|
||||
+ "<td>" + currentEntry.getKey() + "</td>"
|
||||
+ "<td>" + currentEntry.getValue() + "</td>"
|
||||
+ "</tr>");
|
||||
}
|
||||
|
||||
dataTable.append("</tbody>\n </table>\n");
|
||||
|
||||
return dataTable.toString();
|
||||
}
|
||||
|
||||
public SparklineData getValueObjectContainer() {
|
||||
return sparklineData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
|
||||
/**
|
||||
* @author cdtank
|
||||
*
|
||||
*/
|
||||
public class BiboDocument extends Individual {
|
||||
|
||||
private String documentMoniker;
|
||||
private String documentBlurb;
|
||||
private String documentDescription;
|
||||
private String publicationYear;
|
||||
private String publicationYearMonth;
|
||||
private String publicationDate;
|
||||
private String parsedPublicationYear = VOConstants.DEFAULT_PUBLICATION_YEAR;
|
||||
|
||||
public BiboDocument(String documentURL) {
|
||||
super(documentURL);
|
||||
}
|
||||
|
||||
public String getDocumentURL() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getDocumentMoniker() {
|
||||
return documentMoniker;
|
||||
}
|
||||
|
||||
public void setDocumentMoniker(String documentMoniker) {
|
||||
this.documentMoniker = documentMoniker;
|
||||
}
|
||||
|
||||
public String getDocumentLabel() {
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public void setDocumentLabel(String documentLabel) {
|
||||
this.setIndividualLabel(documentLabel);
|
||||
}
|
||||
|
||||
public String getDocumentBlurb() {
|
||||
return documentBlurb;
|
||||
}
|
||||
|
||||
public void setDocumentBlurb(String documentBlurb) {
|
||||
this.documentBlurb = documentBlurb;
|
||||
|
||||
// if (documentBlurb != null) {
|
||||
// this.setParsedPublicationYear(parsePublicationYear(documentBlurb));
|
||||
// }
|
||||
}
|
||||
|
||||
private String parsePublicationYear(String documentBlurb) {
|
||||
|
||||
/*
|
||||
* This pattern will match all group of numbers which have only 4 digits
|
||||
* delimited by the word boundary.
|
||||
* */
|
||||
String pattern = "(?<!-)\\b\\d{4}\\b(?=[^-])";
|
||||
|
||||
Pattern yearPattern = Pattern.compile(pattern);
|
||||
String publishedYear = VOConstants.DEFAULT_PUBLICATION_YEAR;
|
||||
|
||||
Matcher yearMatcher = yearPattern.matcher(documentBlurb);
|
||||
|
||||
while (yearMatcher.find()) {
|
||||
|
||||
String yearCandidate = yearMatcher.group();
|
||||
|
||||
Integer candidateYearInteger = Integer.valueOf(yearCandidate);
|
||||
|
||||
/*
|
||||
* Published year has to be equal or less than the current year
|
||||
* and more than a minimum default year.
|
||||
* */
|
||||
if (candidateYearInteger <= VOConstants.CURRENT_YEAR
|
||||
&& candidateYearInteger >= VOConstants.MINIMUM_PUBLICATION_YEAR) {
|
||||
publishedYear = candidateYearInteger.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return publishedYear;
|
||||
}
|
||||
|
||||
public String getDocumentDescription() {
|
||||
return documentDescription;
|
||||
}
|
||||
public void setDocumentDescription(String documentDescription) {
|
||||
this.documentDescription = documentDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called when there is no usable core:year value found
|
||||
* for the bibo:Document. It will first check & parse core:yearMonth failing
|
||||
* which it will try core:date
|
||||
* @return
|
||||
*/
|
||||
public String getParsedPublicationYear() {
|
||||
|
||||
/*
|
||||
* We are assuming that core:yearMonth has "YYYY-MM" format. This is based
|
||||
* off of http://www.w3.org/TR/xmlschema-2/#gYearMonth , which is what
|
||||
* core:yearMonth points to internally.
|
||||
* */
|
||||
if (publicationYearMonth != null
|
||||
&& publicationYearMonth.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& isValidPublicationYear(publicationYearMonth.substring(
|
||||
0,
|
||||
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
|
||||
|
||||
return publicationYearMonth.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
|
||||
|
||||
}
|
||||
|
||||
if (publicationDate != null
|
||||
&& publicationDate.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& isValidPublicationYear(publicationDate
|
||||
.substring(0,
|
||||
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
|
||||
|
||||
return publicationDate.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
|
||||
}
|
||||
|
||||
/*
|
||||
* If all else fails return default unknown year identifier
|
||||
* */
|
||||
return VOConstants.DEFAULT_PUBLICATION_YEAR;
|
||||
}
|
||||
|
||||
/*
|
||||
* This publicationYear value is directly from the data supported by the ontology.
|
||||
* If this is empty only then use the parsedPublicationYear.
|
||||
* */
|
||||
public String getPublicationYear() {
|
||||
if (publicationYear != null && isValidPublicationYear(publicationYear)) {
|
||||
return publicationYear;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setPublicationYear(String publicationYear) {
|
||||
this.publicationYear = publicationYear;
|
||||
}
|
||||
|
||||
public String getPublicationYearMonth() {
|
||||
return publicationYearMonth;
|
||||
}
|
||||
|
||||
public void setPublicationYearMonth(String publicationYearMonth) {
|
||||
this.publicationYearMonth = publicationYearMonth;
|
||||
}
|
||||
|
||||
public String getPublicationDate() {
|
||||
return publicationDate;
|
||||
}
|
||||
|
||||
public void setPublicationDate(String publicationDate) {
|
||||
this.publicationDate = publicationDate;
|
||||
}
|
||||
|
||||
private boolean isValidPublicationYear(String testPublicationYear) {
|
||||
|
||||
if (testPublicationYear.length() != 0
|
||||
&& testPublicationYear.trim().length() == VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& testPublicationYear.matches("\\d+")
|
||||
&& Integer.parseInt(testPublicationYear) >= VOConstants.MINIMUM_PUBLICATION_YEAR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*
|
||||
*/
|
||||
public class Child extends Individual {
|
||||
|
||||
Set<BiboDocument> documents = new HashSet<BiboDocument>();
|
||||
|
||||
public Child(String individualURI) {
|
||||
super(individualURI);
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getDocuments() {
|
||||
return documents;
|
||||
}
|
||||
|
||||
public Child(String individualURI, String individualLabel) {
|
||||
super(individualURI, individualLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other){
|
||||
boolean result = false;
|
||||
if (other instanceof Child){
|
||||
Child person = (Child) other;
|
||||
result = (this.getIndividualLabel().equals(person.getIndividualLabel())
|
||||
&& this.getIndividualURI().equals(person.getIndividualURI()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return(41*(getIndividualLabel().hashCode() + 41*(getIndividualURI().hashCode())));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CoAuthorshipData {
|
||||
|
||||
private Set<Node> nodes;
|
||||
private Set<Edge> edges;
|
||||
private Node egoNode;
|
||||
private Set<Map<String, String>> NODE_SCHEMA;
|
||||
private Set<Map<String, String>> EDGE_SCHEMA;
|
||||
|
||||
public CoAuthorshipData(Node egoNode, Set<Node> nodes, Set<Edge> edges) {
|
||||
this.egoNode = egoNode;
|
||||
this.nodes = nodes;
|
||||
this.edges = edges;
|
||||
}
|
||||
|
||||
public Set<Node> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public Set<Edge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
public Node getEgoNode() {
|
||||
return egoNode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Schema for graphML
|
||||
* */
|
||||
public Set<Map<String, String>> getNodeSchema() {
|
||||
|
||||
if (NODE_SCHEMA == null) {
|
||||
NODE_SCHEMA = initializeNodeSchema();
|
||||
}
|
||||
|
||||
return NODE_SCHEMA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Edge Schema for graphML
|
||||
* */
|
||||
public Set<Map<String, String>> getEdgeSchema() {
|
||||
|
||||
if (EDGE_SCHEMA == null) {
|
||||
EDGE_SCHEMA = initializeEdgeSchema();
|
||||
}
|
||||
|
||||
return EDGE_SCHEMA;
|
||||
}
|
||||
|
||||
private Set<Map<String, String>> initializeEdgeSchema() {
|
||||
|
||||
Set<Map<String, String>> edgeSchema = new HashSet<Map<String, String>>();
|
||||
|
||||
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "collaborator1");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "collaborator1");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "collaborator2");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "collaborator2");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "number_of_coauthored_works");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "number_of_coauthored_works");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "earliest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "earliest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_earliest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_earliest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "latest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "latest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_latest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_latest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_unknown_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_unknown_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
return edgeSchema;
|
||||
}
|
||||
|
||||
|
||||
private Set<Map<String, String>> initializeNodeSchema() {
|
||||
|
||||
Set<Map<String, String>> nodeSchema = new HashSet<Map<String, String>>();
|
||||
|
||||
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "url");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "url");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "label");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "label");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "profile_url");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "profile_url");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "number_of_authored_works");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "number_of_authored_works");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "earliest_publication");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "earliest_publication");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_earliest_publication");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_earliest_publication");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "latest_publication");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "latest_publication");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_latest_publication");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_latest_publication");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_unknown_publication");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_unknown_publication");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
|
||||
return nodeSchema;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CoPIData {
|
||||
|
||||
private Set<CoPINode> nodes;
|
||||
private Set<CoPIEdge> edges;
|
||||
private CoPINode egoNode;
|
||||
private Set<Map<String, String>> NODE_SCHEMA;
|
||||
private Set<Map<String, String>> EDGE_SCHEMA;
|
||||
|
||||
public CoPIData(CoPINode egoNode, Set<CoPINode> nodes, Set<CoPIEdge> edges) {
|
||||
this.egoNode = egoNode;
|
||||
this.nodes = nodes;
|
||||
this.edges = edges;
|
||||
}
|
||||
|
||||
public Set<CoPINode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public Set<CoPIEdge> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
public CoPINode getEgoNode() {
|
||||
return egoNode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node Schema for graphML
|
||||
* */
|
||||
public Set<Map<String, String>> getNodeSchema() {
|
||||
|
||||
if (NODE_SCHEMA == null) {
|
||||
NODE_SCHEMA = initializeNodeSchema();
|
||||
}
|
||||
|
||||
return NODE_SCHEMA;
|
||||
}
|
||||
|
||||
/*
|
||||
* Edge Schema for graphML
|
||||
* */
|
||||
public Set<Map<String, String>> getEdgeSchema() {
|
||||
|
||||
if (EDGE_SCHEMA == null) {
|
||||
EDGE_SCHEMA = initializeEdgeSchema();
|
||||
}
|
||||
|
||||
return EDGE_SCHEMA;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
|
||||
System.out.println("\n-----------------------------");
|
||||
|
||||
System.out.println("Ego node is "+ this.getEgoNode().getNodeName());
|
||||
|
||||
System.out.println("\nNodes are: ");
|
||||
|
||||
for(CoPINode node : this.getNodes()){
|
||||
System.out.println(node.getNodeName());
|
||||
}
|
||||
|
||||
System.out.println("\nEdges are: ");
|
||||
|
||||
for(CoPIEdge edge : this.getEdges()){
|
||||
System.out.println(edge.getSourceNode() + "-->" + edge.getTargetNode());
|
||||
}
|
||||
|
||||
System.out.println("\n-----------------------------");
|
||||
|
||||
}
|
||||
|
||||
private Set<Map<String, String>> initializeEdgeSchema() {
|
||||
|
||||
Set<Map<String, String>> edgeSchema = new HashSet<Map<String, String>>();
|
||||
|
||||
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "collaborator1");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "collaborator1");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "collaborator2");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "collaborator2");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "number_of_coinvestigated_grants");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "number_of_coinvestigated_grants");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "earliest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "earliest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_earliest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_earliest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "latest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "latest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_latest_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_latest_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_unknown_collaboration");
|
||||
schemaAttributes.put("for", "edge");
|
||||
schemaAttributes.put("attr.name", "num_unknown_collaboration");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
edgeSchema.add(schemaAttributes);
|
||||
|
||||
return edgeSchema;
|
||||
}
|
||||
|
||||
|
||||
private Set<Map<String, String>> initializeNodeSchema() {
|
||||
|
||||
Set<Map<String, String>> nodeSchema = new HashSet<Map<String, String>>();
|
||||
|
||||
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "url");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "url");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "label");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "label");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "profile_url");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "profile_url");
|
||||
schemaAttributes.put("attr.type", "string");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "number_of_investigated_grants");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "number_of_investigated_grants");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "earliest_grant");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "earliest_grant");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_earliest_grant");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_earliest_grant");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "latest_grant");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "latest_grant");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_latest_grant");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_latest_grant");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
schemaAttributes = new LinkedHashMap<String, String>();
|
||||
|
||||
schemaAttributes.put("id", "num_unknown_grant");
|
||||
schemaAttributes.put("for", "node");
|
||||
schemaAttributes.put("attr.name", "num_unknown_grant");
|
||||
schemaAttributes.put("attr.type", "int");
|
||||
|
||||
nodeSchema.add(schemaAttributes);
|
||||
|
||||
|
||||
return nodeSchema;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
* This stores edge information for Co-PI vis.
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class CoPIEdge {
|
||||
|
||||
private int edgeID;
|
||||
private Map<String, Integer> yearToGrantCount;
|
||||
private Set<Grant> collaboratorGrants = new HashSet<Grant>();
|
||||
private CoPINode sourceNode;
|
||||
private CoPINode targetNode;
|
||||
|
||||
public CoPIEdge(CoPINode sourceNode, CoPINode targetNode, Grant seedCoPIedGrant, UniqueIDGenerator uniqueIDGenerator){
|
||||
edgeID = uniqueIDGenerator.getNextNumericID();
|
||||
this.sourceNode = sourceNode;
|
||||
this.targetNode = targetNode;
|
||||
this.collaboratorGrants.add(seedCoPIedGrant);
|
||||
}
|
||||
|
||||
public int getEdgeID() {
|
||||
return edgeID;
|
||||
}
|
||||
public Set<Grant> getCollaboratorGrants() {
|
||||
return collaboratorGrants;
|
||||
}
|
||||
public CoPINode getSourceNode() {
|
||||
return sourceNode;
|
||||
}
|
||||
public CoPINode getTargetNode() {
|
||||
return targetNode;
|
||||
}
|
||||
|
||||
public int getNumberOfCoInvestigatedGrants(){
|
||||
return collaboratorGrants.size();
|
||||
}
|
||||
|
||||
public void addCollaboratorGrant(Grant grant){
|
||||
this.collaboratorGrants.add(grant);
|
||||
}
|
||||
|
||||
/*
|
||||
* getEarliest, Latest & Unknown Grant YearCount should only be used after
|
||||
* the parsing of the entire sparql is done. Else it will give results based on
|
||||
* incomplete dataset.
|
||||
* */
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getEarliestCollaborationYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(collaboratorGrants);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default grant year when we are checking
|
||||
* for the min or max grant year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToGrantCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||
final Integer earliestYearGrantCount = yearToGrantCount.get(earliestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(earliestYear, earliestYearGrantCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getLatestCollaborationYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(collaboratorGrants);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default grant year when we are checking
|
||||
* for the min or max grant year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToGrantCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only grant the PI has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||
final Integer latestYearGrantCount = yearToGrantCount.get(latestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(latestYear, latestYearGrantCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Integer getUnknownCollaborationYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(collaboratorGrants);
|
||||
}
|
||||
|
||||
Integer unknownYearGrantCount = yearToGrantCount
|
||||
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* If there is no unknown year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (unknownYearGrantCount != null) {
|
||||
return unknownYearGrantCount;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
* CoPINode is the node in a CoPI vis.
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class CoPINode extends Individual {
|
||||
|
||||
private int nodeID;
|
||||
private Map<String, Integer> yearToGrantCount;
|
||||
|
||||
private Set<Grant> pIGrants = new HashSet<Grant>();
|
||||
|
||||
public CoPINode(String nodeURI, UniqueIDGenerator uniqueIDGenerator){
|
||||
super(nodeURI);
|
||||
nodeID = uniqueIDGenerator.getNextNumericID();
|
||||
}
|
||||
|
||||
public int getNodeID(){
|
||||
return nodeID;
|
||||
}
|
||||
|
||||
public String getNodeURI(){
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getNodeName(){
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public void setNodeName(String nodeName) {
|
||||
this.setIndividualLabel(nodeName);
|
||||
}
|
||||
|
||||
public Set<Grant> getInvestigatedGrants(){
|
||||
return pIGrants;
|
||||
}
|
||||
|
||||
public int getNumberOfInvestigatedGrants(){
|
||||
return pIGrants.size();
|
||||
}
|
||||
|
||||
public void addGrant(Grant grant){
|
||||
this.pIGrants.add(grant);
|
||||
}
|
||||
|
||||
public Map<String, Integer> getYearToGrantCount(){
|
||||
if(yearToGrantCount == null){
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(pIGrants);
|
||||
}
|
||||
return yearToGrantCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* getEarliest, Latest & Unknown Grant YearCount should only be used after
|
||||
* the parsing of the entire sparql is done. Else it will give results based on
|
||||
* incomplete dataset.
|
||||
* */
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getEarliestGrantYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(pIGrants);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default grant year when we are checking
|
||||
* for the min or max grant year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToGrantCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||
final Integer earliestYearGrantCount = yearToGrantCount.get(earliestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(earliestYear, earliestYearGrantCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getLatestGrantYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(pIGrants);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default grant year when we are checking
|
||||
* for the min or max grant year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToGrantCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only grant the PI has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||
final Integer latestYearGrantCount = yearToGrantCount.get(latestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(latestYear, latestYearGrantCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Integer getUnknownGrantYearCount() {
|
||||
if (yearToGrantCount == null) {
|
||||
yearToGrantCount = UtilityFunctions.getYearToGrantCount(pIGrants);
|
||||
}
|
||||
|
||||
Integer unknownYearGrantCount = yearToGrantCount
|
||||
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* If there is no unknown year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (unknownYearGrantCount != null) {
|
||||
return unknownYearGrantCount;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*
|
||||
*/
|
||||
public class Department extends Individual{
|
||||
|
||||
Set<BiboDocument> publication;
|
||||
Set<Person> person;
|
||||
|
||||
public Department(String departmentURI, String departmentLabel){
|
||||
super(departmentURI, departmentLabel);
|
||||
}
|
||||
|
||||
public void setDepartmentLabel(String departmentURI){
|
||||
this.setIndividualLabel(departmentURI);
|
||||
}
|
||||
|
||||
public String getDepartmentURI(){
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getPublication() {
|
||||
return publication;
|
||||
}
|
||||
|
||||
public String getDepartmentLabel(){
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public Set<Person> getPerson() {
|
||||
return person;
|
||||
}
|
||||
|
||||
public void addPublication(BiboDocument biboDocument) {
|
||||
this.publication.add(biboDocument);
|
||||
}
|
||||
|
||||
public void addPersons(Person person) {
|
||||
this.person.add(person);
|
||||
|
||||
}
|
||||
|
||||
public void addPerson(Person person) {
|
||||
this.person.add(person);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is stores edge information mainly for co-author vis.
|
||||
*
|
||||
* @author cdtank
|
||||
*
|
||||
*/
|
||||
public class Edge {
|
||||
|
||||
private int edgeID;
|
||||
private Map<String, Integer> yearToPublicationCount;
|
||||
private Set<BiboDocument> collaboratorDocuments = new HashSet<BiboDocument>();
|
||||
private Node sourceNode;
|
||||
private Node targetNode;
|
||||
|
||||
public Edge(Node sourceNode, Node targetNode, BiboDocument seedCoAuthoredDocument,
|
||||
UniqueIDGenerator uniqueIDGenerator) {
|
||||
edgeID = uniqueIDGenerator.getNextNumericID();
|
||||
this.sourceNode = sourceNode;
|
||||
this.targetNode = targetNode;
|
||||
this.collaboratorDocuments.add(seedCoAuthoredDocument);
|
||||
}
|
||||
|
||||
public int getEdgeID() {
|
||||
return edgeID;
|
||||
}
|
||||
|
||||
public Node getSourceNode() {
|
||||
return sourceNode;
|
||||
}
|
||||
|
||||
public Node getTargetNode() {
|
||||
return targetNode;
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getCollaboratorDocuments() {
|
||||
return collaboratorDocuments;
|
||||
}
|
||||
|
||||
public int getNumOfCoAuthoredWorks() {
|
||||
return collaboratorDocuments.size();
|
||||
}
|
||||
|
||||
public void addCollaboratorDocument(BiboDocument authorDocument) {
|
||||
this.collaboratorDocuments.add(authorDocument);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* incomplete dataset.
|
||||
* */
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getEarliestCollaborationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions
|
||||
.getYearToPublicationCount(collaboratorDocuments);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default publication year when we are checking
|
||||
* for the min or max publication year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||
final Integer earliestYearPubCount = yearToPublicationCount.get(earliestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(earliestYear, earliestYearPubCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getLatestCollaborationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions
|
||||
.getYearToPublicationCount(collaboratorDocuments);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default publication year when we are checking
|
||||
* for the min or max publication year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||
final Integer latestYearPubCount = yearToPublicationCount.get(latestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(latestYear, latestYearPubCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getUnknownCollaborationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions
|
||||
.getYearToPublicationCount(collaboratorDocuments);
|
||||
}
|
||||
|
||||
Integer unknownYearPubCount = yearToPublicationCount
|
||||
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* If there is no unknown year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (unknownYearPubCount != null) {
|
||||
return unknownYearPubCount;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*
|
||||
*/
|
||||
public class Entity extends Individual{
|
||||
|
||||
Set<BiboDocument> publications = new HashSet<BiboDocument>();
|
||||
Set<SubEntity> children = new LinkedHashSet<SubEntity>();
|
||||
|
||||
public Entity(String departmentURI, String departmentLabel){
|
||||
super(departmentURI, departmentLabel);
|
||||
}
|
||||
|
||||
public void setDepartmentLabel(String departmentURI){
|
||||
this.setIndividualLabel(departmentURI);
|
||||
}
|
||||
|
||||
public String getEntityURI(){
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getPublications() {
|
||||
return publications;
|
||||
}
|
||||
|
||||
public String getEntityLabel(){
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public Set<SubEntity> getSubEntities() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void addPublications(BiboDocument biboDocument) {
|
||||
this.publications.add(biboDocument);
|
||||
}
|
||||
|
||||
public void addSubEntity(SubEntity subEntity) {
|
||||
this.children.add(subEntity);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class GenericQueryMap extends HashMap<String, Set<String>> {
|
||||
|
||||
public GenericQueryMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void addEntry(String property, String value) {
|
||||
|
||||
Set<String> values;
|
||||
|
||||
if (this.containsKey(property)) {
|
||||
|
||||
values = this.get(property);
|
||||
values.add(value);
|
||||
|
||||
} else {
|
||||
|
||||
values = new HashSet<String>();
|
||||
values.add(value);
|
||||
this.put(property, values);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*
|
||||
*/
|
||||
|
||||
public class Grant extends Individual {
|
||||
|
||||
private String grantStartYear;
|
||||
private String grantStartYearMonth;
|
||||
private String grantStartDate;
|
||||
private String grantEndYear;
|
||||
private String grantEndYearMonth;
|
||||
private String grantEndDate;
|
||||
|
||||
public Grant(String grantURL, String grantLabel){
|
||||
super(grantURL, grantLabel);
|
||||
}
|
||||
|
||||
public Grant(String grantURL){
|
||||
super(grantURL);
|
||||
}
|
||||
|
||||
public String getGrantURL() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getGrantLabel(){
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
/**
|
||||
* This method will be called when there is no usable core:year value found
|
||||
* for the bibo:Document. It will first check & parse core:yearMonth failing
|
||||
* which it will try core:date
|
||||
* @return
|
||||
*/
|
||||
public String getParsedGrantStartYear() {
|
||||
|
||||
/*
|
||||
* We are assuming that core:yearMonth has "YYYY-MM-DD" format. This is based
|
||||
* off of http://www.w3.org/TR/xmlschema-2/#gYearMonth , which is what
|
||||
* core:yearMonth points to internally.
|
||||
* */
|
||||
if (grantStartYearMonth != null
|
||||
&& grantStartYearMonth.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& isValidPublicationYear(grantStartYearMonth.substring(
|
||||
0,
|
||||
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
|
||||
|
||||
return grantStartYearMonth.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
|
||||
|
||||
}
|
||||
|
||||
if (grantStartDate != null
|
||||
&& grantStartDate.length() >= VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& isValidPublicationYear(grantStartDate
|
||||
.substring(0,
|
||||
VOConstants.NUM_CHARS_IN_YEAR_FORMAT))) {
|
||||
|
||||
return grantStartDate.substring(0, VOConstants.NUM_CHARS_IN_YEAR_FORMAT);
|
||||
}
|
||||
|
||||
/*
|
||||
* If all else fails return default unknown year identifier
|
||||
* */
|
||||
return VOConstants.DEFAULT_GRANT_YEAR;
|
||||
}
|
||||
|
||||
public String getGrantStartYear() {
|
||||
return grantStartYear;
|
||||
}
|
||||
|
||||
public void setGrantStartYear(String grantStartYear) {
|
||||
this.grantStartYear = grantStartYear;
|
||||
}
|
||||
|
||||
public String getGrantStartYearMonth() {
|
||||
return grantStartYearMonth;
|
||||
}
|
||||
|
||||
public void setGrantStartYearMonth(String grantStartYearMonth) {
|
||||
this.grantStartYearMonth = grantStartYearMonth;
|
||||
}
|
||||
|
||||
public String getGrantStartDate() {
|
||||
return grantStartDate;
|
||||
}
|
||||
|
||||
public void setGrantStartDate(String grantStartDate) {
|
||||
this.grantStartDate = grantStartDate;
|
||||
}
|
||||
|
||||
public String getGrantEndYear() {
|
||||
return grantEndYear;
|
||||
}
|
||||
|
||||
public void setGrantEndYear(String grantEndYear) {
|
||||
this.grantEndYear = grantEndYear;
|
||||
}
|
||||
|
||||
public String getGrantEndYearMonth() {
|
||||
return grantEndYearMonth;
|
||||
}
|
||||
|
||||
public void setGrantEndYearMonth(String grantEndYearMonth) {
|
||||
this.grantEndYearMonth = grantEndYearMonth;
|
||||
}
|
||||
|
||||
public String getGrantEndDate() {
|
||||
return grantEndDate;
|
||||
}
|
||||
|
||||
public void setGrantEndDate(String grantEndDate) {
|
||||
this.grantEndDate = grantEndDate;
|
||||
}
|
||||
|
||||
private boolean isValidPublicationYear(String testGrantYear) {
|
||||
|
||||
if (testGrantYear.length() != 0
|
||||
&& testGrantYear.trim().length() == VOConstants.NUM_CHARS_IN_YEAR_FORMAT
|
||||
&& testGrantYear.matches("\\d+")
|
||||
&& Integer.parseInt(testGrantYear) >= VOConstants.MINIMUM_PUBLICATION_YEAR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
public class Individual {
|
||||
|
||||
private String individualLabel;
|
||||
private String individualURI;
|
||||
|
||||
public Individual(String individualURI, String individualLabel) {
|
||||
this.individualURI = individualURI;
|
||||
this.individualLabel = individualLabel;
|
||||
}
|
||||
|
||||
public Individual(String individualURI) {
|
||||
this(individualURI, "");
|
||||
}
|
||||
|
||||
public String getIndividualLabel() {
|
||||
return individualLabel;
|
||||
}
|
||||
|
||||
public void setIndividualLabel(String individualLabel) {
|
||||
this.individualLabel = individualLabel;
|
||||
}
|
||||
|
||||
public String getIndividualURI() {
|
||||
return individualURI;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JsonObject is used for creating data in JSON format,
|
||||
* by just using the fields that are required to be included.
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class JsonObject {
|
||||
|
||||
private String label;
|
||||
private List<List<Integer>> data = new ArrayList<List<Integer>>();
|
||||
private String entityURI;
|
||||
private String visMode;
|
||||
private List<String> organizationType = new ArrayList<String>();
|
||||
private List<String> stopWords = new ArrayList<String>();
|
||||
|
||||
public List<String> getStopWords() {
|
||||
return stopWords;
|
||||
}
|
||||
|
||||
public void setStopWords(List<String> stopWords) {
|
||||
this.stopWords = stopWords;
|
||||
}
|
||||
|
||||
public List<String> getOrganizationType() {
|
||||
return organizationType;
|
||||
}
|
||||
|
||||
public void setOrganizationType(List<String> organizationType) {
|
||||
this.organizationType = organizationType;
|
||||
}
|
||||
|
||||
public String getEntityURI() {
|
||||
return entityURI;
|
||||
}
|
||||
|
||||
public void setEntityURI(String entityURI) {
|
||||
this.entityURI = entityURI;
|
||||
}
|
||||
|
||||
public String getVisMode() {
|
||||
return visMode;
|
||||
}
|
||||
|
||||
public void setVisMode(String visMode) {
|
||||
this.visMode = visMode;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public List<List<Integer>> getYearToPublicationCount() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public JsonObject(String label){
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public void setYearToPublicationCount(List<List<Integer>> yearToPublicationCount){
|
||||
this.data = yearToPublicationCount;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
*
|
||||
* This stores node information mainly for co-author vis.
|
||||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
public class Node extends Individual {
|
||||
|
||||
private int nodeID;
|
||||
private Map<String, Integer> yearToPublicationCount;
|
||||
|
||||
private Set<BiboDocument> authorDocuments = new HashSet<BiboDocument>();
|
||||
|
||||
public Node(String nodeURI,
|
||||
UniqueIDGenerator uniqueIDGenerator) {
|
||||
super(nodeURI);
|
||||
nodeID = uniqueIDGenerator.getNextNumericID();
|
||||
}
|
||||
|
||||
public int getNodeID() {
|
||||
return nodeID;
|
||||
}
|
||||
|
||||
public String getNodeURI() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getNodeName() {
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public void setNodeName(String nodeName) {
|
||||
this.setIndividualLabel(nodeName);
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getAuthorDocuments() {
|
||||
return authorDocuments;
|
||||
}
|
||||
|
||||
public int getNumOfAuthoredWorks() {
|
||||
return authorDocuments.size();
|
||||
}
|
||||
|
||||
public void addAuthorDocument(BiboDocument authorDocument) {
|
||||
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
|
||||
* incomplete dataset.
|
||||
* */
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getEarliestPublicationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default publication year when we are checking
|
||||
* for the min or max publication year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||
final Integer earliestYearPubCount = yearToPublicationCount.get(earliestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(earliestYear, earliestYearPubCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public Map<String, Integer> getLatestPublicationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to consider the default publication year when we are checking
|
||||
* for the min or max publication year.
|
||||
* */
|
||||
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* There can be a case when the only publication the author has no attached year to it
|
||||
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||
* NoSuchElementException.
|
||||
*
|
||||
* If there is no maximum year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (yearsToBeConsidered.size() > 0) {
|
||||
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||
final Integer latestYearPubCount = yearToPublicationCount.get(latestYear);
|
||||
|
||||
return new HashMap<String, Integer>() { {
|
||||
put(latestYear, latestYearPubCount);
|
||||
} };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Integer getUnknownPublicationYearCount() {
|
||||
if (yearToPublicationCount == null) {
|
||||
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||
}
|
||||
|
||||
Integer unknownYearPubCount = yearToPublicationCount
|
||||
.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
/*
|
||||
* If there is no unknown year available then we should imply so by returning a "null".
|
||||
* */
|
||||
if (unknownYearPubCount != null) {
|
||||
return unknownYearPubCount;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class Person extends Individual {
|
||||
|
||||
Set<BiboDocument> documents = new HashSet<BiboDocument>();
|
||||
|
||||
public Person(String individualURI) {
|
||||
super(individualURI);
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getDocuments() {
|
||||
return documents;
|
||||
}
|
||||
|
||||
public Person(String individualURI, String individualLabel) {
|
||||
super(individualURI, individualLabel);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SparklineData {
|
||||
|
||||
/*
|
||||
* For now sparklineNumPublicationsText & sparklinePublicationRangeText is left
|
||||
* as empty but later on we would want to leverage the granularity that this
|
||||
* provides.
|
||||
* */
|
||||
private String sparklineNumPublicationsText = "";
|
||||
private String sparklinePublicationRangeText = "";
|
||||
|
||||
private Integer earliestYearConsidered;
|
||||
private Integer earliestRenderedPublicationYear;
|
||||
private Integer latestRenderedPublicationYear;
|
||||
|
||||
private Integer renderedSparks;
|
||||
private Integer unknownYearPublications;
|
||||
|
||||
private Map<String, Integer> yearToActivityCount;
|
||||
|
||||
private String table = "";
|
||||
|
||||
private String downloadDataLink = "";
|
||||
private String fullTimelineNetworkLink = "";
|
||||
|
||||
private String visContainerDivID = "pub_count_vis_container";
|
||||
private String sparklineContent;
|
||||
private String sparklineContext;
|
||||
|
||||
private boolean isShortVisMode = true;
|
||||
|
||||
private List<YearPublicationCountDataElement> yearToPublicationCountDataTable;
|
||||
|
||||
private int numOfYearsToBeRendered;
|
||||
|
||||
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 void setNumOfYearsToBeRendered(int numOfYearsToBeRendered) {
|
||||
this.numOfYearsToBeRendered = numOfYearsToBeRendered;
|
||||
}
|
||||
|
||||
public int getNumOfYearsToBeRendered() {
|
||||
return numOfYearsToBeRendered;
|
||||
}
|
||||
|
||||
public void setYearToPublicationCountDataTable(
|
||||
List<YearPublicationCountDataElement> yearToPublicationCountDataTable) {
|
||||
this.yearToPublicationCountDataTable = yearToPublicationCountDataTable;
|
||||
}
|
||||
|
||||
public List<YearPublicationCountDataElement> getYearToPublicationCountDataTable() {
|
||||
return yearToPublicationCountDataTable;
|
||||
}
|
||||
|
||||
public void setYearToActivityCount(Map<String, Integer> yearToActivityCount) {
|
||||
this.yearToActivityCount = yearToActivityCount;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getYearToActivityCount() {
|
||||
return yearToActivityCount;
|
||||
}
|
||||
|
||||
public void setEarliestYearConsidered(Integer earliestYearConsidered) {
|
||||
this.earliestYearConsidered = earliestYearConsidered;
|
||||
}
|
||||
|
||||
public Integer getEarliestYearConsidered() {
|
||||
return earliestYearConsidered;
|
||||
}
|
||||
|
||||
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 void setUnknownYearPublications(Integer unknownYearPublications) {
|
||||
this.unknownYearPublications = unknownYearPublications;
|
||||
}
|
||||
|
||||
public Integer getUnknownYearPublications() {
|
||||
return unknownYearPublications;
|
||||
}
|
||||
|
||||
public void setRenderedSparks(Integer renderedSparks) {
|
||||
this.renderedSparks = renderedSparks;
|
||||
}
|
||||
|
||||
public Integer getRenderedSparks() {
|
||||
return renderedSparks;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void setVisContainerDivID(String visContainerDivID) {
|
||||
this.visContainerDivID = visContainerDivID;
|
||||
}
|
||||
|
||||
public String getVisContainerDivID() {
|
||||
return visContainerDivID;
|
||||
}
|
||||
|
||||
public String getSparklineContent() {
|
||||
return sparklineContent;
|
||||
}
|
||||
|
||||
public void setSparklineContent(String shortSparklineContent) {
|
||||
this.sparklineContent = shortSparklineContent;
|
||||
}
|
||||
|
||||
public void setShortVisMode(boolean isShortVisMode) {
|
||||
this.isShortVisMode = isShortVisMode;
|
||||
}
|
||||
|
||||
public boolean isShortVisMode() {
|
||||
return isShortVisMode;
|
||||
}
|
||||
|
||||
public String getSparklineContext() {
|
||||
return sparklineContext;
|
||||
}
|
||||
|
||||
public void setSparklineContext(String shortSparklineContext) {
|
||||
this.sparklineContext = shortSparklineContext;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author bkoniden
|
||||
* Deepak Konidena
|
||||
*/
|
||||
public class SubEntity extends Individual {
|
||||
|
||||
Set<BiboDocument> publications = new HashSet<BiboDocument>();
|
||||
Map<String, Map<String, String>> personToPositionAndStartYear = new HashMap<String, Map<String, String>>();
|
||||
|
||||
public SubEntity(String individualURI) {
|
||||
super(individualURI);
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Map<String, String>> getPersonToPositionAndStartYear() {
|
||||
return personToPositionAndStartYear;
|
||||
}
|
||||
|
||||
public void setPersonToPositionAndStartYear(
|
||||
Map<String, Map<String, String>> personToPositionAndStartYear) {
|
||||
this.personToPositionAndStartYear = personToPositionAndStartYear;
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getDocuments() {
|
||||
return publications;
|
||||
}
|
||||
|
||||
public SubEntity(String individualURI, String individualLabel) {
|
||||
super(individualURI, individualLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other){
|
||||
boolean result = false;
|
||||
if (other instanceof SubEntity){
|
||||
SubEntity person = (SubEntity) other;
|
||||
result = (this.getIndividualLabel().equals(person.getIndividualLabel())
|
||||
&& this.getIndividualURI().equals(person.getIndividualURI()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return(41*(getIndividualLabel().hashCode() + 41*(getIndividualURI().hashCode())));
|
||||
}
|
||||
|
||||
public void addPublications(BiboDocument biboDocument) {
|
||||
this.publications.add(biboDocument);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects;
|
||||
|
||||
/**
|
||||
* This object is used to store information about the yearToPublicationCount Map in the format
|
||||
* easily expressed to Google Visualization's DataTableAPI.
|
||||
* @author cdtank
|
||||
*
|
||||
*/
|
||||
public class YearPublicationCountDataElement {
|
||||
|
||||
private int publicationCounter;
|
||||
private String publishedYear;
|
||||
private int currentPublications;
|
||||
|
||||
public YearPublicationCountDataElement(int publicationCounter,
|
||||
String publishedYear, int currentPublications) {
|
||||
this.publicationCounter = publicationCounter;
|
||||
this.publishedYear = publishedYear;
|
||||
this.currentPublications = currentPublications;
|
||||
}
|
||||
|
||||
public int getPublicationCounter() {
|
||||
return publicationCounter;
|
||||
}
|
||||
|
||||
public String getPublishedYear() {
|
||||
return publishedYear;
|
||||
}
|
||||
|
||||
public int getCurrentPublications() {
|
||||
return currentPublications;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils;
|
||||
|
||||
public class UniqueIDGenerator {
|
||||
|
||||
private int nextNumericID = 1;
|
||||
|
||||
public int getNextNumericID() {
|
||||
int nextNumericID = this.nextNumericID;
|
||||
this.nextNumericID++;
|
||||
|
||||
return nextNumericID;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoAuthorshipData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.freemarker.valueobjects.Node;
|
||||
|
||||
public class UtilityFunctions {
|
||||
|
||||
public static Map<String, Integer> getYearToPublicationCount(
|
||||
Set<BiboDocument> authorDocuments) {
|
||||
|
||||
/*
|
||||
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||
* parsedPublicationYear to populate the data.
|
||||
* */
|
||||
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||
|
||||
for (BiboDocument curr : authorDocuments) {
|
||||
|
||||
/*
|
||||
* Increment the count because there is an entry already available for
|
||||
* that particular year.
|
||||
*
|
||||
* 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.
|
||||
* 3. We are asking for a publication year & we should get a proper one or NOT at all.
|
||||
* */
|
||||
String publicationYear;
|
||||
if (curr.getPublicationYear() != null) {
|
||||
publicationYear = curr.getPublicationYear();
|
||||
} else {
|
||||
publicationYear = curr.getParsedPublicationYear();
|
||||
}
|
||||
|
||||
if (yearToPublicationCount.containsKey(publicationYear)) {
|
||||
yearToPublicationCount.put(publicationYear,
|
||||
yearToPublicationCount
|
||||
.get(publicationYear) + 1);
|
||||
|
||||
} else {
|
||||
yearToPublicationCount.put(publicationYear, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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.
|
||||
* @param textToBeSlugified
|
||||
* @return
|
||||
*/
|
||||
public static String slugify(String textToBeSlugified) {
|
||||
String textBlockSeparator = "-";
|
||||
return StringUtils.removeEnd(StringUtils.substring(textToBeSlugified.toLowerCase().trim()
|
||||
.replaceAll("[^a-zA-Z0-9-]+", textBlockSeparator),
|
||||
0,
|
||||
VisConstants.MAX_NAME_TEXT_LENGTH),
|
||||
textBlockSeparator);
|
||||
}
|
||||
|
||||
|
||||
public static ResponseValues handleMalformedParameters(String errorPageTitle, String errorMessage, VitroRequest vitroRequest) {
|
||||
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
body.put("portalBean", portal);
|
||||
body.put("error", errorMessage);
|
||||
body.put("title", errorPageTitle);
|
||||
|
||||
return new TemplateResponseValues(VisualizationFrameworkConstants.ERROR_TEMPLATE, body);
|
||||
}
|
||||
|
||||
/* 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());
|
||||
}
|
||||
}*/
|
||||
|
||||
public static Map<String, Set<CoPINode>> getGrantYearToCoPI(
|
||||
CoPIData pINodesAndEdges) {
|
||||
|
||||
|
||||
Map<String, Set<CoPINode>> yearToCoPIs = new TreeMap<String, Set<CoPINode>>();
|
||||
|
||||
CoPINode egoNode = pINodesAndEdges.getEgoNode();
|
||||
|
||||
for (CoPINode currNode : pINodesAndEdges.getNodes()) {
|
||||
|
||||
/*
|
||||
* We have already printed the Ego Node info.
|
||||
* */
|
||||
if (currNode != egoNode) {
|
||||
|
||||
for (String year : currNode.getYearToGrantCount().keySet()) {
|
||||
|
||||
Set<CoPINode> coPINodes;
|
||||
|
||||
if (yearToCoPIs.containsKey(year)) {
|
||||
|
||||
coPINodes = yearToCoPIs.get(year);
|
||||
coPINodes.add(currNode);
|
||||
|
||||
} else {
|
||||
|
||||
coPINodes = new HashSet<CoPINode>();
|
||||
coPINodes.add(currNode);
|
||||
yearToCoPIs.put(year, coPINodes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return yearToCoPIs;
|
||||
|
||||
}
|
||||
|
||||
public static Map<String, Integer> getYearToGrantCount(Set<Grant> pIGrants) {
|
||||
|
||||
/*
|
||||
* Create a map from the year to number of grants. Use the Grant's
|
||||
* parsedGrantStartYear to populate the data.
|
||||
* */
|
||||
Map<String, Integer> yearToGrantCount = new TreeMap<String, Integer>();
|
||||
|
||||
for (Grant curr : pIGrants) {
|
||||
|
||||
/*
|
||||
* Increment the count because there is an entry already available for
|
||||
* that particular year.
|
||||
*
|
||||
* I am pushing the logic to check for validity of year in "getGrantYear" itself
|
||||
* because,
|
||||
* 1. We will be using getGra... multiple times & this will save us duplication of code
|
||||
* 2. If we change the logic of validity of a grant year we would not have to make
|
||||
* changes all throughout the codebase.
|
||||
* 3. We are asking for a grant year & we should get a proper one or NOT at all.
|
||||
* */
|
||||
String grantYear;
|
||||
if (curr.getGrantStartYear() != null) {
|
||||
grantYear = curr.getGrantStartYear();
|
||||
} else {
|
||||
grantYear = curr.getParsedGrantStartYear();
|
||||
}
|
||||
|
||||
if (yearToGrantCount.containsKey(grantYear)) {
|
||||
yearToGrantCount.put(grantYear,
|
||||
yearToGrantCount
|
||||
.get(grantYear) + 1);
|
||||
|
||||
} else {
|
||||
yearToGrantCount.put(grantYear, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return yearToGrantCount;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker.visutils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
|
||||
/**
|
||||
* 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{
|
||||
|
||||
ResponseValues generateVisualization(VitroRequest vitroRequest,
|
||||
Log log,
|
||||
DataSource dataSource);
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue