re-integrating the branch /branches/iu-vis-dev-branches/vivo-post-1.1
This commit is contained in:
parent
3488c43f55
commit
67d14f3212
49 changed files with 4796 additions and 921 deletions
77
deploy.properties
Normal file
77
deploy.properties
Normal file
|
@ -0,0 +1,77 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# VIVO deployment properties
|
||||
#
|
||||
# This file is provided as example.deploy.properties.
|
||||
#
|
||||
# Save a copy of this file as deploy.properties, and edit the properties as
|
||||
# needed for your deployment.
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# This namespace will be used when generating URIs for objects created in the
|
||||
# editor. Change it to reflect your own domain. For example, Cornell's
|
||||
# namespace is http://vivo.cornell.edu/individual/
|
||||
#
|
||||
# Note: it is essential that this namespace end with a trailing slash.
|
||||
#
|
||||
Vitro.defaultNamespace = http://vivo-trunk.indiana.edu/individual/
|
||||
|
||||
#
|
||||
# Where is the Vitro core directory?
|
||||
# In most deployments, this is set to ./vitro-core, but internal developers may
|
||||
# prefer to set it to ../vitro
|
||||
# Examples:
|
||||
# vitro.core.dir = ./vitro-core
|
||||
# vitro.core.dir = ../vitro
|
||||
# vitro.core.dir = /usr/local/vitro/trunk
|
||||
vitro.core.dir = /usr/local/home/bkoniden/eclipse-workspace/bkoniden-vitro-post-1.1
|
||||
|
||||
#
|
||||
# The base install directory for your Tomcat server. The VIVO application
|
||||
# will be deployed in the /webapps directory below this base.
|
||||
#
|
||||
tomcat.home = /usr/local/tomcat
|
||||
|
||||
#
|
||||
# The name of the VIVO application. This will be used as the name of the
|
||||
# subdirectory within your Tomcat server's /webapps directory. It also appears
|
||||
# in the URL for the application. For example, http://my.vivo.server/vivo
|
||||
#
|
||||
webapp.name = vivo1
|
||||
|
||||
#
|
||||
# The location where the VIVO application will store uploaded files
|
||||
# (usually images). You should arrange for these files to be backed up in some
|
||||
# way.
|
||||
#
|
||||
upload.directory = /usr/local/vivo1/data-vivo-updated/uploads
|
||||
|
||||
#
|
||||
# The location where the VIVO application will create its Lucene search
|
||||
# index.
|
||||
#
|
||||
LuceneSetup.indexDir = /usr/local/vivo1/data-vivo-updated/luceneIndex
|
||||
|
||||
#
|
||||
# SMTP host which the "Contact Us" form can use to send mail. If this is left
|
||||
# empty, the "Contact Us" form will be disabled.
|
||||
#
|
||||
Vitro.smtpHost =
|
||||
|
||||
#
|
||||
# The basic parameters for a MySQL database connection. Change the end of the
|
||||
# URL to reflect your database name (if it is not "vitro"). Change the username
|
||||
# and password to match the authorized user you created in MySQL.
|
||||
#
|
||||
VitroConnection.DataSource.url = jdbc:mysql://localhost/vivo1
|
||||
VitroConnection.DataSource.username = vivouser1
|
||||
VitroConnection.DataSource.password = vivo123
|
||||
|
||||
#
|
||||
# The name of your first admin user for the VIVO application. The password for
|
||||
# for this user is initially set to "defaultAdmin", but you will be asked to
|
||||
# change the password the first time you login.
|
||||
#
|
||||
initialAdminUser = defaultAdmin
|
2
deployVIVOInstance
Executable file
2
deployVIVOInstance
Executable file
|
@ -0,0 +1,2 @@
|
|||
sudo /usr/local/tomcat/bin/shutdown.sh
|
||||
ant clean deploy
|
|
@ -1,6 +1,5 @@
|
|||
<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: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
|
||||
|
@ -10,21 +9,31 @@
|
|||
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
|
||||
<bean id="person_pub_count" class="edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.PersonPublicationCountRequestHandler" />
|
||||
<bean id="college_pub_count" class="edu.cornell.mannlib.vitro.webapp.visualization.collegepubcount.CollegePublicationCountRequestHandler" />
|
||||
<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="person_pub_count"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.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="freemarker"
|
||||
class="edu.cornell.mannlib.vitro.webapp.visualization.freemarker.FreemarkerRequestHandler" />
|
||||
|
||||
<bean id="visualizationInjector" class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector">
|
||||
|
||||
|
||||
|
||||
<bean id="visualizationInjector"
|
||||
class="edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationInjector">
|
||||
<property name="visualizations">
|
||||
<map>
|
||||
<entry key="person_pub_count">
|
||||
<ref bean="person_pub_count"></ref>
|
||||
</entry>
|
||||
<entry key="college_pub_count">
|
||||
<ref bean="college_pub_count"></ref>
|
||||
</entry>
|
||||
<entry key="coauthorship">
|
||||
<ref bean="coauthorship"></ref>
|
||||
</entry>
|
||||
|
@ -34,9 +43,18 @@
|
|||
<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>
|
||||
<entry key="freemarker">
|
||||
<ref bean="freemarker"></ref>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
|
||||
</bean>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -1221,7 +1221,6 @@
|
|||
<url-pattern>/admin/sparqlquery</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
<servlet>
|
||||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.DummyVisClientController</servlet-class>
|
||||
|
@ -1231,7 +1230,8 @@
|
|||
<servlet-name>DummyVisClient</servlet-name>
|
||||
<url-pattern>/admin/dummyVisClient</url-pattern>
|
||||
</servlet-mapping>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>VisualizationController</servlet-name>
|
||||
|
|
75
productMods/js/visualization/entityComparison/constants.js
Normal file
75
productMods/js/visualization/entityComparison/constants.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
//Hard coded color constants
|
||||
var TURQUOISE = "#8DD3C7";
|
||||
var LIGHT_YELLOW = "#FFFFB3";
|
||||
var LIGHT_VIOLET = "#BEBADA";
|
||||
var LIGHT_RED = "#FB8072";
|
||||
var SKY_BLUE = "#80B1D3";
|
||||
var ORANGE = "#FDB462";
|
||||
var LIGHT_GREEN = "#B3DE69";
|
||||
var LIGHT_PINK = "#FCCDE5";
|
||||
var LIGHT_GREY = "#D9D9D9";
|
||||
var PURPLE = "#BC80BD";
|
||||
|
||||
var colorConstantQueue =
|
||||
[
|
||||
TURQUOISE, LIGHT_YELLOW, LIGHT_VIOLET, LIGHT_RED,
|
||||
SKY_BLUE, ORANGE, LIGHT_GREEN, LIGHT_PINK, LIGHT_GREY,
|
||||
PURPLE
|
||||
];
|
||||
|
||||
var freeColors = [
|
||||
TURQUOISE, LIGHT_YELLOW, LIGHT_VIOLET, LIGHT_RED,
|
||||
SKY_BLUE, ORANGE, LIGHT_GREEN, LIGHT_PINK, LIGHT_GREY,
|
||||
PURPLE
|
||||
];
|
||||
|
||||
var year = {
|
||||
min: 1998,
|
||||
max: 2018,
|
||||
globalMin: 1995,
|
||||
globalMax: 2025
|
||||
};
|
||||
|
||||
var colors = {};
|
||||
var prevColor = {};
|
||||
var colorToAssign, colorToRemove;
|
||||
var renderedObjects = [];
|
||||
var labelToEntityRecord = {};
|
||||
var setOfLabels = [];
|
||||
var labelToCheckedEntities = {};
|
||||
var stopWordsToCount = {};
|
||||
|
||||
var graphContainer;
|
||||
var tableDiv;
|
||||
var entityLevel;
|
||||
|
||||
//options for Flot
|
||||
var FlotOptions = {
|
||||
legend : {
|
||||
show : false
|
||||
},
|
||||
lines : {
|
||||
show : true
|
||||
},
|
||||
points : {
|
||||
show : false
|
||||
},
|
||||
xaxis : {
|
||||
tickDecimals : 0,
|
||||
tickSize : 10
|
||||
},
|
||||
series : {
|
||||
lines : {
|
||||
lineWidth : 7
|
||||
}
|
||||
},
|
||||
yaxis : {
|
||||
tickSize : 1,
|
||||
tickDecimals : 0,
|
||||
min : 0
|
||||
}
|
||||
};
|
||||
|
||||
FlotOptions.colors = colorConstantQueue;
|
||||
|
1032
productMods/js/visualization/entityComparison/util.js
Normal file
1032
productMods/js/visualization/entityComparison/util.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -256,6 +256,7 @@ function createTable(tableID, tableContainer, tableData) {
|
|||
$('#' + tableContainer + " #loadingData").remove();
|
||||
}
|
||||
|
||||
//renderStatsOnNodeClicked, CoRelations, noOfCoRelations
|
||||
function nodeClickedJS(json){
|
||||
|
||||
var obj = jQuery.parseJSON(json);
|
||||
|
@ -309,6 +310,11 @@ function nodeClickedJS(json){
|
|||
|
||||
}
|
||||
|
||||
function encodeURL(url){
|
||||
var domainURL = 'http://vivo-vis-bkoniden.slis.indiana.edu/';
|
||||
return domainURL + url.replace(/&/g,'%26');
|
||||
}
|
||||
|
||||
function renderCoAuthorshipVisualization() {
|
||||
|
||||
// Version check for the Flash Player that has the ability to start Player
|
||||
|
@ -330,13 +336,13 @@ function renderCoAuthorshipVisualization() {
|
|||
AC_FL_RunContent(
|
||||
"src", "playerProductInstall",
|
||||
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
|
||||
"width", "600",
|
||||
"width", "800",
|
||||
"height", "840",
|
||||
"align", "middle",
|
||||
"id", "CoAuthor",
|
||||
"id", "EgoCentric",
|
||||
"quality", "high",
|
||||
"bgcolor", "#ffffff",
|
||||
"name", "CoAuthor",
|
||||
"name", "EgoCentric",
|
||||
"allowScriptAccess","sameDomain",
|
||||
"type", "application/x-shockwave-flash",
|
||||
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||
|
@ -344,16 +350,17 @@ function renderCoAuthorshipVisualization() {
|
|||
} else if (hasRequestedVersion) {
|
||||
// if we've detected an acceptable version
|
||||
// embed the Flash Content SWF when all tests are passed
|
||||
//coAuthorUrl=/vivo1/visualization?vis=coauthorship%26render_mode=data%26uri=http%3A%2F%2Fvivo.iu.edu%2Findividual%2FBrnerKaty&labelField=label&coPIUrl=/vivo1/visualization?vis=coprincipalinvestigator%26render_mode=data%26uri=http%3A%2F%2Fvivo.iu.edu%2Findividual%2FBrnerKaty&labelField=label
|
||||
AC_FL_RunContent(
|
||||
"src", swfLink,
|
||||
"flashVars", "graphmlUrl=" + egoCoAuthorshipDataFeederURL,
|
||||
"width", "600",
|
||||
"flashVars", 'coAuthorUrl='+ encodeURL(egoCoAuthorshipDataFeederURL) + '&coPIUrl=' + encodeURL(egoCoPIDataFeederURL) ,
|
||||
"width", "800",
|
||||
"height", "850",
|
||||
"align", "top",
|
||||
"id", "CoAuthor",
|
||||
"id", "EgoCentric",
|
||||
"quality", "high",
|
||||
"bgcolor", "#ffffff",
|
||||
"name", "CoAuthor",
|
||||
"name", "EgoCentric",
|
||||
"allowScriptAccess","sameDomain",
|
||||
"type", "application/x-shockwave-flash",
|
||||
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5611"/>
|
||||
</c:url>
|
||||
|
||||
|
||||
<c:url var="staticHref3" value="/visualization">
|
||||
<c:param name="vis" value="person_pub_count"/>
|
||||
<c:param name="vis_mode" value="short"/>
|
||||
|
@ -204,13 +203,13 @@
|
|||
<c:url var="coAuthorship10" value="/visualization">
|
||||
<c:param name="vis" value="coauthorship"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual12053"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/BrnerKaty"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="coAuthorship10Data" value="/visualization">
|
||||
<c:param name="vis" value="coauthorship"/>
|
||||
<c:param name="render_mode" value="data"/>
|
||||
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual12053"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/BrnerKaty"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="coAuthorshipSparklineData" value="/visualization">
|
||||
|
@ -229,6 +228,61 @@
|
|||
|
||||
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||
|
||||
<c:url var="departmentPublications" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="vis_mode" value="DEPARTMENT"/>
|
||||
<c:param name="uri" value="http://vivo-trunk.indiana.edu/individual/DepartmentBL-SLIS"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="schoolPublications" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="vis_mode" value="SCHOOL"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/SchoolofLibraryandInformationScience"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="universityPublications" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="vis_mode" value="UNIVERSITY"/>
|
||||
<c:param name="uri" value="http://vivo-trunk.indiana.edu/individual/n7971"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="departmentPublicationsdata" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="data"/>
|
||||
<c:param name="vis_mode" value="DEPARTMENT"/>
|
||||
<c:param name="uri" value="http://vivo-trunk.indiana.edu/individual/DepartmentBL-SLIS"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="schoolPublicationsdata" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="data"/>
|
||||
<c:param name="vis_mode" value="SCHOOL"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/SchoolofLibraryandInformationScience"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="universityPublicationsdata" value="/visualization">
|
||||
<c:param name="vis" value="entity_comparison"/>
|
||||
<c:param name="render_mode" value="data"/>
|
||||
<c:param name="vis_mode" value="UNIVERSITY"/>
|
||||
<c:param name="uri" value="http://vivo-trunk.indiana.edu/individual/n7971"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="coprincipalinvestigatordata" value="/visualization">
|
||||
<c:param name="vis" value="coprincipalinvestigator"/>
|
||||
<c:param name="render_mode" value="data"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/McDonaldRobertH"/>
|
||||
</c:url>
|
||||
|
||||
<c:url var="freemarkertest" value="/visualization">
|
||||
<c:param name="vis" value="freemarker"/>
|
||||
<c:param name="render_mode" value="standalone"/>
|
||||
<c:param name="uri" value="http://vivo.iu.edu/individual/McDonaldRobertH"/>
|
||||
</c:url>
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
.get_vis {
|
||||
background-color:Yellow;
|
||||
|
@ -316,7 +370,7 @@ $(document).ready(function() {
|
|||
|
||||
<h1 id="test-bed">Visualization Testbed (Not to be seen by eventual end users)</h1>
|
||||
|
||||
|
||||
<h2>Hello World!</h2>
|
||||
|
||||
<a href='<c:out value="${coAuthorship1}"/>'>vis link for coauthorship -> "Erb, Hollis Nancy"</a>
|
||||
<a href='<c:out value="${coAuthorship1Data}"/>'>Data</a>
|
||||
|
@ -342,8 +396,24 @@ $(document).ready(function() {
|
|||
<a href='<c:out value="${coAuthorship10}"/>'>vis link for coauthorship -> "Not Working"</a>
|
||||
<a href='<c:out value="${coAuthorship10Data}"/>'>Data</a><br />
|
||||
|
||||
<a href='<c:out value="${departmentPublications}"/>'>Department Publications</a>
|
||||
<a href='<c:out value="${departmentPublicationsdata}"/>'>Data</a><br />
|
||||
<a href='<c:out value="${schoolPublications}"/>'>School Publications</a>
|
||||
<a href='<c:out value="${schoolPublicationsdata}"/>'>Data</a><br />
|
||||
<a href='<c:out value="${universityPublications}"/>'>University Publications</a>
|
||||
<a href='<c:out value="${universityPublicationsdata}"/>'>Data</a><br />
|
||||
|
||||
<br /><br /><br />
|
||||
|
||||
<a href='<c:out value="${coprincipalinvestigatordata}"/>'>Co-PI data </a>
|
||||
|
||||
<br /><br /><br />
|
||||
|
||||
<a href='<c:out value="${freemarkertest}"/>'>Freemarker Test</a>
|
||||
|
||||
<br /><br /><br />
|
||||
|
||||
|
||||
<a href='<c:out value="${collegeCSV}"/>'>vis data query for college -> "School of Industrial and Labor Relations (ILR)"</a><br />
|
||||
<a href='<c:out value="${collegeCSV2}"/>'>vis data query for college -> "College of Agriculture and Life Sciences (CALS)"</a><br />
|
||||
<a href='<c:out value="${collegeCSV3}"/>'>vis data query for college -> "College of Arts and Sciences"</a><br />
|
||||
|
|
189
productMods/templates/visualization/entity_comparison.jsp
Normal file
189
productMods/templates/visualization/entity_comparison.jsp
Normal file
|
@ -0,0 +1,189 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
<!--<script type="text/javascript" src="http://orderedlist.com/demos/quicksilverjs/javascripts/quicksilver.js"></script>
|
||||
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>-->
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
|
||||
|
||||
<c:set var="portalBean" value="${requestScope.portalBean}" />
|
||||
<c:set var="themeDir">
|
||||
<c:out value="${portalBean.themeDir}" />
|
||||
</c:set>
|
||||
<c:set var='jsonContent' value='${requestScope.JsonContent}' />
|
||||
<div id="body">
|
||||
<div id="navcontainer">
|
||||
<ul id="navlist">
|
||||
<li><a href="#">Temporal</a></li>
|
||||
<li><a href="#">Geospatial</a></li>
|
||||
<li><a href="#">Scimap</a></li>
|
||||
<li><a href="#">Networks</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<h1>Temporal Graph Visualization<span id="entitylevelheading"><i> School level</i></span></h1>
|
||||
<div id="leftblock">
|
||||
<div id="leftUpper">
|
||||
<h2 style="background-color:#3D454E; color: white; margin-top: 0px; margin-bottom: 20px; padding-bottom:5px;">How do you want to compare?</h2>
|
||||
<p style="float:left; margin-left:10px; margin-right: 10px; margin-top: 6px;">Select </p>
|
||||
<select class="comparisonValues" style="margin-bottom: 20px;">
|
||||
<option value="Publications" selected="selected">Publications</option>
|
||||
<option value="Grants" disabled="disabled">Grants</option>
|
||||
<option value="People" disabled="disabled">People</option>
|
||||
<option value="Item4" disabled="disabled">Item4</option>
|
||||
<option value="Item5" disabled="disabled">Item5</option>
|
||||
</select>
|
||||
</div>
|
||||
<br/>
|
||||
<div id="leftLower">
|
||||
<h2 style="background-color:#3D454E; color: white; margin-top: 0px; margin-bottom: 20px; padding-bottom:5px;">Choose</h2>
|
||||
<div id="paginatedTable">
|
||||
</div>
|
||||
</div>
|
||||
<div id = "stopwordsdiv">
|
||||
* The entity types core:Person, foaf:Organization have been excluded as they are too general.
|
||||
</div>
|
||||
</div>
|
||||
<div id="rightblock">
|
||||
<div id="graphContainer" style="width: 450px; height: 250px;"></div>
|
||||
<div id="yaxislabel"></div>
|
||||
<div id="bottom" style="width: 450px; height: 350px;">
|
||||
<div id="xaxislabel">Year</div>
|
||||
<h3><span id="comparisonParameter"></span></h3>
|
||||
<p class="displayCounter">You have selected <span id="counter">0</span> of a maximum <span
|
||||
id="total">10</span> <span id="entityleveltext"> schools</span> to compare.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bottomButtons">
|
||||
<button id="clear" class = "metallic" type ="button">Clear</button>
|
||||
<button id="csv" class = "metallic" type ="button">Save as CSV</button>
|
||||
<button id="image" class= "metallic" type="button" onClick="window.print()"> Save as Image</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var jsonString = '${jsonContent}';
|
||||
var jsonObject = {
|
||||
prepare : function(arg1){
|
||||
loadData(arg1);
|
||||
}
|
||||
};
|
||||
|
||||
graphContainer = $("#graphContainer");
|
||||
tableDiv = $('#paginatedTable');
|
||||
|
||||
// initial display of the grid when the page loads
|
||||
init(graphContainer);
|
||||
|
||||
/*
|
||||
* When the intra-entity parameters are clicked,
|
||||
* update the status accordingly.
|
||||
*/
|
||||
$("select.comparisonValues").click(function(){
|
||||
var selectedValue = $("select.comparisonValues option:selected").val();
|
||||
$("#comparisonParameter").text("Total Number of " + selectedValue);
|
||||
$('#yaxislabel').html("Number of " + selectedValue ).mbFlipText(false);
|
||||
$("span#paramdesc").text($("select.comparisonValues option:selected").val() + ' (desc)');
|
||||
$("span#paramasc").text($("select.comparisonValues option:selected").val() + ' (asc)');
|
||||
});
|
||||
|
||||
//click event handler for clear button
|
||||
$("button#clear").click(function(){
|
||||
clearRenderedObjects();
|
||||
});
|
||||
|
||||
|
||||
$("input[type=checkbox].easyDeselectCheckbox").live('click', function(){
|
||||
|
||||
var checkbox = $(this);
|
||||
var checkboxValue = $(this).attr("value");
|
||||
var linkedCheckbox = labelToCheckedEntities[checkboxValue];
|
||||
//console.log('checkbox value is '+ checkboxValue);
|
||||
var entityToBeRemoved = labelToEntityRecord[checkboxValue];
|
||||
|
||||
if(!checkbox.is(':checked')){
|
||||
//console.log("Easy deselect checkbox is unclicked!");
|
||||
updateRowHighlighter(linkedCheckbox);
|
||||
removeUsedColor(entityToBeRemoved);
|
||||
removeEntityUnChecked(renderedObjects, entityToBeRemoved);
|
||||
removeGraphic(linkedCheckbox);
|
||||
removeCheckBoxFromGlobalSet(linkedCheckbox);
|
||||
$(linkedCheckbox).attr('checked', false);
|
||||
checkIfColorLimitIsReached();
|
||||
displayLineGraphs();
|
||||
updateCounter();
|
||||
}
|
||||
});
|
||||
|
||||
//parse the json object and pass it to loadData
|
||||
jsonObject.prepare(jQuery.parseJSON(jsonString));
|
||||
|
||||
/*
|
||||
* function to populate the labelToEntityRecord object with the
|
||||
* values from the json file and
|
||||
* dynamically generate checkboxes
|
||||
*/
|
||||
function loadData(jsonData){
|
||||
|
||||
// var yearRange;
|
||||
|
||||
$.each(jsonData, function(index, val){
|
||||
setOfLabels.push(val.label);
|
||||
labelToEntityRecord[val.label] = val;
|
||||
});
|
||||
|
||||
getEntityVisMode(jsonData);
|
||||
prepareTableForDataTablePagination(jsonData);
|
||||
setEntityLevel();
|
||||
// calcMinandMaxYears(labelToEntityRecord, year);
|
||||
//yearRange = (year.max - year.min);
|
||||
|
||||
// setLineWidthAndTickSize(yearRange, FlotOptions);
|
||||
//setTickSizeOfYAxis(calcMaxOfComparisonParameter(labelToEntityRecord), FlotOptions);
|
||||
/*
|
||||
* When the elements in the paginated div
|
||||
* are clicked this event handler is called
|
||||
*/
|
||||
$("input.if_clicked_on_school").live('click', function(){
|
||||
|
||||
var checkbox = $(this);
|
||||
var checkboxValue = $(this).attr("value");
|
||||
var entity = labelToEntityRecord[checkboxValue];
|
||||
|
||||
//Dynamically generate the bar, checkbox and label.
|
||||
|
||||
var bottomDiv = $("#bottom");
|
||||
var hiddenLabel = createGraphic(entity, bottomDiv);
|
||||
|
||||
|
||||
var divBar = hiddenLabel.next();
|
||||
var divLabel = hiddenLabel.prev();
|
||||
var spanElement = divBar.next('span');
|
||||
|
||||
if (checkbox.is(':checked')) {
|
||||
|
||||
getNextFreeColor(entity);
|
||||
generateBarAndLabel(entity, divBar, divLabel,checkbox, spanElement) ;
|
||||
renderLineGraph(renderedObjects, entity);
|
||||
labelToCheckedEntities[checkboxValue] = checkbox;
|
||||
|
||||
} else if (!checkbox.is(':checked')) {
|
||||
|
||||
removeUsedColor(entity);
|
||||
removeEntityUnChecked(renderedObjects, entity);
|
||||
removeGraphic(checkbox);
|
||||
removeCheckBoxFromGlobalSet(checkbox);
|
||||
|
||||
}
|
||||
//console.log('Number of checked entities: ' + getSize(labelToCheckedEntities));
|
||||
//disableUncheckedEntities();
|
||||
setTickSizeOfAxes();
|
||||
checkIfColorLimitIsReached();
|
||||
//populateMapOfCheckedEntities();
|
||||
displayLineGraphs();
|
||||
updateCounter();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
|
@ -0,0 +1,62 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
|
||||
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||
|
||||
<c:set var="portalBean" value="${requestScope.portalBean}" />
|
||||
<c:set var="themeDir"><c:out value="${portalBean.themeDir}" /></c:set>
|
||||
<c:set var="contextPath"><c:out value="${pageContext.request.contextPath}" /></c:set>
|
||||
|
||||
<c:url var="jquery" value="/js/jquery.js"/>
|
||||
<c:url var="flot" value="/js/jquery_plugins/flot/jquery.flot.js"/>
|
||||
<c:url var="fliptext" value="/js/jquery_plugins/fliptext/jquery.mb.flipText.js"/>
|
||||
<c:url var="jgrowl" value="/js/jquery_plugins/jgrowl/jquery.jgrowl.js"/>
|
||||
<c:url var="pagination" value="/js/jquery_plugins/pagination/jquery.pagination.js"/>
|
||||
<c:url var="livesearch" value="/js/jquery_plugins/jquery.livesearch.js"/>
|
||||
<c:url var="datatable" value="/js/jquery_plugins/datatable/jquery.dataTables.js"/>
|
||||
<c:url var="autoellipsis" value="/js/jquery_plugins/jquery.AutoEllipsis.js"/>
|
||||
|
||||
|
||||
<c:url var="entityComparisonUtils" value="/js/visualization/entityComparison/util.js" />
|
||||
<c:url var="entityComparisonConstants" value="/js/visualization/entityComparison/constants.js" />
|
||||
|
||||
<!-- css related to jgrowl and pagination js files. -->
|
||||
<c:url var="paginationStyle" value="/js/jquery_plugins/pagination/pagination.css" />
|
||||
<c:url var="jgrowlStyle" value="/js/jquery_plugins/jgrowl/jquery.jgrowl.css" />
|
||||
|
||||
<!-- css related to dataTable js files. -->
|
||||
<c:url var="demopage" value="/js/jquery_plugins/datatable/demo_page.css" />
|
||||
<c:url var="demoTable" value="/js/jquery_plugins/datatable/demo_table.css" />
|
||||
|
||||
<c:url var="entityComparisonStyle" value="/${themeDir}css/visualization/entityComparison/layout.css" />
|
||||
<c:url var="vizStyle" value="/${themeDir}css/visualization/visualization.css" />
|
||||
|
||||
<!-- Including jquery, entity comparison related javascript files -->
|
||||
|
||||
<script type="text/javascript" src="${jquery}"></script>
|
||||
<script type="text/javascript" src="${flot}"></script>
|
||||
<script type="text/javascript" src="${fliptext}"></script>
|
||||
<script type="text/javascript" src="${jgrowl}"></script>
|
||||
<script type="text/javascript" src="${pagination}"></script>
|
||||
<script type="text/javascript" src="${livesearch}"></script>
|
||||
<script type="text/javascript" src="${datatable}"></script>
|
||||
<script type="text/javascript" src="${autoellipsis}"></script>
|
||||
<script type="text/javascript" src="${entityComparisonUtils}"></script>
|
||||
<script type="text/javascript" src="${entityComparisonConstants}"></script>
|
||||
|
||||
|
||||
<link href="${entityComparisonStyle}" rel="stylesheet" type="text/css" />
|
||||
<link href="${paginationStyle}" rel="stylesheet" type="text/css" />
|
||||
<link href="${jgrowlStyle}" rel="stylesheet" type="text/css" />
|
||||
<link href="${demopage}" rel="stylesheet" type="text/css" />
|
||||
<link href="${demoTable}" rel="stylesheet" type="text/css" />
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="${vizStyle}" />
|
||||
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
<!--
|
||||
|
||||
var contextPath = "${contextPath}";
|
||||
|
||||
// -->
|
||||
</script>
|
|
@ -18,6 +18,8 @@
|
|||
<c:set var='numOfAuthors' value='${requestScope.numOfAuthors}' />
|
||||
<c:set var='numOfCoAuthorShips' value='${requestScope.numOfCoAuthorShips}' />
|
||||
|
||||
<c:set var='completeURL' value='${requestScope.completeURL}' />
|
||||
|
||||
<c:url var="egoVivoProfileURL" value="/individual">
|
||||
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||
</c:url>
|
||||
|
@ -59,6 +61,7 @@ $(document).ready(function(){
|
|||
|
||||
<div id="body">
|
||||
|
||||
<div>complete URL = '${completeURL} '</div>
|
||||
<!--[if IE]>
|
||||
<style type="text/css">
|
||||
|
||||
|
|
|
@ -13,6 +13,14 @@
|
|||
<c:param name="labelField" value="label" />
|
||||
</c:url>
|
||||
|
||||
<c:url var="egoCoPIDataFeederURL" value="/visualization">
|
||||
<c:param name="vis" value="coprincipalinvestigator" />
|
||||
<c:param name="render_mode" value="data" />
|
||||
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||
<c:param name="labelField" value="label" />
|
||||
</c:url>
|
||||
|
||||
|
||||
<c:url var="egoCoAuthorsListDataFileURL" value="/visualization">
|
||||
<c:param name="vis" value="person_level" />
|
||||
<c:param name="render_mode" value="data" />
|
||||
|
@ -20,7 +28,7 @@
|
|||
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||
</c:url>
|
||||
|
||||
<c:url var="swfLink" value="/${themeDir}site_icons/visualization/coauthorship/CoAuthor.swf" />
|
||||
<c:url var="swfLink" value="/${themeDir}site_icons/visualization/coauthorship/EgoCentric.swf" />
|
||||
|
||||
<c:url var="jquery" value="/js/jquery.js"/>
|
||||
<c:url var="adobeFlashDetector" value="/js/visualization/coauthorship/AC_OETags.js" />
|
||||
|
@ -48,6 +56,7 @@ var swfLink = "${swfLink}";
|
|||
var egoURI = "${requestScope.egoURIParam}";
|
||||
var egoCoAuthorshipDataFeederURL = "${egoCoAuthorshipDataFeederURL}";
|
||||
var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
|
||||
var egoCoPIDataFeederURL = "${egoCoPIDataFeederURL}";
|
||||
var contextPath = "${contextPath}";
|
||||
|
||||
// -->
|
||||
|
|
|
@ -13,6 +13,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
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;
|
||||
|
@ -36,14 +37,13 @@ import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequ
|
|||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class VisualizationController extends BaseEditController {
|
||||
|
||||
private Map<String, VisualizationRequestHandler> visualizationIDsToClass;
|
||||
|
||||
public static final String URL_ENCODING_SCHEME = "UTF-8";
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Log log = LogFactory.getLog(VisualizationController.class.getName());
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
|
|
@ -46,6 +46,7 @@ public class VisualizationFrameworkConstants {
|
|||
public static final String COAUTHORSLIST_VIS_MODE = "coauthors";
|
||||
public static final String SHORT_SPARKLINE_VIS_MODE = "short";
|
||||
public static final String FULL_SPARKLINE_VIS_MODE = "full";
|
||||
public static final String COPI_VIS_MODE = "copi";
|
||||
|
||||
/*
|
||||
* These values represent possible utilities vis modes.
|
||||
|
@ -55,6 +56,10 @@ public class VisualizationFrameworkConstants {
|
|||
public static final String COAUTHOR_UTILS_VIS_MODE = "COAUTHORSHIP_URL";
|
||||
public static final String PERSON_LEVEL_UTILS_VIS_MODE = "PERSON_LEVEL_URL";
|
||||
public static final String IMAGE_UTILS_VIS_MODE = "IMAGE_URL";
|
||||
public static final String UNIVERSITY_COMPARISON_VIS_MODE = "UNIVERSITY";
|
||||
public static final String SCHOOL_COMPARISON_VIS_MODE = "SCHOOL";
|
||||
public static final String DEPARTMENT_COMPARISON_VIS_MODE = "DEPARTMENT";
|
||||
|
||||
|
||||
/*
|
||||
* These values represent possible visualizations provided as values to the "vis" url key.
|
||||
|
@ -65,5 +70,8 @@ public class VisualizationFrameworkConstants {
|
|||
public static final String COAUTHORSHIP_VIS = "coauthorship";
|
||||
public static final String PERSON_LEVEL_VIS = "person_level";
|
||||
public static final String UTILITIES_VIS = "utilities";
|
||||
public static final String ENTITY_COMPARISON_VIS = "entity_comparison";
|
||||
public static final String CO_PI_VIS = "coprincipalinvestigator";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.visualization.freemarker;
|
||||
|
||||
public class VisualizationController {
|
||||
|
||||
}
|
|
@ -33,7 +33,6 @@ import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
|||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
|
||||
|
@ -51,8 +50,6 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String egoURI;
|
||||
private Map<String, VivoCollegeOrSchool> collegeURLToVO =
|
||||
new HashMap<String, VivoCollegeOrSchool>();
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
|
@ -356,9 +353,9 @@ public class CoAuthorshipQueryRunner implements QueryRunner<CoAuthorshipData> {
|
|||
|
||||
}
|
||||
|
||||
public Map<String, VivoCollegeOrSchool> getCollegeURLToVO() {
|
||||
return collegeURLToVO;
|
||||
}
|
||||
// public Map<String, VivoCollegeOrSchool> getCollegeURLToVO() {
|
||||
// return collegeURLToVO;
|
||||
// }
|
||||
|
||||
private BiboDocument createDocumentVO(QuerySolution solution, String documentURL) {
|
||||
|
||||
|
|
|
@ -1,322 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.collegepubcount;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.iri.IRI;
|
||||
import com.hp.hpl.jena.iri.IRIFactory;
|
||||
import com.hp.hpl.jena.iri.Violation;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.Query;
|
||||
import com.hp.hpl.jena.query.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||
import com.hp.hpl.jena.query.QueryFactory;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants.EmployeeType;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoDepartmentOrDivision;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoEmployee;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author cdtank
|
||||
*/
|
||||
public class CollegePublicationCountQueryRunner implements QueryRunner<Set<VivoEmployee>> {
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String collegeURI;
|
||||
private Map<String, VivoCollegeOrSchool> collegeURLToVO =
|
||||
new HashMap<String, VivoCollegeOrSchool>();
|
||||
private DataSource dataSource;
|
||||
|
||||
private Log log;
|
||||
|
||||
public CollegePublicationCountQueryRunner(String collegeURI,
|
||||
DataSource dataSource, Log log) {
|
||||
|
||||
this.collegeURI = collegeURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
|
||||
}
|
||||
|
||||
private Set<VivoEmployee> createJavaValueObjects(ResultSet resultSet) {
|
||||
|
||||
Set<VivoEmployee> collegeAcademicEmployees = new HashSet<VivoEmployee>();
|
||||
|
||||
Map<String, VivoDepartmentOrDivision> departmentURLToVO =
|
||||
new HashMap<String, VivoDepartmentOrDivision>();
|
||||
Map<String, VivoEmployee> employeeURLToVO = new HashMap<String, VivoEmployee>();
|
||||
|
||||
while (resultSet.hasNext()) {
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
String collegeURL = solution.get(QueryFieldLabels.COLLEGE_URL).toString();
|
||||
|
||||
VivoCollegeOrSchool currentCollege;
|
||||
|
||||
if (collegeURLToVO.containsKey(collegeURL)) {
|
||||
currentCollege = collegeURLToVO.get(collegeURL);
|
||||
} else {
|
||||
currentCollege = new VivoCollegeOrSchool(collegeURL);
|
||||
collegeURLToVO.put(collegeURL, currentCollege);
|
||||
|
||||
RDFNode collegeLabelNode = solution.get(QueryFieldLabels.COLLEGE_LABEL);
|
||||
if (collegeLabelNode != null) {
|
||||
currentCollege.setCollegeLabel(collegeLabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
String departmentURL = solution.get(QueryFieldLabels.DEPARTMENT_URL).toString();
|
||||
|
||||
VivoDepartmentOrDivision currentDepartment;
|
||||
|
||||
if (departmentURLToVO.containsKey(departmentURL)) {
|
||||
currentDepartment = departmentURLToVO.get(departmentURL);
|
||||
currentDepartment.addParentCollege(currentCollege);
|
||||
} else {
|
||||
currentDepartment = new VivoDepartmentOrDivision(departmentURL, currentCollege);
|
||||
departmentURLToVO.put(departmentURL, currentDepartment);
|
||||
|
||||
RDFNode departmentLabelNode = solution.get(QueryFieldLabels.DEPARTMENT_LABEL);
|
||||
if (departmentLabelNode != null) {
|
||||
currentDepartment.setDepartmentLabel(departmentLabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
currentCollege.addDepartment(currentDepartment);
|
||||
|
||||
RDFNode employeeNode = solution.get(QueryFieldLabels.ACADEMIC_FACULTY_EMPLOYEE_URL);
|
||||
EmployeeType currentEmployeeType;
|
||||
VivoEmployee currentEmployee;
|
||||
|
||||
if (employeeNode != null) {
|
||||
currentEmployeeType = EmployeeType.ACADEMIC_FACULTY_EMPLOYEE;
|
||||
} else {
|
||||
currentEmployeeType = EmployeeType.ACADEMIC_STAFF_EMPLOYEE;
|
||||
employeeNode = solution.get(QueryFieldLabels.ACADEMIC_STAFF_EMPLOYEE_URL);
|
||||
}
|
||||
|
||||
if (employeeURLToVO.containsKey(employeeNode.toString())) {
|
||||
currentEmployee = employeeURLToVO.get(employeeNode.toString());
|
||||
currentEmployee.addParentDepartment(currentDepartment);
|
||||
} else {
|
||||
currentEmployee = new VivoEmployee(employeeNode.toString(),
|
||||
currentEmployeeType,
|
||||
currentDepartment);
|
||||
RDFNode authorLabelNode = solution.get(QueryFieldLabels.AUTHOR_LABEL);
|
||||
if (authorLabelNode != null) {
|
||||
currentEmployee.setIndividualLabel(authorLabelNode.toString());
|
||||
}
|
||||
employeeURLToVO.put(employeeNode.toString(), currentEmployee);
|
||||
}
|
||||
|
||||
RDFNode documentNode = solution.get(QueryFieldLabels.DOCUMENT_URL);
|
||||
if (documentNode != null) {
|
||||
|
||||
/*
|
||||
* A document can have multiple authors but if the same author serves in
|
||||
* multiple departments then we need to account for "An Authored Document"
|
||||
* only once. This check will make sure that a document by same author is
|
||||
* not added twice just because that author serves in 2 distinct department.
|
||||
* */
|
||||
boolean isNewDocumentAlreadyAdded = testForDuplicateEntryOfDocument(
|
||||
currentEmployee,
|
||||
documentNode);
|
||||
|
||||
if (!isNewDocumentAlreadyAdded) {
|
||||
currentEmployee.addAuthorDocument(
|
||||
createAuthorDocumentsVO(solution,
|
||||
documentNode.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
collegeAcademicEmployees.add(currentEmployee);
|
||||
}
|
||||
|
||||
return collegeAcademicEmployees;
|
||||
}
|
||||
|
||||
private boolean testForDuplicateEntryOfDocument(
|
||||
VivoEmployee currentEmployee, RDFNode documentNode) {
|
||||
boolean isNewDocumentAlreadyAdded = false;
|
||||
|
||||
for (BiboDocument currentAuthoredDocument : currentEmployee.getAuthorDocuments()) {
|
||||
if (currentAuthoredDocument.getDocumentURL()
|
||||
.equalsIgnoreCase(documentNode.toString())) {
|
||||
isNewDocumentAlreadyAdded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isNewDocumentAlreadyAdded;
|
||||
}
|
||||
|
||||
public Map<String, VivoCollegeOrSchool> getCollegeURLToVO() {
|
||||
return collegeURLToVO;
|
||||
}
|
||||
|
||||
private BiboDocument createAuthorDocumentsVO(QuerySolution solution, String documentURI) {
|
||||
|
||||
BiboDocument biboDocument = new BiboDocument(documentURI);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
return biboDocument;
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryText,
|
||||
DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
try {
|
||||
Query query = QueryFactory.create(queryText, 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 generateCollegeEmployeeSparqlQuery(String queryURI) {
|
||||
// Resource uri1 = ResourceFactory.createResource(queryURI);
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT (str(?collegeLabel) as ?" + QueryFieldLabels.COLLEGE_LABEL + ") "
|
||||
+ " (str(?department) as ?" + QueryFieldLabels.DEPARTMENT_URL + ") "
|
||||
+ " (str(?departmentLabel) as ?" + QueryFieldLabels.DEPARTMENT_LABEL + ") "
|
||||
+ " (str(?academicFacultyEmployee) as ?" + QueryFieldLabels.ACADEMIC_FACULTY_EMPLOYEE_URL + ") "
|
||||
+ " (str(?academicStaffEmployee) as ?" + QueryFieldLabels.ACADEMIC_STAFF_EMPLOYEE_URL + ") "
|
||||
+ " (str(<" + queryURI + ">) as ?" + QueryFieldLabels.COLLEGE_URL + ") "
|
||||
+ " (str(?authorLabel) as ?" + QueryFieldLabels.AUTHOR_LABEL + ") "
|
||||
+ " (str(?document) as ?" + QueryFieldLabels.DOCUMENT_URL + ") "
|
||||
+ " (str(?documentMoniker) as ?" + QueryFieldLabels.DOCUMENT_MONIKER + ") "
|
||||
+ " (str(?documentLabel) as ?" + QueryFieldLabels.DOCUMENT_LABEL + ") "
|
||||
+ " (str(?documentBlurb) as ?" + QueryFieldLabels.DOCUMENT_BLURB + ") "
|
||||
+ " (str(?documentDescription) as ?" + QueryFieldLabels.DOCUMENT_DESCRIPTION + ") "
|
||||
+ " (str(?publicationYear) as ?" + QueryFieldLabels.DOCUMENT_PUBLICATION_YEAR + ") "
|
||||
+ "WHERE { "
|
||||
+ "<" + queryURI + "> rdf:type vivo:CollegeOrSchoolWithinUniversity; " +
|
||||
"rdfs:label ?collegeLabel; " +
|
||||
"vivo:hasAcademicDepartmentOrDivision ?department . "
|
||||
+ "?department rdfs:label ?departmentLabel ."
|
||||
+ "{ "
|
||||
+ getAcademicEmployeePublicationsSparqlQuery("academicFacultyEmployee", "vivo:hasEmployeeAcademicFacultyMember")
|
||||
+ " UNION "
|
||||
+ getAcademicEmployeePublicationsSparqlQuery("academicStaffEmployee", "vivo:hasEmployeeAcademicStaffMember")
|
||||
+ "}"
|
||||
+ "}";
|
||||
|
||||
// System.out.println(sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
|
||||
private String getAcademicEmployeePublicationsSparqlQuery(String employeeHandle,
|
||||
String ontologyHandle) {
|
||||
|
||||
String sparqlQuery = " {?department " + ontologyHandle + " ?" + employeeHandle + " . "
|
||||
+ "?" + employeeHandle + " rdf:type foaf:Person; rdfs:label ?authorLabel. "
|
||||
+ "OPTIONAL { ?" + employeeHandle + " vivo:authorOf ?document ." +
|
||||
" ?document rdfs:label ?documentLabel ." +
|
||||
" OPTIONAL { ?document vitro:moniker ?documentMoniker } ." +
|
||||
" OPTIONAL { ?document vitro:blurb ?documentBlurb } ." +
|
||||
" OPTIONAL { ?document vitro:description ?documentDescription } ." +
|
||||
" OPTIONAL { ?document vivo:publicationYear ?publicationYear } ." +
|
||||
"}" +
|
||||
"} ";
|
||||
|
||||
return sparqlQuery;
|
||||
|
||||
}
|
||||
|
||||
public Set<VivoEmployee> getQueryResult()
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.collegeURI)) {
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
* */
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
IRI iri = iRIFactory.create(this.collegeURI);
|
||||
if (iri.hasViolation(false)) {
|
||||
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
|
||||
log.error("Pub Count Vis Query " + errorMsg);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an individual is malformed.");
|
||||
}
|
||||
} else {
|
||||
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(generateCollegeEmployeeSparqlQuery(this.collegeURI),
|
||||
this.dataSource);
|
||||
|
||||
return createJavaValueObjects(resultSet);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,394 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.collegepubcount;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.skife.csv.CSVWriter;
|
||||
import org.skife.csv.SimpleWriter;
|
||||
|
||||
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.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoCollegeOrSchool;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoDepartmentOrDivision;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.VivoEmployee;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.PDFDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
|
||||
|
||||
public class CollegePublicationCountRequestHandler implements VisualizationRequestHandler {
|
||||
|
||||
public void generateVisualization(VitroRequest vitroRequest,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Log log,
|
||||
DataSource dataSource) {
|
||||
|
||||
String collegeURIParam = 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<VivoEmployee>> queryManager =
|
||||
new CollegePublicationCountQueryRunner(collegeURIParam,
|
||||
dataSource,
|
||||
log);
|
||||
|
||||
try {
|
||||
|
||||
Set<VivoEmployee> employees = queryManager.getQueryResult();
|
||||
|
||||
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime =
|
||||
new HashMap<VivoDepartmentOrDivision, Map<String, Integer>>();
|
||||
|
||||
Set<String> publishedYearsForCollege = new HashSet<String>();
|
||||
|
||||
for (VivoEmployee currentEmployee : employees) {
|
||||
|
||||
Map<String, Integer> currentEmployeeYearToPublicationCount =
|
||||
UtilityFunctions.getYearToPublicationCount(
|
||||
currentEmployee.getAuthorDocuments());
|
||||
|
||||
if (currentEmployeeYearToPublicationCount.size() > 0) {
|
||||
|
||||
|
||||
publishedYearsForCollege.addAll(currentEmployeeYearToPublicationCount.keySet());
|
||||
|
||||
for (VivoDepartmentOrDivision currentDepartment
|
||||
: currentEmployee.getParentDepartments()) {
|
||||
|
||||
departmentToPublicationsOverTime
|
||||
.put(currentDepartment,
|
||||
getUpdatedDepartmentPublicationsOverTime(
|
||||
currentEmployeeYearToPublicationCount,
|
||||
departmentToPublicationsOverTime
|
||||
.get(currentDepartment)));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to avoid unneeded computations we have pushed this "if" condition up.
|
||||
* This case arises when the render mode is data. In that case we dont want to generate
|
||||
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
|
||||
* It is ugly!
|
||||
* */
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE.equalsIgnoreCase(renderMode)) {
|
||||
prepareDataResponse(
|
||||
departmentToPublicationsOverTime,
|
||||
((CollegePublicationCountQueryRunner) queryManager).getCollegeURLToVO(),
|
||||
response);
|
||||
|
||||
log.debug(publishedYearsForCollege);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (PDF_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||
prepareVisualizationQueryPDFResponse(authorDocuments,
|
||||
yearToPublicationCount);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Computations required to generate HTML for the sparklines & related context.
|
||||
* */
|
||||
|
||||
/*
|
||||
* 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".
|
||||
* */
|
||||
publishedYearsForCollege.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||
|
||||
} catch (MalformedQueryParametersException e) {
|
||||
try {
|
||||
UtilityFunctions.handleMalformedParameters(
|
||||
e.getMessage(),
|
||||
"Visualization Query Error - College Publication Count",
|
||||
vitroRequest,
|
||||
request,
|
||||
response,
|
||||
log);
|
||||
} catch (ServletException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
} catch (IOException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Integer> getUpdatedDepartmentPublicationsOverTime(
|
||||
Map<String, Integer> currentEmployeeYearToPublicationCount,
|
||||
Map<String, Integer> currentDepartmentYearToPublicationCount) {
|
||||
|
||||
Map<String, Integer> departmentYearToPublicationCount;
|
||||
|
||||
/*
|
||||
* In case this is the first time we are consolidating publication counts
|
||||
* over time for a department.
|
||||
* */
|
||||
if (currentDepartmentYearToPublicationCount == null) {
|
||||
|
||||
departmentYearToPublicationCount = new TreeMap<String, Integer>();
|
||||
|
||||
} else {
|
||||
departmentYearToPublicationCount = currentDepartmentYearToPublicationCount;
|
||||
}
|
||||
|
||||
|
||||
Iterator employeePubCountIterator = currentEmployeeYearToPublicationCount
|
||||
.entrySet().iterator();
|
||||
|
||||
while (employeePubCountIterator.hasNext()) {
|
||||
Map.Entry<String, Integer> employeePubCountEntry =
|
||||
(Map.Entry) employeePubCountIterator.next();
|
||||
|
||||
String employeePublicationYear = employeePubCountEntry.getKey();
|
||||
Integer employeePublicationCount = employeePubCountEntry.getValue();
|
||||
|
||||
try {
|
||||
if (departmentYearToPublicationCount.containsKey(employeePublicationYear)) {
|
||||
departmentYearToPublicationCount.put(employeePublicationYear,
|
||||
departmentYearToPublicationCount
|
||||
.get(employeePublicationYear)
|
||||
+ employeePublicationCount);
|
||||
|
||||
} else {
|
||||
|
||||
departmentYearToPublicationCount.put(employeePublicationYear,
|
||||
employeePublicationCount);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return departmentYearToPublicationCount;
|
||||
}
|
||||
|
||||
private void preparePDFResponse(Individual college,
|
||||
List<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 = college.getIndividualLabel();
|
||||
}
|
||||
|
||||
/*
|
||||
* To make sure that null/empty records for author names do not cause any mischief.
|
||||
* */
|
||||
if (authorName == null) {
|
||||
authorName = "";
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
response.setHeader("Expires", "0");
|
||||
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
|
||||
response.setHeader("Pragma", "public");
|
||||
response.setContentLength(baos.size());
|
||||
|
||||
baos.writeTo(responseOutputStream);
|
||||
responseOutputStream.flush();
|
||||
responseOutputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareDataResponse(
|
||||
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime,
|
||||
Map<String, VivoCollegeOrSchool> collegeURLToVO, HttpServletResponse response) {
|
||||
|
||||
String collegeName = null;
|
||||
|
||||
/*
|
||||
* To protect against cases where there are no author documents associated with the
|
||||
* individual.
|
||||
* */
|
||||
|
||||
if (collegeURLToVO.size() > 0) {
|
||||
|
||||
collegeName = ((VivoCollegeOrSchool) collegeURLToVO.values()
|
||||
.iterator().next()).getCollegeLabel();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* To make sure that null/empty records for author names do not cause any mischief.
|
||||
* */
|
||||
if (collegeName == null) {
|
||||
collegeName = "";
|
||||
}
|
||||
|
||||
String outputFileName = UtilityFunctions.slugify(collegeName) + "depts-pub-count" + ".csv";
|
||||
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter responseWriter = response.getWriter();
|
||||
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||
* object of the servlet.
|
||||
* */
|
||||
generateCsvFileBuffer(departmentToPublicationsOverTime,
|
||||
collegeURLToVO,
|
||||
responseWriter);
|
||||
|
||||
responseWriter.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateCsvFileBuffer(
|
||||
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime,
|
||||
Map<String, VivoCollegeOrSchool> collegeURLToVO, PrintWriter printWriter) {
|
||||
|
||||
CSVWriter csvWriter = new SimpleWriter(printWriter);
|
||||
|
||||
try {
|
||||
csvWriter.append(new String[]{"School", "Department", "Year", "Publications"});
|
||||
|
||||
Iterator<VivoCollegeOrSchool> collegeIterator = collegeURLToVO.values().iterator();
|
||||
|
||||
while (collegeIterator.hasNext()) {
|
||||
VivoCollegeOrSchool college = collegeIterator.next();
|
||||
String collegeLabel = college.getCollegeLabel();
|
||||
for (VivoDepartmentOrDivision currentDepartment : college.getDepartments()) {
|
||||
|
||||
Map<String, Integer> currentDepartmentPublicationsOverTime =
|
||||
departmentToPublicationsOverTime.get(currentDepartment);
|
||||
|
||||
/*
|
||||
* This because many departments might not have any publication.
|
||||
* */
|
||||
if (currentDepartmentPublicationsOverTime != null) {
|
||||
|
||||
for (Entry<String, Integer> currentEntry
|
||||
: currentDepartmentPublicationsOverTime.entrySet()) {
|
||||
csvWriter.append(new Object[]{collegeLabel,
|
||||
currentDepartment.getDepartmentLabel(),
|
||||
currentEntry.getKey(),
|
||||
currentEntry.getValue()});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
printWriter.flush();
|
||||
|
||||
}
|
||||
|
||||
private void prepareStandaloneResponse(HttpServletRequest request,
|
||||
HttpServletResponse response, VitroRequest vreq,
|
||||
String visContentCode, String visContextCode) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
request.setAttribute("visContentCode", visContentCode);
|
||||
request.setAttribute("visContextCode", visContextCode);
|
||||
|
||||
request.setAttribute("bodyJsp", "/templates/visualization/publication_count.jsp");
|
||||
request.setAttribute("portalBean", portal);
|
||||
request.setAttribute("title", "Individual Publication Count Visualization");
|
||||
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||
|
||||
}
|
||||
|
||||
private void prepareDynamicResponse(HttpServletRequest request,
|
||||
HttpServletResponse response, VitroRequest vreq,
|
||||
String visContentCode, String visContextCode) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
|
||||
request.setAttribute("visContentCode", visContentCode);
|
||||
request.setAttribute("visContextCode", visContextCode);
|
||||
|
||||
request.setAttribute("portalBean", portal);
|
||||
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -51,11 +51,7 @@ public class QueryFieldLabels {
|
|||
public static final String COLLEGE_URL = "collegeLit";
|
||||
public static final String COLLEGE_LABEL = "collegeLabelLit";
|
||||
|
||||
/*
|
||||
* Department related field labels
|
||||
* */
|
||||
public static final String DEPARTMENT_URL = "departmentLit";
|
||||
public static final String DEPARTMENT_LABEL = "departmentLabelLit";
|
||||
|
||||
|
||||
/*
|
||||
* Employee related field labels
|
||||
|
@ -63,4 +59,62 @@ public class QueryFieldLabels {
|
|||
public static final String ACADEMIC_FACULTY_EMPLOYEE_URL = "academicFacultyEmployeeLit";
|
||||
public static final String ACADEMIC_STAFF_EMPLOYEE_URL = "academicStaffEmployeeLit";
|
||||
|
||||
/*
|
||||
* Person related field Labels
|
||||
*/
|
||||
public static final String PERSON_URL = "personLit";
|
||||
public static final String PERSON_LABEL = "personLabelLit";
|
||||
public static final String PERSON_TYPE = "personTypeLit";
|
||||
public static final String PERSON_TYPE_LABEL = "personTypeLabelLit";
|
||||
|
||||
|
||||
/*
|
||||
* Position related field labels
|
||||
*/
|
||||
public static final String SECONDARY_POSITION_LABEL = "SecondaryPositionLabelLit";
|
||||
|
||||
/*
|
||||
* start year related field labels
|
||||
*/
|
||||
public static final String START_YEAR_LABEL = "StartYearLit";
|
||||
|
||||
|
||||
/*
|
||||
* Organization related field Labels
|
||||
*/
|
||||
public static final String ORGANIZATION_URL = "organizationLit";
|
||||
public static final String ORGANIZATION_LABEL = "organizationLabelLit";
|
||||
|
||||
|
||||
/*
|
||||
* Sub Organization related field labels
|
||||
*/
|
||||
public static final String SUBORGANIZATION_URL = "subOrganizationLit";
|
||||
public static final String SUBORGANIZATION_LABEL = "subOrganizationLabelLit";
|
||||
|
||||
/*
|
||||
* Sub Organization related field labels
|
||||
*/
|
||||
public static final String SUBORGANIZATION_TYPE = "subOrganizationTypeLit";
|
||||
public static final String SUBORGANIZATION_TYPE_LABEL = "subOrganizationTypeLabelLit";
|
||||
|
||||
|
||||
/*
|
||||
* Department related field labels
|
||||
* */
|
||||
public static final String DEPARTMENT_URL = "departmentLit";
|
||||
public static final String DEPARTMENT_LABEL = "departmentLabelLit";
|
||||
|
||||
/*
|
||||
* Co-PI related field labels
|
||||
*/
|
||||
public static final String PI_URL = "PILit";
|
||||
public static final String PI_LABEL = "PILabelLit";
|
||||
public static final String CO_PI_URL = "coPILit";
|
||||
public static final String CO_PI_LABEL = "coPILabelLit";
|
||||
public static final String GRANT_URL = "grantLit";
|
||||
public static final String GRANT_LABEL = "grantLabelLit";
|
||||
public static final String GRANT_START_DATE = "grantStartDateLit";
|
||||
public static final String GRANT_END_DATE = "grantEndDateLit";
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Calendar;
|
|||
public class VOConstants {
|
||||
|
||||
public static final String DEFAULT_PUBLICATION_YEAR = "Unknown";
|
||||
public static final String DEFAULT_GRANT_YEAR = "Unknown";
|
||||
|
||||
/*
|
||||
* Employee related constants
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIEdge;
|
||||
|
||||
|
||||
/**
|
||||
* This Comparator is used to sort the edges based on their IDs in ascending order.
|
||||
* @author bkoniden
|
||||
*
|
||||
*/
|
||||
public class CoPIEdgeComparator implements Comparator<CoPIEdge> {
|
||||
|
||||
@Override
|
||||
public int compare(CoPIEdge arg0, CoPIEdge arg1) {
|
||||
return arg0.getEdgeID() - arg1.getEdgeID();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,438 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.iri.IRI;
|
||||
import com.hp.hpl.jena.iri.IRIFactory;
|
||||
import com.hp.hpl.jena.iri.Violation;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.Query;
|
||||
import com.hp.hpl.jena.query.QueryExecution;
|
||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
||||
import com.hp.hpl.jena.query.QueryFactory;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.query.Syntax;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryFieldLabels;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIEdge;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UniqueIDGenerator;
|
||||
|
||||
public class CoPIGrantCountQueryRunner implements QueryRunner<CoPIData> {
|
||||
|
||||
private static final int MAX_PI_PER_GRANT_ALLOWED = 100;
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String egoURI;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private Log log;
|
||||
|
||||
private UniqueIDGenerator nodeIDGenerator;
|
||||
|
||||
private UniqueIDGenerator edgeIDGenerator;
|
||||
|
||||
public CoPIGrantCountQueryRunner(String egoURI,
|
||||
DataSource dataSource, Log log) {
|
||||
|
||||
this.egoURI = egoURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
|
||||
this.nodeIDGenerator = new UniqueIDGenerator();
|
||||
this.edgeIDGenerator = new UniqueIDGenerator();
|
||||
|
||||
}
|
||||
|
||||
private String generateEgoCoPIquery(String queryURI) {
|
||||
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT "
|
||||
+ " (str(<" + queryURI + ">) as ?" + QueryFieldLabels.PI_URL + ") "
|
||||
+ " (str(?PILabel) as ?" + QueryFieldLabels.PI_LABEL + ") "
|
||||
+ " (str(?Grant) as ?" + QueryFieldLabels.GRANT_URL + ") "
|
||||
+ " (str(?GrantLabel) as ?" + QueryFieldLabels.GRANT_LABEL + ") "
|
||||
+ " (str(?GrantStartDate) as ?" + QueryFieldLabels.GRANT_START_DATE + ") "
|
||||
+ " (str(?GrantEndDate) as ?" + QueryFieldLabels.GRANT_END_DATE + ") "
|
||||
+ " (str(?CoPI) as ?" + QueryFieldLabels.CO_PI_URL + ") "
|
||||
+ " (str(?CoPILabel) as ?" + QueryFieldLabels.CO_PI_LABEL + ") "
|
||||
+ "WHERE { "
|
||||
+ "<" + queryURI + "> rdfs:label ?PILabel ;"
|
||||
+ " core:hasCo-PrincipalInvestigatorRole ?Role . "
|
||||
+ "?Role core:roleIn ?Grant . "
|
||||
+ "?Grant rdfs:label ?GrantLabel ; "
|
||||
+ "core:startDate ?GrantStartDate ; "
|
||||
+ "core:endDate ?GrantEndDate ;"
|
||||
+ "core:relatedRole ?RelatedRole . "
|
||||
+ "?RelatedRole core:co-PrincipalInvestigatorRoleOf ?CoPI . "
|
||||
+ "?CoPI rdfs:label ?CoPILabel . "
|
||||
+ " }";
|
||||
|
||||
System.out.println("COPI QUERY - " + sparqlQuery);
|
||||
|
||||
return sparqlQuery;
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryText, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
try {
|
||||
Query query = QueryFactory.create(queryText, SYNTAX);
|
||||
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
|
||||
if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
} finally {
|
||||
if (queryExecution != null) {
|
||||
queryExecution.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public CoPIData getQueryResult()
|
||||
throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.egoURI)) {
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
* */
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
IRI iri = iRIFactory.create(this.egoURI);
|
||||
if (iri.hasViolation(false)) {
|
||||
String errorMsg = ((Violation) iri.violations(false).next()).getShortMessage();
|
||||
log.error("Ego Co-PI Vis Query " + errorMsg);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an individual is malformed.");
|
||||
}
|
||||
} else {
|
||||
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(generateEgoCoPIquery(this.egoURI),
|
||||
this.dataSource);
|
||||
return createQueryResult(resultSet);
|
||||
}
|
||||
|
||||
|
||||
private CoPIEdge getExistingEdge(
|
||||
CoPINode collaboratingNode1,
|
||||
CoPINode collaboratingNode2,
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
|
||||
|
||||
String edgeUniqueIdentifier = getEdgeUniqueIdentifier(collaboratingNode1.getNodeID(),
|
||||
collaboratingNode2.getNodeID());
|
||||
|
||||
return edgeUniqueIdentifierToVO.get(edgeUniqueIdentifier);
|
||||
|
||||
}
|
||||
|
||||
private String getEdgeUniqueIdentifier(int nodeID1, int nodeID2) {
|
||||
|
||||
String separator = "*";
|
||||
|
||||
if (nodeID1 < nodeID2) {
|
||||
return nodeID1 + separator + nodeID2;
|
||||
} else {
|
||||
return nodeID2 + separator + nodeID1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CoPIData createQueryResult(ResultSet resultSet) {
|
||||
|
||||
Set<CoPINode> nodes = new HashSet<CoPINode>();
|
||||
|
||||
Map<String, Grant> grantURLToVO = new HashMap<String, Grant>();
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs = new HashMap<String, Set<CoPINode>>();
|
||||
Map<String, CoPINode> nodeURLToVO = new HashMap<String, CoPINode>();
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO = new HashMap<String, CoPIEdge>();
|
||||
|
||||
CoPINode egoNode = null;
|
||||
|
||||
Set<CoPIEdge> edges = new HashSet<CoPIEdge>();
|
||||
|
||||
while (resultSet.hasNext()) {
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
/*
|
||||
* We only want to create only ONE ego node.
|
||||
* */
|
||||
RDFNode egoPIURLNode = solution.get(QueryFieldLabels.PI_URL);
|
||||
if (nodeURLToVO.containsKey(egoPIURLNode.toString())) {
|
||||
|
||||
egoNode = nodeURLToVO.get(egoPIURLNode.toString());
|
||||
|
||||
} else {
|
||||
|
||||
egoNode = new CoPINode(egoPIURLNode.toString(), nodeIDGenerator);
|
||||
nodes.add(egoNode);
|
||||
nodeURLToVO.put(egoPIURLNode.toString(), egoNode);
|
||||
|
||||
RDFNode authorLabelNode = solution.get(QueryFieldLabels.PI_LABEL);
|
||||
if (authorLabelNode != null) {
|
||||
egoNode.setNodeName(authorLabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
RDFNode grantNode = solution.get(QueryFieldLabels.GRANT_URL);
|
||||
Grant grant;
|
||||
|
||||
if (grantURLToVO.containsKey(grantNode.toString())) {
|
||||
grant = grantURLToVO.get(grantNode.toString());
|
||||
} else {
|
||||
grant = createGrantVO(solution, grantNode.toString());
|
||||
grantURLToVO.put(grantNode.toString(), grant);
|
||||
}
|
||||
|
||||
egoNode.addGrant(grant);
|
||||
|
||||
/*
|
||||
* After some discussion we concluded that for the purpose of this visualization
|
||||
* we do not want a co-pi node or edge if the grant has only one
|
||||
* pi and that happens to be the ego.
|
||||
* */
|
||||
if (solution.get(QueryFieldLabels.PI_URL).toString().equalsIgnoreCase(
|
||||
solution.get(QueryFieldLabels.CO_PI_URL).toString())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CoPINode coPINode;
|
||||
|
||||
RDFNode coPIURLNode = solution.get(QueryFieldLabels.CO_PI_URL);
|
||||
if (nodeURLToVO.containsKey(coPIURLNode.toString())) {
|
||||
|
||||
coPINode = nodeURLToVO.get(coPIURLNode.toString());
|
||||
|
||||
} else {
|
||||
|
||||
coPINode = new CoPINode(coPIURLNode.toString(), nodeIDGenerator);
|
||||
nodes.add(coPINode);
|
||||
nodeURLToVO.put(coPIURLNode.toString(), coPINode);
|
||||
|
||||
RDFNode coPILabelNode = solution.get(QueryFieldLabels.CO_PI_LABEL);
|
||||
if (coPILabelNode != null) {
|
||||
coPINode.setNodeName(coPILabelNode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
coPINode.addGrant(grant);
|
||||
|
||||
Set<CoPINode> coPIsForCurrentGrant;
|
||||
|
||||
if (grantURLToCoPIs.containsKey(grant.getGrantURL())) {
|
||||
coPIsForCurrentGrant = grantURLToCoPIs
|
||||
.get(grant.getGrantURL());
|
||||
} else {
|
||||
coPIsForCurrentGrant = new HashSet<CoPINode>();
|
||||
grantURLToCoPIs.put(grant.getGrantURL(),
|
||||
coPIsForCurrentGrant);
|
||||
}
|
||||
|
||||
coPIsForCurrentGrant.add(coPINode);
|
||||
|
||||
CoPIEdge egoCoPIEdge = getExistingEdge(egoNode, coPINode, edgeUniqueIdentifierToVO);
|
||||
|
||||
/*
|
||||
* If "egoCoPIEdge" is null it means that no edge exists in between the egoNode
|
||||
* & current coPINode. Else create a new edge, add it to the edges set & add
|
||||
* the collaborator grant to it.
|
||||
* */
|
||||
if (egoCoPIEdge != null) {
|
||||
egoCoPIEdge.addCollaboratorGrant(grant);
|
||||
} else {
|
||||
egoCoPIEdge = new CoPIEdge(egoNode, coPINode, grant, edgeIDGenerator);
|
||||
edges.add(egoCoPIEdge);
|
||||
edgeUniqueIdentifierToVO.put(
|
||||
getEdgeUniqueIdentifier(egoNode.getNodeID(),
|
||||
coPINode.getNodeID()),
|
||||
egoCoPIEdge);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This method takes out all the PIs & edges between PIs that belong to grants
|
||||
* that have more than 100 PIs. We conjecture that these grants do not provide much
|
||||
* insight. However, we have left the grants be.
|
||||
*
|
||||
* This method side-effects "nodes" & "edges".
|
||||
* */
|
||||
removeLowQualityNodesAndEdges(nodes,
|
||||
grantURLToVO,
|
||||
grantURLToCoPIs,
|
||||
edges);
|
||||
/*
|
||||
* We need to create edges between 2 co-PIs. E.g. On a grant there were 3 PI
|
||||
* ego, A & B then we have already created edges like,
|
||||
* ego - A
|
||||
* ego - B
|
||||
* The below sub-routine will take care of,
|
||||
* A - B
|
||||
*
|
||||
* We are side-effecting "edges" here. The only reason to do this is because we are adding
|
||||
* edges en masse for all the co-PIs on all the grants considered so far. The
|
||||
* other reason being we dont want to compare against 2 sets of edges (edges created before
|
||||
* & co-PI edges created during the course of this method) when we are creating a new
|
||||
* edge.
|
||||
* */
|
||||
createCoPIEdges(grantURLToVO,
|
||||
grantURLToCoPIs,
|
||||
edges,
|
||||
edgeUniqueIdentifierToVO);
|
||||
|
||||
|
||||
return new CoPIData(egoNode, nodes, edges);
|
||||
}
|
||||
|
||||
private void createCoPIEdges(Map<String, Grant> grantURLToVO,
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges,
|
||||
Map<String, CoPIEdge> edgeUniqueIdentifierToVO) {
|
||||
|
||||
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
|
||||
: grantURLToCoPIs.entrySet()) {
|
||||
|
||||
/*
|
||||
* If there was only one co-PI (other than ego) then we dont have to create any
|
||||
* edges. so the below condition will take care of that.
|
||||
*
|
||||
* We are restricting edges between co-PI if a particular grant has more than
|
||||
* 100 co-PIs. Our conjecture is that such edges do not provide any good insight
|
||||
* & causes unnecessary computations causing the server to time-out.
|
||||
* */
|
||||
if (currentGrantEntry.getValue().size() > 1
|
||||
&& currentGrantEntry.getValue().size()
|
||||
<= MAX_PI_PER_GRANT_ALLOWED) {
|
||||
|
||||
|
||||
Set<CoPIEdge> newlyAddedEdges = new HashSet<CoPIEdge>();
|
||||
|
||||
/*
|
||||
* In order to leverage the nested "for loop" for making edges between all the
|
||||
* co-PIs we need to create a list out of the set first.
|
||||
* */
|
||||
List<CoPINode> coPINodes = new ArrayList<CoPINode>(currentGrantEntry.getValue());
|
||||
Collections.sort(coPINodes, new CoPINodeComparator());
|
||||
|
||||
int numOfCoPIs = coPINodes.size();
|
||||
|
||||
for (int ii = 0; ii < numOfCoPIs - 1; ii++) {
|
||||
for (int jj = ii + 1; jj < numOfCoPIs; jj++) {
|
||||
|
||||
CoPINode coPI1 = coPINodes.get(ii);
|
||||
CoPINode coPI2 = coPINodes.get(jj);
|
||||
|
||||
CoPIEdge coPI1_2Edge = getExistingEdge(coPI1,
|
||||
coPI2,
|
||||
edgeUniqueIdentifierToVO);
|
||||
|
||||
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
|
||||
|
||||
if (coPI1_2Edge != null) {
|
||||
coPI1_2Edge.addCollaboratorGrant(currentGrant);
|
||||
} else {
|
||||
coPI1_2Edge = new CoPIEdge(coPI1,
|
||||
coPI2,
|
||||
currentGrant,
|
||||
edgeIDGenerator);
|
||||
newlyAddedEdges.add(coPI1_2Edge);
|
||||
edgeUniqueIdentifierToVO.put(
|
||||
getEdgeUniqueIdentifier(coPI1.getNodeID(),
|
||||
coPI2.getNodeID()),
|
||||
coPI1_2Edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
edges.addAll(newlyAddedEdges);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void removeLowQualityNodesAndEdges(Set<CoPINode> nodes,
|
||||
Map<String, Grant> grantURLToVO,
|
||||
Map<String, Set<CoPINode>> grantURLToCoPIs, Set<CoPIEdge> edges) {
|
||||
|
||||
Set<CoPINode> nodesToBeRemoved = new HashSet<CoPINode>();
|
||||
for (Map.Entry<String, Set<CoPINode>> currentGrantEntry
|
||||
: grantURLToCoPIs.entrySet()) {
|
||||
|
||||
if (currentGrantEntry.getValue().size() > MAX_PI_PER_GRANT_ALLOWED) {
|
||||
|
||||
Grant currentGrant = grantURLToVO.get(currentGrantEntry.getKey());
|
||||
|
||||
Set<CoPIEdge> edgesToBeRemoved = new HashSet<CoPIEdge>();
|
||||
|
||||
for (CoPIEdge currentEdge : edges) {
|
||||
Set<Grant> currentCollaboratorGrants =
|
||||
currentEdge.getCollaboratorGrants();
|
||||
|
||||
if (currentCollaboratorGrants.contains(currentGrant)) {
|
||||
currentCollaboratorGrants.remove(currentGrant);
|
||||
if (currentCollaboratorGrants.isEmpty()) {
|
||||
edgesToBeRemoved.add(currentEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edges.removeAll(edgesToBeRemoved);
|
||||
|
||||
for (CoPINode currentCoPI : currentGrantEntry.getValue()) {
|
||||
currentCoPI.getInvestigatedGrants().remove(currentGrant);
|
||||
if (currentCoPI.getInvestigatedGrants().isEmpty()) {
|
||||
nodesToBeRemoved.add(currentCoPI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes.removeAll(nodesToBeRemoved);
|
||||
|
||||
}
|
||||
|
||||
private Grant createGrantVO(QuerySolution solution, String grantURL) {
|
||||
|
||||
Grant grant = new Grant(grantURL);
|
||||
|
||||
RDFNode grantLabelNode = solution.get(QueryFieldLabels.GRANT_LABEL);
|
||||
if (grantLabelNode != null) {
|
||||
grant.setIndividualLabel(grantLabelNode.toString());
|
||||
}
|
||||
|
||||
|
||||
RDFNode grantStartYear = solution.get(QueryFieldLabels.GRANT_START_DATE);
|
||||
if (grantStartYear != null) {
|
||||
grant.setGrantStartDate(grantStartYear.toString());
|
||||
}
|
||||
|
||||
RDFNode grantEndDate = solution.get(QueryFieldLabels
|
||||
.GRANT_END_DATE);
|
||||
if (grantEndDate != null) {
|
||||
grant.setGrantEndDate(grantEndDate.toString());
|
||||
}
|
||||
|
||||
return grant;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
|
||||
|
||||
public class CoPIGrantCountRequestHandler implements VisualizationRequestHandler{
|
||||
|
||||
public void generateVisualization(VitroRequest vitroRequest, HttpServletRequest request, HttpServletResponse response, Log log, DataSource dataSource){
|
||||
|
||||
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
|
||||
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
||||
QueryRunner<CoPIData> queryManager = new CoPIGrantCountQueryRunner(egoURI, dataSource, log);
|
||||
|
||||
try{
|
||||
CoPIData PINodesAndEdges = queryManager.getQueryResult();
|
||||
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
if (VisualizationFrameworkConstants.COPI_VIS_MODE
|
||||
.equalsIgnoreCase(visMode)) {
|
||||
|
||||
prepareCoPIDataResponse(PINodesAndEdges, response);
|
||||
return;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* When the graphML file is required - based on which copi network
|
||||
* visualization will be rendered.
|
||||
* */
|
||||
prepareNetworkDataResponse(PINodesAndEdges, response);
|
||||
return;
|
||||
}
|
||||
}else {
|
||||
|
||||
RequestDispatcher requestDispatcher = null;
|
||||
|
||||
prepareStandaloneResponse(
|
||||
egoURI,
|
||||
PINodesAndEdges,
|
||||
vitroRequest,
|
||||
request);
|
||||
|
||||
requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
|
||||
try {
|
||||
requestDispatcher.forward(request, response);
|
||||
} catch (Exception e) {
|
||||
log.error("EntityEditController could not forward to view.");
|
||||
log.error(e.getMessage());
|
||||
log.error(e.getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
}catch(MalformedQueryParametersException e){
|
||||
try {
|
||||
UtilityFunctions.handleMalformedParameters(
|
||||
e.getMessage(),
|
||||
"Visualization Query Error - Co-authorship Network",
|
||||
vitroRequest,
|
||||
request,
|
||||
response,
|
||||
log);
|
||||
} catch (ServletException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
} catch (IOException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the page for person level visualization is requested.
|
||||
* @param egoURI
|
||||
* @param coPIVO
|
||||
* @param vitroRequest
|
||||
* @param request
|
||||
*/
|
||||
private void prepareStandaloneResponse(String egoURI,
|
||||
CoPIData pINodesAndEdges, VitroRequest vitroRequest,
|
||||
HttpServletRequest request) {
|
||||
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
|
||||
request.setAttribute("egoURIParam", egoURI);
|
||||
|
||||
String title = "";
|
||||
if (pINodesAndEdges.getNodes() != null
|
||||
&& pINodesAndEdges.getNodes().size() > 0) {
|
||||
request.setAttribute("numOfAuthors", pINodesAndEdges.getNodes()
|
||||
.size());
|
||||
title = pINodesAndEdges.getEgoNode().getNodeName() + " - ";
|
||||
}
|
||||
|
||||
if (pINodesAndEdges.getEdges() != null
|
||||
&& pINodesAndEdges.getEdges().size() > 0) {
|
||||
request.setAttribute("numOfCoPIs", pINodesAndEdges
|
||||
.getEdges().size());
|
||||
}
|
||||
|
||||
request.setAttribute("title", title + "Co-PI Visualization");
|
||||
request.setAttribute("portalBean", portal);
|
||||
request.setAttribute("scripts",
|
||||
"/templates/visualization/person_level_inject_head.jsp");
|
||||
request.setAttribute("bodyJsp",
|
||||
"/templates/visualization/co_authorship.jsp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a response when graphml formatted co-pi network is requested, typically by
|
||||
* the flash vis.
|
||||
* @param pINodesAndEdges
|
||||
* @param response
|
||||
*/
|
||||
private void prepareNetworkDataResponse(CoPIData pINodesAndEdges,
|
||||
HttpServletResponse response) {
|
||||
|
||||
response.setContentType("text/xml");
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter responseWriter = response.getWriter();
|
||||
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||
* object of the servlet.
|
||||
* */
|
||||
CoPIGraphMLWriter coPIGraphMLWriter =
|
||||
new CoPIGraphMLWriter(pINodesAndEdges);
|
||||
|
||||
responseWriter.append(coPIGraphMLWriter.getCoPIGraphMLContent());
|
||||
|
||||
responseWriter.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when a csv file containing number & names of unique co-pis per
|
||||
* year is requested.
|
||||
* @param pINodesAndEdges
|
||||
* @param response
|
||||
*/
|
||||
private void prepareCoPIDataResponse(CoPIData pINodesAndEdges,
|
||||
HttpServletResponse response) {
|
||||
|
||||
String outputFileName;
|
||||
Map<String, Set<CoPINode>> yearToCoPI = new TreeMap<String, Set<CoPINode>>();
|
||||
|
||||
if (pINodesAndEdges.getNodes() != null && pINodesAndEdges.getNodes().size() > 0) {
|
||||
|
||||
outputFileName = UtilityFunctions.slugify(pINodesAndEdges
|
||||
.getEgoNode().getNodeName())
|
||||
+ "_copis-per-year" + ".csv";
|
||||
|
||||
yearToCoPI = UtilityFunctions.getGrantYearToCoPI(pINodesAndEdges);
|
||||
|
||||
} else {
|
||||
|
||||
outputFileName = "no_copis-per-year" + ".csv";
|
||||
}
|
||||
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment;filename=" + outputFileName);
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter responseWriter = response.getWriter();
|
||||
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||
* object of the servlet.
|
||||
* */
|
||||
writeCoPIsPerYearCSV(yearToCoPI, responseWriter);
|
||||
|
||||
responseWriter.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeCoPIsPerYearCSV(Map<String, Set<CoPINode>> yearToCoPI,
|
||||
PrintWriter responseWriter) {
|
||||
responseWriter.append("Year, Count, Co-PI(s)\n");
|
||||
for (Map.Entry<String, Set<CoPINode>> currentEntry : yearToCoPI.entrySet()) {
|
||||
|
||||
responseWriter.append("\"" + currentEntry.getKey() + "\","
|
||||
+ "\"" + currentEntry.getValue().size() + "\","
|
||||
+ "\"" + getCoPINamesAsString(currentEntry.getValue())
|
||||
+ "\"\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getCoPINamesAsString(Set<CoPINode> CoPIs) {
|
||||
|
||||
StringBuilder coPIsMerged = new StringBuilder();
|
||||
|
||||
String coPISeparator = ";";
|
||||
for(CoPINode currentCoPI : CoPIs){
|
||||
coPIsMerged.append(currentCoPI.getNodeName() + coPISeparator);
|
||||
}
|
||||
|
||||
return StringUtils.removeEnd(coPIsMerged.toString(), coPISeparator);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIEdge;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
public class CoPIGraphMLWriter {
|
||||
|
||||
private StringBuilder coPIGraphMLContent;
|
||||
|
||||
private final String GRAPHML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ " <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n"
|
||||
+ " http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n\n";
|
||||
|
||||
private final String GRAPHML_FOOTER = "</graphml>";
|
||||
|
||||
public CoPIGraphMLWriter(CoPIData coPIData){
|
||||
coPIGraphMLContent = createCoPIGraphMLContent(coPIData);
|
||||
}
|
||||
|
||||
private StringBuilder createCoPIGraphMLContent(CoPIData coPIData) {
|
||||
|
||||
StringBuilder graphMLContent = new StringBuilder();
|
||||
|
||||
graphMLContent.append(GRAPHML_HEADER);
|
||||
|
||||
/*
|
||||
* We are side-effecting "graphMLContent" object in this method since creating
|
||||
* another String object to hold key definition data will be redundant & will
|
||||
* not serve the purpose.
|
||||
* */
|
||||
generateKeyDefinitionContent(coPIData, graphMLContent);
|
||||
|
||||
/*
|
||||
* Used to generate graph content. It will contain both the nodes & edge information.
|
||||
* We are side-effecting "graphMLContent".
|
||||
* */
|
||||
generateGraphContent(coPIData, graphMLContent);
|
||||
|
||||
graphMLContent.append(GRAPHML_FOOTER);
|
||||
|
||||
return graphMLContent;
|
||||
}
|
||||
|
||||
public StringBuilder getCoPIGraphMLContent(){
|
||||
return coPIGraphMLContent;
|
||||
}
|
||||
|
||||
private void generateGraphContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("\n<graph edgedefault=\"undirected\">\n");
|
||||
|
||||
if (coPIData.getNodes() != null & coPIData.getNodes().size() > 0) {
|
||||
generateNodeSectionContent(coPIData, graphMLContent);
|
||||
}
|
||||
|
||||
if (coPIData.getEdges() != null & coPIData.getEdges().size() > 0) {
|
||||
generateEdgeSectionContent(coPIData, graphMLContent);
|
||||
}
|
||||
|
||||
graphMLContent.append("</graph>\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void generateEdgeSectionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("<!-- edges -->\n");
|
||||
|
||||
Set<CoPIEdge> edges = coPIData.getEdges();
|
||||
|
||||
List<CoPIEdge> orderedEdges = new ArrayList<CoPIEdge>(edges);
|
||||
|
||||
Collections.sort(orderedEdges, new CoPIEdgeComparator());
|
||||
|
||||
for (CoPIEdge currentEdge : orderedEdges) {
|
||||
|
||||
/*
|
||||
* This method actually creates the XML code for a single edge. "graphMLContent"
|
||||
* is being side-effected.
|
||||
* */
|
||||
getEdgeContent(graphMLContent, currentEdge);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getEdgeContent(StringBuilder graphMLContent, CoPIEdge currentEdge) {
|
||||
|
||||
graphMLContent.append("<edge "
|
||||
+ "id=\"" + currentEdge.getEdgeID() + "\" "
|
||||
+ "source=\"" + currentEdge.getSourceNode().getNodeID() + "\" "
|
||||
+ "target=\"" + currentEdge.getTargetNode().getNodeID() + "\" "
|
||||
+ ">\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"collaborator1\">"
|
||||
+ currentEdge.getSourceNode().getNodeName()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"collaborator2\">"
|
||||
+ currentEdge.getTargetNode().getNodeName()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"number_of_coinvestigated_grants\">"
|
||||
+ currentEdge.getNumberOfCoInvestigatedGrants()
|
||||
+ "</data>\n");
|
||||
|
||||
if (currentEdge.getEarliestCollaborationYearCount() != null) {
|
||||
|
||||
/*
|
||||
* There is no clean way of getting the map contents in java even though
|
||||
* we are sure to have only one entry on the map. So using the for loop.
|
||||
* */
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: currentEdge.getEarliestCollaborationYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"earliest_collaboration\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_earliest_collaboration\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (currentEdge.getLatestCollaborationYearCount() != null) {
|
||||
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: currentEdge.getLatestCollaborationYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"latest_collaboration\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_latest_collaboration\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (currentEdge.getUnknownCollaborationYearCount() != null) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_unknown_collaboration\">"
|
||||
+ currentEdge.getUnknownCollaborationYearCount()
|
||||
+ "</data>\n");
|
||||
|
||||
}
|
||||
|
||||
graphMLContent.append("</edge>\n");
|
||||
}
|
||||
|
||||
|
||||
private void generateNodeSectionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
graphMLContent.append("<!-- nodes -->\n");
|
||||
|
||||
CoPINode egoNode = coPIData.getEgoNode();
|
||||
Set<CoPINode> piNodes = coPIData.getNodes();
|
||||
|
||||
/*
|
||||
* This method actually creates the XML code for a single node. "graphMLContent"
|
||||
* is being side-effected. The egoNode is added first because this is the "requirement"
|
||||
* of the co-pi vis. Ego should always come first.
|
||||
*
|
||||
* */
|
||||
getNodeContent(graphMLContent, egoNode);
|
||||
|
||||
List<CoPINode> orderedPINodes = new ArrayList<CoPINode>(piNodes);
|
||||
orderedPINodes.remove(egoNode);
|
||||
|
||||
Collections.sort(orderedPINodes, new CoPINodeComparator());
|
||||
|
||||
|
||||
for (CoPINode currNode : orderedPINodes) {
|
||||
|
||||
/*
|
||||
* We have already printed the Ego Node info.
|
||||
* */
|
||||
if (currNode != egoNode) {
|
||||
|
||||
getNodeContent(graphMLContent, currNode);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getNodeContent(StringBuilder graphMLContent, CoPINode node) {
|
||||
|
||||
String profileURL = null;
|
||||
try {
|
||||
profileURL = VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX + "?"
|
||||
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY
|
||||
+ "=" + URLEncoder.encode(node.getNodeURI(),
|
||||
VisualizationController
|
||||
.URL_ENCODING_SCHEME).toString();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
System.err.println("URL Encoding Error. Move this to use log.error ASAP");
|
||||
}
|
||||
|
||||
graphMLContent.append("<node id=\"" + node.getNodeID() + "\">\n");
|
||||
graphMLContent.append("\t<data key=\"url\">" + node.getNodeURI() + "</data>\n");
|
||||
graphMLContent.append("\t<data key=\"label\">" + node.getNodeName() + "</data>\n");
|
||||
|
||||
if (profileURL != null) {
|
||||
graphMLContent.append("\t<data key=\"profile_url\">" + profileURL + "</data>\n");
|
||||
}
|
||||
|
||||
|
||||
graphMLContent.append("\t<data key=\"number_of_investigated_grants\">"
|
||||
+ node.getNumberOfInvestigatedGrants()
|
||||
+ "</data>\n");
|
||||
|
||||
if (node.getEarliestGrantYearCount() != null) {
|
||||
|
||||
/*
|
||||
* There is no clean way of getting the map contents in java even though
|
||||
* we are sure to have only one entry on the map. So using the for loop.
|
||||
* I am feeling dirty just about now.
|
||||
* */
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: node.getEarliestGrantYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"earliest_grant\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_earliest_grant\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (node.getLatestGrantYearCount() != null) {
|
||||
|
||||
for (Map.Entry<String, Integer> publicationInfo
|
||||
: node.getLatestGrantYearCount().entrySet()) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"latest_grant\">"
|
||||
+ publicationInfo.getKey()
|
||||
+ "</data>\n");
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_latest_grant\">"
|
||||
+ publicationInfo.getValue()
|
||||
+ "</data>\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (node.getUnknownGrantYearCount() != null) {
|
||||
|
||||
graphMLContent.append("\t<data key=\"num_unknown_grant\">"
|
||||
+ node.getUnknownGrantYearCount()
|
||||
+ "</data>\n");
|
||||
|
||||
}
|
||||
|
||||
graphMLContent.append("</node>\n");
|
||||
}
|
||||
|
||||
private void generateKeyDefinitionContent(CoPIData coPIData,
|
||||
StringBuilder graphMLContent) {
|
||||
/*
|
||||
* Generate the key definition content for node.
|
||||
* */
|
||||
getKeyDefinitionFromSchema(coPIData.getNodeSchema(), graphMLContent);
|
||||
|
||||
/*
|
||||
* Generate the key definition content for edge.
|
||||
* */
|
||||
getKeyDefinitionFromSchema(coPIData.getEdgeSchema(), graphMLContent);
|
||||
}
|
||||
|
||||
private void getKeyDefinitionFromSchema(Set<Map<String, String>> schema,
|
||||
StringBuilder graphMLContent) {
|
||||
|
||||
for (Map<String, String> currentNodeSchemaAttribute : schema) {
|
||||
|
||||
graphMLContent.append("\n<key ");
|
||||
|
||||
for (Map.Entry<String, String> currentAttributeKey
|
||||
: currentNodeSchemaAttribute.entrySet()) {
|
||||
|
||||
graphMLContent.append(currentAttributeKey.getKey()
|
||||
+ "=\"" + currentAttributeKey.getValue()
|
||||
+ "\" ");
|
||||
|
||||
}
|
||||
|
||||
if (currentNodeSchemaAttribute.containsKey("default")) {
|
||||
|
||||
graphMLContent.append(">\n");
|
||||
graphMLContent.append("<default>");
|
||||
graphMLContent.append(currentNodeSchemaAttribute.get("default"));
|
||||
graphMLContent.append("</default>\n");
|
||||
graphMLContent.append("</key>\n");
|
||||
|
||||
} else {
|
||||
graphMLContent.append("/>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
|
||||
/**
|
||||
* This Comparator is used to sort the CoPINodes based on their IDs in ascending order.
|
||||
* @author bkoniden
|
||||
*/
|
||||
|
||||
public class CoPINodeComparator implements Comparator<CoPINode>{
|
||||
@Override
|
||||
public int compare(CoPINode arg0, CoPINode arg1) {
|
||||
return arg0.getNodeID() - arg1.getNodeID();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Entity;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SubEntity;
|
||||
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
|
||||
* department/school/university.
|
||||
*
|
||||
* @author bkoniden
|
||||
*/
|
||||
public class EntityPublicationCountQueryRunner implements QueryRunner<Entity> {
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String entityURI;
|
||||
private DataSource dataSource;
|
||||
private Log log;
|
||||
private String visMode;
|
||||
|
||||
private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = ""
|
||||
+ " (str(?Person) as ?personLit) "
|
||||
+ " (str(?PersonLabel) as ?personLabelLit) "
|
||||
+ " (str(?SecondaryPositionLabel) as ?SecondaryPositionLabelLit)"
|
||||
+ " (str(?Document) as ?documentLit) "
|
||||
+ " (str(?DocumentLabel) as ?documentLabelLit) "
|
||||
+ " (str(?publicationYear) as ?publicationYearLit) "
|
||||
+ " (str(?publicationYearMonth) as ?publicationYearMonthLit) "
|
||||
+ " (str(?publicationDate) as ?publicationDateLit) "
|
||||
+ " (str(?StartYear) as ?StartYearLit)";
|
||||
|
||||
|
||||
private static final String SPARQL_QUERY_COMMON_WHERE_CLAUSE = ""
|
||||
+ "?Document rdf:type bibo:Document ;"
|
||||
+ " rdfs:label ?DocumentLabel ."
|
||||
+ "OPTIONAL { ?Document core:year ?publicationYear } ."
|
||||
+ "OPTIONAL { ?Document core:yearMonth ?publicationYearMonth } ."
|
||||
+ "OPTIONAL { ?Document core:date ?publicationDate } ."
|
||||
+ "OPTIONAL { ?SecondaryPosition core:startYear ?StartYear } .";
|
||||
|
||||
private static String ENTITY_LABEL;
|
||||
private static String ENTITY_URL;
|
||||
private static String SUBENTITY_LABEL;
|
||||
private static String SUBENTITY_URL;
|
||||
|
||||
public EntityPublicationCountQueryRunner(String entityURI,
|
||||
DataSource dataSource, Log log, String visMode) {
|
||||
|
||||
this.entityURI = entityURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
this.visMode = visMode;
|
||||
|
||||
}
|
||||
|
||||
private Entity createJavaValueObjects(ResultSet resultSet) {
|
||||
|
||||
Entity entity = null;
|
||||
Map<String, BiboDocument> biboDocumentURLToVO = new HashMap<String, BiboDocument>();
|
||||
Map<String, SubEntity> subentityURLToVO = new HashMap<String, SubEntity>();
|
||||
|
||||
while (resultSet.hasNext()) {
|
||||
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
if (entity == null) {
|
||||
entity = new Entity(solution.get(ENTITY_URL).toString(),
|
||||
solution.get(ENTITY_LABEL).toString());
|
||||
}
|
||||
|
||||
RDFNode documentNode = solution.get(QueryFieldLabels.DOCUMENT_URL);
|
||||
BiboDocument biboDocument;
|
||||
|
||||
if (biboDocumentURLToVO.containsKey(documentNode.toString())) {
|
||||
biboDocument = biboDocumentURLToVO.get(documentNode.toString());
|
||||
|
||||
} else {
|
||||
|
||||
biboDocument = new BiboDocument(documentNode.toString());
|
||||
biboDocumentURLToVO.put(documentNode.toString(), biboDocument);
|
||||
|
||||
RDFNode documentLabelNode = solution
|
||||
.get(QueryFieldLabels.DOCUMENT_LABEL);
|
||||
if (documentLabelNode != null) {
|
||||
biboDocument.setDocumentLabel(documentLabelNode.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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RDFNode subEntityURLNode = solution.get(SUBENTITY_URL);
|
||||
|
||||
if (subEntityURLNode != null) {
|
||||
SubEntity subEntity;
|
||||
if (subentityURLToVO.containsKey(subEntityURLNode.toString())) {
|
||||
subEntity = subentityURLToVO.get(subEntityURLNode
|
||||
.toString());
|
||||
} else {
|
||||
subEntity = new SubEntity(subEntityURLNode.toString());
|
||||
subentityURLToVO
|
||||
.put(subEntityURLNode.toString(), subEntity);
|
||||
}
|
||||
|
||||
RDFNode subEntityLabelNode = solution.get(SUBENTITY_LABEL);
|
||||
if (subEntityLabelNode != null) {
|
||||
subEntity.setIndividualLabel(subEntityLabelNode.toString());
|
||||
}
|
||||
entity.addSubEntity(subEntity);
|
||||
subEntity.addPublications(biboDocument);
|
||||
}
|
||||
|
||||
entity.addPublications(biboDocument);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryURI, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
try {
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI, this.visMode), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
|
||||
if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
} finally {
|
||||
if (queryExecution != null) {
|
||||
queryExecution.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getSparqlQuery(String queryURI, String visMode) {
|
||||
String result = "";
|
||||
|
||||
if (visMode.equals("DEPARTMENT")) {
|
||||
result = getSparqlQueryForDepartment(queryURI);
|
||||
ENTITY_URL = QueryFieldLabels.DEPARTMENT_URL;
|
||||
ENTITY_LABEL = QueryFieldLabels.DEPARTMENT_LABEL;
|
||||
SUBENTITY_URL = QueryFieldLabels.PERSON_URL;
|
||||
SUBENTITY_LABEL = QueryFieldLabels.PERSON_LABEL;
|
||||
} else {
|
||||
result = getSparqlQueryForOrganization(queryURI);
|
||||
ENTITY_URL = QueryFieldLabels.ORGANIZATION_URL;
|
||||
ENTITY_LABEL = QueryFieldLabels.ORGANIZATION_LABEL;
|
||||
SUBENTITY_URL = QueryFieldLabels.SUBORGANIZATION_URL;
|
||||
SUBENTITY_LABEL = QueryFieldLabels.SUBORGANIZATION_LABEL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getSparqlQueryForDepartment(String queryURI) {
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT (str(?DepartmentLabel) as ?departmentLabelLit) "
|
||||
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE + " (str(<" + queryURI
|
||||
+ ">) as ?" + QueryFieldLabels.DEPARTMENT_URL + ") "
|
||||
+ "WHERE { " + "<" + queryURI + "> rdf:type core:Department ;"
|
||||
+ " rdfs:label ?DepartmentLabel ;"
|
||||
+ " core:organizationForPosition ?Position . "
|
||||
+ " ?Position rdf:type core:Position ;"
|
||||
+ " core:positionForPerson ?Person . "
|
||||
+ " ?Person core:authorInAuthorship ?Resource ; "
|
||||
+ " rdfs:label ?PersonLabel ; core:personInPosition ?SecondaryPosition . "
|
||||
+ " ?Resource core:linkedInformationResource ?Document ."
|
||||
+ " ?SecondaryPosition rdfs:label ?SecondaryPositionLabel ."
|
||||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}"
|
||||
+ " ORDER BY ?DocumentLabel";
|
||||
System.out.println("\nThe sparql query is :\n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
|
||||
}
|
||||
|
||||
private String getSparqlQueryForOrganization(String queryURI) {
|
||||
|
||||
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT (str(?organizationLabel) as ?organizationLabelLit) "
|
||||
+ " (str(?subOrganization) as ?subOrganizationLit) "
|
||||
+ " (str(?subOrganizationLabel) as ?subOrganizationLabelLit) "
|
||||
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE + " (str(<" + queryURI
|
||||
+ ">) as ?" + QueryFieldLabels.ORGANIZATION_URL + ") "
|
||||
+ "WHERE { " + "<" + queryURI + "> rdf:type foaf:Organization ;"
|
||||
+ " rdfs:label ?organizationLabel ;"
|
||||
+ " core:hasSubOrganization ?subOrganization ."
|
||||
+ " ?subOrganization rdfs:label ?subOrganizationLabel ;"
|
||||
+ " core:organizationForPosition ?Position . "
|
||||
+ " ?Position rdf:type core:Position ;"
|
||||
+ " core:positionForPerson ?Person . "
|
||||
+ " ?Person core:authorInAuthorship ?Resource ; "
|
||||
+ " rdfs:label ?PersonLabel ; core:personInPosition ?SecondaryPosition . "
|
||||
+ " ?Resource core:linkedInformationResource ?Document ."
|
||||
+ " ?SecondaryPosition rdfs:label ?SecondaryPositionLabel ."
|
||||
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE + "}"
|
||||
+ " ORDER BY ?DocumentLabel";
|
||||
System.out.println("\nThe sparql query is :\n" + sparqlQuery);
|
||||
return sparqlQuery;
|
||||
|
||||
}
|
||||
|
||||
public Entity getQueryResult() throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.entityURI)) {
|
||||
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
*/
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
IRI iri = iRIFactory.create(this.entityURI);
|
||||
if (iri.hasViolation(false)) {
|
||||
String errorMsg = ((Violation) iri.violations(false).next())
|
||||
.getShortMessage();
|
||||
log.error("Entity Comparison vis Query " + errorMsg);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an entity is malformed.");
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new MalformedQueryParametersException(
|
||||
"URL parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(this.entityURI, this.dataSource);
|
||||
|
||||
return createJavaValueObjects(resultSet);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,304 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Entity;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.JsonObject;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SubEntity;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.QueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
|
||||
|
||||
public class EntityPublicationCountRequestHandler implements
|
||||
VisualizationRequestHandler {
|
||||
|
||||
/*
|
||||
* Vis container holds the "id" of the div on the final response html page
|
||||
* that the visualization actually appears on.
|
||||
*/
|
||||
public static String ENTITY_VIS_MODE;
|
||||
public static String SUB_ENTITY_VIS_MODE;
|
||||
|
||||
|
||||
@SuppressWarnings("null")
|
||||
public void generateVisualization(VitroRequest vitroRequest,
|
||||
HttpServletRequest request, HttpServletResponse response, Log log,
|
||||
DataSource dataSource) {
|
||||
|
||||
String entityURI = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
|
||||
String renderMode = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
|
||||
|
||||
ENTITY_VIS_MODE = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
||||
String visContainer = vitroRequest
|
||||
.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_KEY);
|
||||
|
||||
System.out
|
||||
.println("\nInside EntityPublicationCountRequestHandler! \n----------------------------------------- ");
|
||||
System.out.println("\nEntity URI: " + entityURI + "\nRender Mode: "
|
||||
+ renderMode + "\nVis Mode: " + ENTITY_VIS_MODE
|
||||
+ "\nVis Containter: " + visContainer);
|
||||
|
||||
QueryRunner<Entity> queryManager = new EntityPublicationCountQueryRunner(
|
||||
entityURI, dataSource, log, ENTITY_VIS_MODE);
|
||||
|
||||
try {
|
||||
Entity entity = queryManager.getQueryResult();
|
||||
|
||||
if (ENTITY_VIS_MODE.equals("DEPARTMENT")) {
|
||||
|
||||
SUB_ENTITY_VIS_MODE = "PERSON";
|
||||
// System.out
|
||||
// .println("\n\nDocuments within the Entity\n---------------------------------------------");
|
||||
// for (BiboDocument document : entity.getPublications()) {
|
||||
// System.out.println(document.getDocumentLabel() + " > "
|
||||
// + document.getDocumentURL());
|
||||
// }
|
||||
//
|
||||
// System.out
|
||||
// .println("\n\nSubEntities within the Entity\n---------------------------------------------");
|
||||
//
|
||||
// for (SubEntity person : entity.getSubEntities()) {
|
||||
// System.out.println(person.getIndividualLabel());
|
||||
// }
|
||||
}else if (ENTITY_VIS_MODE.equals("SCHOOL")) {
|
||||
|
||||
SUB_ENTITY_VIS_MODE = "DEPARTMENT";
|
||||
// System.out
|
||||
// .println("\nDocuments within the Entity\n---------------------------------------------");
|
||||
// for (BiboDocument document : entity.getPublications()) {
|
||||
// System.out.println(document.getDocumentLabel() + " > "
|
||||
// + document.getDocumentURL());
|
||||
// }
|
||||
//
|
||||
// System.out
|
||||
// .println("\n\nSubEntities within the Entity\n---------------------------------------------");
|
||||
// for (SubEntity department : entity.getSubEntities()) {
|
||||
// System.out.println(department.getIndividualLabel());
|
||||
// }
|
||||
}else {
|
||||
SUB_ENTITY_VIS_MODE = "SCHOOL";
|
||||
// System.out
|
||||
// .println("\nDocuments within the Entity\n---------------------------------------------");
|
||||
// for (BiboDocument document : entity.getPublications()) {
|
||||
// System.out.println(document.getDocumentLabel() + " > "
|
||||
// + document.getDocumentURL());
|
||||
// }
|
||||
//
|
||||
// System.out
|
||||
// .println("\n\nSubEntities within the Entity\n---------------------------------------------");
|
||||
//
|
||||
// for (SubEntity school : entity.getSubEntities()) {
|
||||
// System.out.println(school.getIndividualLabel());
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
QueryRunner<Map<String, Set<String>>> queryManagerForsubOrganisationTypes = new EntitySubOrganizationTypesQueryRunner(
|
||||
entityURI, dataSource, log, ENTITY_VIS_MODE);
|
||||
|
||||
Map<String, Set<String>> subOrganizationTypesResult = queryManagerForsubOrganisationTypes.getQueryResult();
|
||||
|
||||
System.out.println("Sub Organization Types With Their Labels \n------------------");
|
||||
|
||||
for(String label: subOrganizationTypesResult.keySet()){
|
||||
System.out.println("Label :"+ label);
|
||||
for(String type : subOrganizationTypesResult.get(label)){
|
||||
System.out.println("type: "+ type);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
RequestDispatcher requestDispatcher = null;
|
||||
if (VisualizationFrameworkConstants.DATA_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
prepareDataResponse(entity, entity.getSubEntities(),subOrganizationTypesResult, response);
|
||||
|
||||
} else if (VisualizationFrameworkConstants.STANDALONE_RENDER_MODE
|
||||
.equalsIgnoreCase(renderMode)) {
|
||||
|
||||
prepareStandaloneResponse(request, response, vitroRequest,
|
||||
entity, subOrganizationTypesResult);
|
||||
requestDispatcher = request
|
||||
.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
}
|
||||
|
||||
try {
|
||||
requestDispatcher.forward(request, response);
|
||||
} catch (Exception e) {
|
||||
log.error("EntityEditController could not forward to view.");
|
||||
log.error(e.getMessage());
|
||||
log.error(e.getStackTrace());
|
||||
}
|
||||
//
|
||||
} catch (MalformedQueryParametersException e) {
|
||||
try {
|
||||
UtilityFunctions
|
||||
.handleMalformedParameters(
|
||||
e.getMessage(),
|
||||
"Visualization Query Error - Individual Publication Count",
|
||||
vitroRequest, request, response, log);
|
||||
} catch (ServletException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
} catch (IOException e1) {
|
||||
log.error(e1.getStackTrace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when csv file containing the publication count over the
|
||||
* years is requested.
|
||||
*
|
||||
* @param author
|
||||
* @param subentities
|
||||
* @param subOrganizationTypesResult
|
||||
* @param yearToPublicationCount
|
||||
* @param response
|
||||
*/
|
||||
private void prepareDataResponse(Entity entity, Set<SubEntity> subentities,
|
||||
Map<String, Set<String>> subOrganizationTypesResult, HttpServletResponse response) {
|
||||
|
||||
String entityLabel = entity.getEntityLabel();
|
||||
|
||||
String outputFileName = UtilityFunctions.slugify(entityLabel)
|
||||
+ "_publications-per-year" + ".json";
|
||||
|
||||
response.setContentType("text/plain");
|
||||
response.setHeader("Content-Disposition", "attachment;filename="
|
||||
+ outputFileName);
|
||||
|
||||
try {
|
||||
|
||||
PrintWriter responseWriter = response.getWriter();
|
||||
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly
|
||||
* manipulating the response object of the servlet.
|
||||
*/
|
||||
responseWriter.append(writePublicationsOverTimeJSON(subentities, subOrganizationTypesResult));
|
||||
|
||||
responseWriter.flush();
|
||||
responseWriter.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides response when an entire page dedicated to publication sparkline
|
||||
* is requested.
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param vreq
|
||||
* @param entity
|
||||
* @param subOrganizationTypesResult
|
||||
*/
|
||||
private void prepareStandaloneResponse(HttpServletRequest request,
|
||||
HttpServletResponse response, VitroRequest vreq, Entity entity, Map<String, Set<String>> subOrganizationTypesResult) {
|
||||
|
||||
Portal portal = vreq.getPortal();
|
||||
String jsonContent = "";
|
||||
/*
|
||||
* We are side-effecting responseWriter since we are directly
|
||||
* manipulating the response object of the servlet.
|
||||
*/
|
||||
jsonContent = writePublicationsOverTimeJSON(entity.getSubEntities(), subOrganizationTypesResult);
|
||||
|
||||
request.setAttribute("JsonContent", jsonContent);
|
||||
|
||||
request.setAttribute("bodyJsp",
|
||||
"/templates/visualization/entity_comparison.jsp");
|
||||
request.setAttribute("portalBean", portal);
|
||||
request.setAttribute("title", "Entity Comparison visualization");
|
||||
request.setAttribute("scripts",
|
||||
"/templates/visualization/entity_comparison_inject_head.jsp");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* function to generate a json file for year <-> publication count mapping
|
||||
* @param subOrganizationTypesResult
|
||||
*
|
||||
* @param yearToPublicationCount
|
||||
* @param responseWriter
|
||||
* @param visMode
|
||||
*/
|
||||
private String writePublicationsOverTimeJSON(Set<SubEntity> subentities, Map<String, Set<String>> subOrganizationTypesResult) {
|
||||
// System.out.println("\nsub entity vis mode ------>"
|
||||
// + SUB_ENTITY_VIS_MODE + "\n");
|
||||
System.out.println("Creating JSONObject \n-----------------------");
|
||||
Gson json = new Gson();
|
||||
Set<JsonObject> subEntitiesJson = new HashSet<JsonObject>();
|
||||
|
||||
for (SubEntity subentity : subentities) {
|
||||
JsonObject entityJson = new JsonObject(
|
||||
subentity.getIndividualLabel());
|
||||
|
||||
List<List<Integer>> yearPubCount = new ArrayList<List<Integer>>();
|
||||
|
||||
for (Map.Entry<String, Integer> pubEntry : UtilityFunctions
|
||||
.getYearToPublicationCount(subentity.getDocuments())
|
||||
.entrySet()) {
|
||||
|
||||
List<Integer> currentPubYear = new ArrayList<Integer>();
|
||||
if (pubEntry.getKey().equals(
|
||||
VOConstants.DEFAULT_PUBLICATION_YEAR))
|
||||
currentPubYear.add(-1);
|
||||
else
|
||||
currentPubYear.add(Integer.parseInt(pubEntry.getKey()));
|
||||
currentPubYear.add(pubEntry.getValue());
|
||||
yearPubCount.add(currentPubYear);
|
||||
}
|
||||
|
||||
entityJson.setYearToPublicationCount(yearPubCount);
|
||||
entityJson.getOrganizationType().addAll(subOrganizationTypesResult.get(entityJson.getLabel()));
|
||||
|
||||
entityJson.setEntityURI(subentity.getIndividualURI());
|
||||
entityJson.setVisMode(SUB_ENTITY_VIS_MODE);
|
||||
System.out.println("Adding object with uri: "
|
||||
+ entityJson.getEntityURI() + " vismode: "
|
||||
+ entityJson.getVisMode() + " label: "
|
||||
+ entityJson.getLabel() + " type: "
|
||||
+ entityJson.getOrganizationType().toString());
|
||||
subEntitiesJson.add(entityJson);
|
||||
}
|
||||
|
||||
// System.out.println("\nStopWords are "+ EntitySubOrganizationTypesQueryRunner.stopWords.toString() + "\n");
|
||||
return json.toJson(subEntitiesJson);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.entitycomparison;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.visutils.QueryRunner;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class EntitySubOrganizationTypesQueryRunner implements QueryRunner<Map<String, Set<String>>> {
|
||||
|
||||
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||
|
||||
private String entityURI;
|
||||
private DataSource dataSource;
|
||||
private Log log;
|
||||
private String visMode;
|
||||
static String SUBORGANISATION_LABEL;
|
||||
static String SUBORGANISATION_TYPE_LABEL;
|
||||
// public static Map<String, Integer> subOrganizationTypesToCount = new HashMap<String, Integer>();
|
||||
// public static Set<String> stopWords = new HashSet<String>();
|
||||
// public static Set<String> subOrganizations = new HashSet<String>();
|
||||
// public static Set<String> STOP_WORDS = new HashSet<String>() {
|
||||
// {
|
||||
// add("Person");
|
||||
// add("Organization");
|
||||
// }
|
||||
// };
|
||||
|
||||
private static final String SPARQL_QUERY_SELECT_CLAUSE = ""
|
||||
+ " (str(?organizationLabel) as ?"+QueryFieldLabels.ORGANIZATION_LABEL+") "
|
||||
+ " (str(?subOrganizationLabel) as ?"+QueryFieldLabels.SUBORGANIZATION_LABEL+") "
|
||||
+ " (str(?subOrganizationType) as ?"+QueryFieldLabels.SUBORGANIZATION_TYPE +")"
|
||||
+ " (str(?subOrganizationTypeLabel) as ?"+QueryFieldLabels.SUBORGANIZATION_TYPE_LABEL+") ";
|
||||
|
||||
|
||||
public EntitySubOrganizationTypesQueryRunner(String entityURI,
|
||||
DataSource dataSource, Log log, String visMode){
|
||||
|
||||
this.entityURI = entityURI;
|
||||
this.dataSource = dataSource;
|
||||
this.log = log;
|
||||
this.visMode = visMode;
|
||||
// stopWords.clear();
|
||||
// subOrganizations.clear();
|
||||
// subOrganizationTypesToCount.clear();
|
||||
}
|
||||
|
||||
private ResultSet executeQuery(String queryURI, DataSource dataSource) {
|
||||
|
||||
QueryExecution queryExecution = null;
|
||||
try {
|
||||
Query query = QueryFactory.create(
|
||||
getSparqlQuery(queryURI), SYNTAX);
|
||||
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||
|
||||
if (query.isSelectType()) {
|
||||
return queryExecution.execSelect();
|
||||
}
|
||||
} finally {
|
||||
if (queryExecution != null) {
|
||||
queryExecution.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getSparqlQuery(String queryURI) {
|
||||
String sparqlQuery = "";
|
||||
|
||||
if (!this.visMode.equals("DEPARTMENT")) {
|
||||
|
||||
SUBORGANISATION_LABEL = QueryFieldLabels.SUBORGANIZATION_LABEL;
|
||||
SUBORGANISATION_TYPE_LABEL = QueryFieldLabels.SUBORGANIZATION_TYPE_LABEL;
|
||||
sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT "
|
||||
+ SPARQL_QUERY_SELECT_CLAUSE
|
||||
+ " WHERE { "
|
||||
+ "<"
|
||||
+ queryURI
|
||||
+ "> rdf:type foaf:Organization ;"
|
||||
+ " rdfs:label ?organizationLabel ;"
|
||||
+ " core:hasSubOrganization ?subOrganization . "
|
||||
+ " ?subOrganization rdfs:label ?subOrganizationLabel ;"
|
||||
+ " rdf:type ?subOrganizationType . "
|
||||
+ " ?subOrganizationType rdfs:label ?subOrganizationTypeLabel ."
|
||||
+ "}";
|
||||
System.out.println("\nThe sparql query is :\n" + sparqlQuery);
|
||||
} else{
|
||||
|
||||
SUBORGANISATION_LABEL = QueryFieldLabels.PERSON_LABEL;
|
||||
SUBORGANISATION_TYPE_LABEL = QueryFieldLabels.PERSON_TYPE_LABEL;
|
||||
sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||
+ "SELECT "
|
||||
+ " (str(?departmentLabel) as ?"+QueryFieldLabels.DEPARTMENT_LABEL+") "
|
||||
+ " (str(?personLabel) as ?"+QueryFieldLabels.PERSON_LABEL+") "
|
||||
+ " (str(?personType) as ?"+QueryFieldLabels.PERSON_TYPE +")"
|
||||
+ " (str(?personTypeLabel) as ?"+QueryFieldLabels.PERSON_TYPE_LABEL+") "
|
||||
+ " WHERE { "
|
||||
+ "<"
|
||||
+ queryURI
|
||||
+ "> rdf:type core:Department ;"
|
||||
+ " rdfs:label ?departmentLabel ;"
|
||||
+ " core:organizationForPosition ?position . "
|
||||
+ " ?position rdf:type core:Position ; core:positionForPerson ?person . "
|
||||
+ " ?person rdfs:label ?personLabel ;"
|
||||
+ " rdf:type ?personType . "
|
||||
+ " ?personType rdfs:label ?personTypeLabel ."
|
||||
+ "}";;
|
||||
}
|
||||
return sparqlQuery;
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Set<String>> createJavaValueObjects(ResultSet resultSet) {
|
||||
|
||||
Map<String, Set<String>> subOrganizationLabelToTypes = new HashMap<String, Set<String>>();
|
||||
|
||||
while(resultSet.hasNext()){
|
||||
|
||||
QuerySolution solution = resultSet.nextSolution();
|
||||
|
||||
RDFNode subOrganizationLabel = solution.get(SUBORGANISATION_LABEL);
|
||||
|
||||
if(subOrganizationLabelToTypes.containsKey(subOrganizationLabel.toString())){
|
||||
RDFNode subOrganizationType = solution.get(SUBORGANISATION_TYPE_LABEL);
|
||||
if(subOrganizationType != null){
|
||||
subOrganizationLabelToTypes.get(subOrganizationLabel.toString()).add(subOrganizationType.toString());
|
||||
// updateSubOrganizationTypesToCount(subOrganizationType.toString());
|
||||
// subOrganizations.add(subOrganizationLabel.toString());
|
||||
}
|
||||
}else{
|
||||
RDFNode subOrganizationType = solution.get(SUBORGANISATION_TYPE_LABEL);
|
||||
if(subOrganizationType != null){
|
||||
subOrganizationLabelToTypes.put(subOrganizationLabel.toString(), new HashSet<String>());
|
||||
subOrganizationLabelToTypes.get(subOrganizationLabel.toString()).add(subOrganizationType.toString());
|
||||
// updateSubOrganizationTypesToCount(subOrganizationType.toString());
|
||||
// subOrganizations.add(subOrganizationLabel.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// collectStopWords();
|
||||
|
||||
return subOrganizationLabelToTypes;
|
||||
}
|
||||
|
||||
|
||||
// private void collectStopWords() {
|
||||
// System.out.println("Inside collectStopWords \n-----------------------------\n");
|
||||
// for(Map.Entry<String, Integer> typesCount : subOrganizationTypesToCount.entrySet()){
|
||||
// System.out.println(typesCount.getKey() + ": "+ typesCount.getValue());
|
||||
// if(typesCount.getValue() >= subOrganizations.size()){
|
||||
// stopWords.add(typesCount.getKey());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void updateSubOrganizationTypesToCount(String typeLabel) {
|
||||
// int count = 0;
|
||||
// if(subOrganizationTypesToCount.containsKey(typeLabel)){
|
||||
// count = subOrganizationTypesToCount.get(typeLabel);
|
||||
// subOrganizationTypesToCount.put(typeLabel, ++count);
|
||||
// }else{
|
||||
// subOrganizationTypesToCount.put(typeLabel, 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
public Map<String, Set<String>> getQueryResult() throws MalformedQueryParametersException {
|
||||
|
||||
if (StringUtils.isNotBlank(this.entityURI)) {
|
||||
|
||||
/*
|
||||
* To test for the validity of the URI submitted.
|
||||
*/
|
||||
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||
IRI iri = iRIFactory.create(this.entityURI);
|
||||
if (iri.hasViolation(false)) {
|
||||
String errorMsg = ((Violation) iri.violations(false).next())
|
||||
.getShortMessage();
|
||||
log.error("Entity Comparison sub organization types query " + errorMsg);
|
||||
throw new MalformedQueryParametersException(
|
||||
"URI provided for an entity is malformed.");
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new MalformedQueryParametersException(
|
||||
"URL parameter is either null or empty.");
|
||||
}
|
||||
|
||||
ResultSet resultSet = executeQuery(this.entityURI, this.dataSource);
|
||||
|
||||
return createJavaValueObjects(resultSet);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.freemarker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.VisualizationRequestHandler;
|
||||
|
||||
|
||||
public class VisTestController extends FreemarkerHttpServlet implements VisualizationRequestHandler {
|
||||
|
||||
private static final String TEMPLATE_DEFAULT = "vistest.ftl";
|
||||
|
||||
public void generateVisualization(VitroRequest vitroRequest, HttpServletRequest request, HttpServletResponse response, Log log, DataSource dataSource){
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseValues processRequest(VitroRequest vitroRequest){
|
||||
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
String egoURI = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY);
|
||||
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_KEY);
|
||||
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY);
|
||||
|
||||
List<String> parameters = new ArrayList<String>();
|
||||
|
||||
parameters.add(egoURI);
|
||||
parameters.add(renderMode);
|
||||
parameters.add(visMode);
|
||||
|
||||
body.put("parameters", parameters);
|
||||
body.put("title", getTitle("VIVO Vis"));
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.visualization.personlevel;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
@ -333,6 +335,7 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
VitroRequest vitroRequest,
|
||||
HttpServletRequest request) {
|
||||
|
||||
String completeURL = "";
|
||||
Portal portal = vitroRequest.getPortal();
|
||||
|
||||
request.setAttribute("egoURIParam", egoURI);
|
||||
|
@ -348,6 +351,13 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
}
|
||||
|
||||
|
||||
try {
|
||||
completeURL = getCompleteURL(request);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
request.setAttribute("completeURL", completeURL);
|
||||
request.setAttribute("egoPubSparklineVO", egoPubSparklineVO);
|
||||
request.setAttribute("uniqueCoauthorsSparklineVO", uniqueCoauthorsSparklineVO);
|
||||
|
||||
|
@ -360,4 +370,16 @@ public class PersonLevelRequestHandler implements VisualizationRequestHandler {
|
|||
request.setAttribute("scripts", "/templates/visualization/person_level_inject_head.jsp");
|
||||
request.setAttribute("bodyJsp", "/templates/visualization/person_level.jsp");
|
||||
}
|
||||
|
||||
private String getCompleteURL(HttpServletRequest request) throws MalformedURLException {
|
||||
|
||||
String file = request.getRequestURI();
|
||||
System.out.println("getRequestURI() = "+ file + "getQueryString() ="+request.getQueryString()+ "getScheme() = "+ request.getScheme());
|
||||
System.out.println("getServerName() = "+ request.getServerName() + "getServerPort() ="+request.getServerPort());
|
||||
|
||||
URL reconstructedURL = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), file);
|
||||
|
||||
return reconstructedURL.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
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.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;
|
||||
}
|
||||
|
||||
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,143 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.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.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
* This stores edge information for Co-PI vis.
|
||||
* @author bkoniden
|
||||
*
|
||||
*/
|
||||
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,152 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.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.visutils.UtilityFunctions;
|
||||
|
||||
/**
|
||||
* CoPINode is the node in a CoPI vis.
|
||||
* @author bkoniden
|
||||
*/
|
||||
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,48 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
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,45 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
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,127 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||
|
||||
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,75 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.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
|
||||
*
|
||||
*/
|
||||
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,22 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
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,54 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is equivalent for vivo:CollegeOrSchoolWithinUniversity object type.
|
||||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
public class VivoCollegeOrSchool extends Individual {
|
||||
|
||||
private Set<VivoDepartmentOrDivision> departments = new HashSet<VivoDepartmentOrDivision>();
|
||||
|
||||
public VivoCollegeOrSchool(String collegeURI) {
|
||||
super(collegeURI);
|
||||
}
|
||||
|
||||
public Set<VivoDepartmentOrDivision> getDepartments() {
|
||||
return departments;
|
||||
}
|
||||
|
||||
public void addDepartment(VivoDepartmentOrDivision department) {
|
||||
this.departments.add(department);
|
||||
}
|
||||
|
||||
public String getCollegeURI() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getCollegeLabel() {
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public void setCollegeLabel(String collegeLabel) {
|
||||
this.setIndividualLabel(collegeLabel);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is equivalent for vivo:AcademicDepartmentOrDivision object type.
|
||||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
public class VivoDepartmentOrDivision extends Individual {
|
||||
|
||||
private Set<VivoCollegeOrSchool> parentColleges = new HashSet<VivoCollegeOrSchool>();
|
||||
|
||||
public VivoDepartmentOrDivision(String departmentURI, VivoCollegeOrSchool parentCollege) {
|
||||
super(departmentURI);
|
||||
addParentCollege(parentCollege);
|
||||
}
|
||||
|
||||
public Set<VivoCollegeOrSchool> getParentCollege() {
|
||||
return parentColleges;
|
||||
}
|
||||
|
||||
public void addParentCollege(VivoCollegeOrSchool parentCollege) {
|
||||
this.parentColleges.add(parentCollege);
|
||||
}
|
||||
|
||||
public String getDepartmentURI() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getDepartmentLabel() {
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public void setDepartmentLabel(String departmentLabel) {
|
||||
this.setIndividualLabel(departmentLabel);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants.EmployeeType;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the equivalent for vivo's Employee object type.
|
||||
*
|
||||
* @author cdtank
|
||||
*/
|
||||
public class VivoEmployee extends Individual {
|
||||
|
||||
private EmployeeType employeeType;
|
||||
private Set<VivoDepartmentOrDivision> parentDepartments =
|
||||
new HashSet<VivoDepartmentOrDivision>();
|
||||
private Set<BiboDocument> authorDocuments = new HashSet<BiboDocument>();
|
||||
|
||||
public VivoEmployee(String employeeURL,
|
||||
EmployeeType employeeType,
|
||||
VivoDepartmentOrDivision parentDepartment) {
|
||||
super(employeeURL);
|
||||
addParentDepartment(parentDepartment);
|
||||
}
|
||||
|
||||
public String getEmployeeURI() {
|
||||
return this.getIndividualURI();
|
||||
}
|
||||
|
||||
public String getEmployeeName() {
|
||||
return this.getIndividualLabel();
|
||||
}
|
||||
|
||||
public EmployeeType getEmployeeType() {
|
||||
return employeeType;
|
||||
}
|
||||
|
||||
public void setEmployeeType(EmployeeType employeeType) {
|
||||
this.employeeType = employeeType;
|
||||
}
|
||||
|
||||
public Set<VivoDepartmentOrDivision> getParentDepartments() {
|
||||
return parentDepartments;
|
||||
}
|
||||
|
||||
public void addParentDepartment(VivoDepartmentOrDivision parentDepartment) {
|
||||
this.parentDepartments.add(parentDepartment);
|
||||
}
|
||||
|
||||
public Set<BiboDocument> getAuthorDocuments() {
|
||||
return authorDocuments;
|
||||
}
|
||||
|
||||
public void addAuthorDocument(BiboDocument authorDocument) {
|
||||
this.authorDocuments.add(authorDocument);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -22,8 +22,12 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|||
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoAuthorshipData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPIData;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Grant;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.CoPINode;
|
||||
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||
|
||||
|
||||
public class UtilityFunctions {
|
||||
|
||||
public static Map<String, Integer> getYearToPublicationCount(
|
||||
|
@ -154,4 +158,86 @@ public class UtilityFunctions {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
2
startTomcat
Executable file
2
startTomcat
Executable file
|
@ -0,0 +1,2 @@
|
|||
sudo /usr/local/tomcat/bin/startup.sh
|
||||
tail -f /usr/local/tomcat/logs/catalina.out
|
194
themes/vivo-basic/css/visualization/entityComparison/layout.css
Normal file
194
themes/vivo-basic/css/visualization/entityComparison/layout.css
Normal file
|
@ -0,0 +1,194 @@
|
|||
@CHARSET "UTF-8";
|
||||
|
||||
head,#body {
|
||||
font: 0.9em Helvetica;
|
||||
}
|
||||
|
||||
#body {
|
||||
background-color: #fff;
|
||||
min-height: 800px;
|
||||
width: 100%;
|
||||
min-width: 900px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-top: 10px;
|
||||
font-size: 1.5em;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.1em;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.01em;
|
||||
}
|
||||
|
||||
button{
|
||||
margin-top: 10px;
|
||||
float:right;
|
||||
}
|
||||
|
||||
form{
|
||||
margin-top:70px;
|
||||
margin-bottom: -50px;
|
||||
}
|
||||
#yaxislabel{
|
||||
font-size: 12px;
|
||||
float:right;
|
||||
background-color: white;
|
||||
color:black;
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
#xaxislabel{
|
||||
font-size: 12px;
|
||||
margin-top: -5px;
|
||||
margin-left: 250px;
|
||||
}
|
||||
|
||||
#functions{
|
||||
margin-top: 20px;
|
||||
margin-bottom: -40px;
|
||||
}
|
||||
#bar {
|
||||
height: 20px;
|
||||
float: left;
|
||||
background-color: #fff;
|
||||
width: 250px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
#checkbox{
|
||||
float:left;
|
||||
}
|
||||
#label {
|
||||
float: left;
|
||||
font-size: 12px;
|
||||
width: 160px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#searchresult {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
#bottom,#graphContainer {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#graphContainer {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#leftblock {
|
||||
float: left;
|
||||
margin-left: 5%;
|
||||
width: 36%;
|
||||
}
|
||||
|
||||
#text {
|
||||
margin-left: 5px;
|
||||
}
|
||||
#searchresult a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
font-family: Helvetica;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#label a,#text {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
font-family: Helvetica;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#rightblock {
|
||||
float:right;
|
||||
margin-right:5%;
|
||||
width:54%;
|
||||
}
|
||||
|
||||
#counter,#total {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#heading {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
li{
|
||||
padding: 5px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#paginatedTable{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.sDomSearchBar{
|
||||
margin-bottom: 10px;
|
||||
margin-left: 41%;
|
||||
}
|
||||
|
||||
.datatablerowhighlight {
|
||||
background-color: #ECFFB3 !important;
|
||||
}
|
||||
|
||||
.metallic{
|
||||
background-color: #212D34;
|
||||
color: white;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#leftUpper{
|
||||
border: 1px #3D454E solid;
|
||||
border-top: 10px #3D454E solid;
|
||||
background-color: #D9D9D9;
|
||||
}
|
||||
|
||||
#leftLower{
|
||||
border: 1px #3D454E solid;
|
||||
border-top: 10px #3D454E solid;
|
||||
}
|
||||
|
||||
#navcontainer{
|
||||
background: none repeat scroll 0 0 #3D454E;
|
||||
height: 1%;
|
||||
padding: 8px 22em 8px 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#navlist li
|
||||
{
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
padding: 20px;
|
||||
|
||||
}
|
||||
|
||||
#navlist li a{
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#bottomButtons{
|
||||
width: 50%;
|
||||
float:right;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
#stopwordsdiv{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
p.displayCounter{
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
Binary file not shown.
Loading…
Add table
Reference in a new issue