merging in http://svn.mannlib.cornell.edu/svn/vitro/branches/iu-vis-vitro-1.1-pre-release from r4966 to r5166
This commit is contained in:
commit
0d09bcf546
56 changed files with 9118 additions and 1 deletions
|
@ -1119,6 +1119,26 @@
|
||||||
<servlet-name>SparqlQuery</servlet-name>
|
<servlet-name>SparqlQuery</servlet-name>
|
||||||
<url-pattern>/admin/sparqlquery</url-pattern>
|
<url-pattern>/admin/sparqlquery</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>DummyVisClient</servlet-name>
|
||||||
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.DummyVisClientController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>DummyVisClient</servlet-name>
|
||||||
|
<url-pattern>/admin/dummyVisClient</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>VisualizationController</servlet-name>
|
||||||
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>VisualizationController</servlet-name>
|
||||||
|
<url-pattern>/admin/visQuery</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>authtest</servlet-name>
|
<servlet-name>authtest</servlet-name>
|
||||||
|
|
BIN
webapp/lib/gson-1.4.jar
Normal file
BIN
webapp/lib/gson-1.4.jar
Normal file
Binary file not shown.
BIN
webapp/lib/iText-5.0.2.jar
Normal file
BIN
webapp/lib/iText-5.0.2.jar
Normal file
Binary file not shown.
|
@ -417,7 +417,11 @@ public class SparqlQueryServlet extends BaseEditController {
|
||||||
"PREFIX swrl: <http://www.w3.org/2003/11/swrl#>\n" +
|
"PREFIX swrl: <http://www.w3.org/2003/11/swrl#>\n" +
|
||||||
"PREFIX swrlb: <http://www.w3.org/2003/11/swrlb#>\n" +
|
"PREFIX swrlb: <http://www.w3.org/2003/11/swrlb#>\n" +
|
||||||
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>\n"+
|
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>\n"+
|
||||||
"PREFIX vivo: <http://vivo.library.cornell.edu/ns/0.1#>\n"+
|
"PREFIX vivo: <http://vivo.library.cornell.edu/ns/0.1#>\n" +
|
||||||
|
"PREFIX bibo: <http://purl.org/ontology/bibo/>\n" +
|
||||||
|
"PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n" +
|
||||||
|
"PREFIX core: <http://vivoweb.org/ontology/core#>\n" +
|
||||||
|
"PREFIX aktp: <http://www.aktors.org/ontology/portal#>\n"+
|
||||||
"#\n" +
|
"#\n" +
|
||||||
"# This query gets all range entities labels and types of a person\n"+
|
"# This query gets all range entities labels and types of a person\n"+
|
||||||
"# A query like this could be used to get enough info to create a display\n"+
|
"# A query like this could be used to get enough info to create a display\n"+
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.visualization;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010, Cornell University
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of Cornell University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
|
||||||
|
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Services a sparql query. This will return a simple error message and a 501 if
|
||||||
|
* there is no jena Model.
|
||||||
|
*
|
||||||
|
* @author bdc34
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DummyVisClientController extends BaseEditController {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(DummyVisClientController.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
this.doGet(request,response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
super.doGet(request, response);
|
||||||
|
|
||||||
|
VitroRequest vreq = handleLoginAuthentication(request, response);
|
||||||
|
prepareVisualizationQueryResponse(request, response, vreq);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryResponse(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, VitroRequest vreq) {
|
||||||
|
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/dummy_vis_client.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Dummy Visualization Client");
|
||||||
|
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private VitroRequest handleLoginAuthentication(HttpServletRequest request,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
// This might not be required
|
||||||
|
/*
|
||||||
|
* why are there multiple places where the login is checked? shud be abtracted into
|
||||||
|
* new methoid?
|
||||||
|
* */
|
||||||
|
// if( !checkLoginStatus(request, response) )
|
||||||
|
// return null;
|
||||||
|
|
||||||
|
VitroRequest vreq = new VitroRequest(request);
|
||||||
|
|
||||||
|
Object obj = vreq.getSession().getAttribute("loginHandler");
|
||||||
|
LoginFormBean loginHandler = null;
|
||||||
|
|
||||||
|
if( obj != null && obj instanceof LoginFormBean )
|
||||||
|
loginHandler = ((LoginFormBean)obj);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* what is the speciality of 5 in the conditions?
|
||||||
|
*
|
||||||
|
if( loginHandler == null ||
|
||||||
|
! "authenticated".equalsIgnoreCase(loginHandler.getLoginStatus()) ||
|
||||||
|
Integer.parseInt(loginHandler.getLoginRole()) <= 5 ){
|
||||||
|
HttpSession session = request.getSession(true);
|
||||||
|
|
||||||
|
session.setAttribute("postLoginRequest",
|
||||||
|
vreq.getRequestURI()+( vreq.getQueryString()!=null?('?' + vreq.getQueryString()):"" ));
|
||||||
|
String redirectURL = request.getContextPath() + Controllers.SITE_ADMIN + "?login=block";
|
||||||
|
response.sendRedirect(redirectURL);
|
||||||
|
return null;
|
||||||
|
}*/
|
||||||
|
return vreq;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,379 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.visualization;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2010, Cornell University
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of Cornell University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
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.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.query.DataSource;
|
||||||
|
import com.hp.hpl.jena.query.DatasetFactory;
|
||||||
|
import com.hp.hpl.jena.query.Syntax;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||||
|
import com.hp.hpl.jena.sparql.resultset.ResultSetFormat;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vedit.beans.LoginFormBean;
|
||||||
|
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Services a sparql query. This will return a simple error message and a 501 if
|
||||||
|
* there is no jena Model.
|
||||||
|
*
|
||||||
|
* @author bdc34
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class VisualizationController extends BaseEditController {
|
||||||
|
|
||||||
|
private static final String VIS_TYPE_URL_HANDLE = "vis";
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
protected static HashMap<String,ResultSetFormat> formatSymbols = new HashMap<String,ResultSetFormat>();
|
||||||
|
static{
|
||||||
|
formatSymbols.put( ResultSetFormat.syntaxXML.getSymbol(), ResultSetFormat.syntaxXML);
|
||||||
|
formatSymbols.put( ResultSetFormat.syntaxRDF_XML.getSymbol(), ResultSetFormat.syntaxRDF_XML);
|
||||||
|
formatSymbols.put( ResultSetFormat.syntaxRDF_N3.getSymbol(), ResultSetFormat.syntaxRDF_N3);
|
||||||
|
formatSymbols.put( ResultSetFormat.syntaxText.getSymbol() , ResultSetFormat.syntaxText);
|
||||||
|
formatSymbols.put( ResultSetFormat.syntaxJSON.getSymbol() , ResultSetFormat.syntaxJSON);
|
||||||
|
formatSymbols.put( "vitro:csv", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String,String> rdfFormatSymbols = new HashMap<String,String>();
|
||||||
|
static {
|
||||||
|
rdfFormatSymbols.put( "RDF/XML", "application/rdf+xml" );
|
||||||
|
rdfFormatSymbols.put( "RDF/XML-ABBREV", "application/rdf+xml" );
|
||||||
|
rdfFormatSymbols.put( "N3", "text/n3" );
|
||||||
|
rdfFormatSymbols.put( "N-TRIPLE", "text/plain" );
|
||||||
|
rdfFormatSymbols.put( "TTL", "application/x-turtle" );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static HashMap<String, String> mimeTypes = new HashMap<String,String>();
|
||||||
|
static{
|
||||||
|
mimeTypes.put( ResultSetFormat.syntaxXML.getSymbol() , "text/xml" );
|
||||||
|
mimeTypes.put( ResultSetFormat.syntaxRDF_XML.getSymbol(), "application/rdf+xml" );
|
||||||
|
mimeTypes.put( ResultSetFormat.syntaxRDF_N3.getSymbol(), "text/plain" );
|
||||||
|
mimeTypes.put( ResultSetFormat.syntaxText.getSymbol() , "text/plain");
|
||||||
|
mimeTypes.put( ResultSetFormat.syntaxJSON.getSymbol(), "application/javascript" );
|
||||||
|
mimeTypes.put( "vitro:csv", "text/csv");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String PERSON_PUBLICATION_COUNT_VIS_URL_VALUE
|
||||||
|
= "person_pub_count";
|
||||||
|
|
||||||
|
public static final String PDF_REPORT_VIS_URL_VALUE
|
||||||
|
= "pdf_report";
|
||||||
|
|
||||||
|
public static final String COLLEGE_PUBLICATION_COUNT_VIS_URL_VALUE
|
||||||
|
= "college_pub_count";
|
||||||
|
|
||||||
|
public static final String COAUTHORSHIP_VIS_URL_VALUE
|
||||||
|
= "coauthorship";
|
||||||
|
|
||||||
|
public static final String PERSON_LEVEL_VIS_URL_VALUE
|
||||||
|
= "person_level";
|
||||||
|
|
||||||
|
public static final String UTILITIES_URL_VALUE
|
||||||
|
= "utilities";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
this.doGet(request,response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException
|
||||||
|
{
|
||||||
|
super.doGet(request, response);
|
||||||
|
|
||||||
|
VitroRequest vreq = handleLoginAuthentication(request, response);
|
||||||
|
|
||||||
|
|
||||||
|
if (PERSON_PUBLICATION_COUNT_VIS_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.VisualizationRequestHandler visRequestHandler =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.VisualizationRequestHandler(vreq, request, response, log);
|
||||||
|
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
DataSource dataSource = setupJENADataSource(request,
|
||||||
|
response,
|
||||||
|
vreq,
|
||||||
|
rdfResultFormatParam);
|
||||||
|
|
||||||
|
if (dataSource != null) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the visualization content is added
|
||||||
|
* to the request object.
|
||||||
|
* */
|
||||||
|
visRequestHandler.generateVisualization(dataSource);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
log.error("ERROR! Data Model Empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (COLLEGE_PUBLICATION_COUNT_VIS_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.collegepubcount.VisualizationRequestHandler visRequestHandler =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.collegepubcount.VisualizationRequestHandler(vreq, request, response, log);
|
||||||
|
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
DataSource dataSource = setupJENADataSource(request,
|
||||||
|
response,
|
||||||
|
vreq,
|
||||||
|
rdfResultFormatParam);
|
||||||
|
|
||||||
|
if (dataSource != null) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the visualization content is added
|
||||||
|
* to the request object.
|
||||||
|
* */
|
||||||
|
visRequestHandler.generateVisualization(dataSource);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.error("ERROR! data model empoty");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (COAUTHORSHIP_VIS_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisualizationRequestHandler visRequestHandler =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisualizationRequestHandler(vreq, request, response, log);
|
||||||
|
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
DataSource dataSource = setupJENADataSource(request,
|
||||||
|
response,
|
||||||
|
vreq,
|
||||||
|
rdfResultFormatParam);
|
||||||
|
|
||||||
|
if (dataSource != null) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the visualization content is added
|
||||||
|
* to the request object.
|
||||||
|
* */
|
||||||
|
visRequestHandler.generateVisualization(dataSource);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.error("ERROR! data model empoty");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PERSON_LEVEL_VIS_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.personlevel.VisualizationRequestHandler visRequestHandler =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.personlevel.VisualizationRequestHandler(vreq, request, response, log);
|
||||||
|
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
DataSource dataSource = setupJENADataSource(request,
|
||||||
|
response,
|
||||||
|
vreq,
|
||||||
|
rdfResultFormatParam);
|
||||||
|
|
||||||
|
if (dataSource != null) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the visualization content is added
|
||||||
|
* to the request object.
|
||||||
|
* */
|
||||||
|
visRequestHandler.generateVisualization(dataSource);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.error("ERROR! data model empoty");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PDF_REPORT_VIS_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
} else if (UTILITIES_URL_VALUE
|
||||||
|
.equalsIgnoreCase(vreq.getParameter(VIS_TYPE_URL_HANDLE))) {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationRequestHandler visRequestHandler =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.utilities.VisualizationRequestHandler(vreq, request, response, log);
|
||||||
|
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
DataSource dataSource = setupJENADataSource(request,
|
||||||
|
response,
|
||||||
|
vreq,
|
||||||
|
rdfResultFormatParam);
|
||||||
|
|
||||||
|
if (dataSource != null) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the visualization content is added
|
||||||
|
* to the request object.
|
||||||
|
* */
|
||||||
|
visRequestHandler.generateVisualization(dataSource);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.error("ERROR! data model empoty");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
log.debug("vis uqery parameter value -> " + vreq.getParameter("vis"));
|
||||||
|
log.debug("uri uqery parameter value -> " + vreq.getParameter("uri"));
|
||||||
|
log.debug("render_mode query parameter value -> " + vreq.getParameter("render_mode"));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the error content is directly
|
||||||
|
* added to the request object. From where it is redirected to
|
||||||
|
* the error page.
|
||||||
|
* */
|
||||||
|
handleMalformedParameters("Inappropriate query parameters were submitted. ", request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VitroRequest handleLoginAuthentication(HttpServletRequest request,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
// This might not be required
|
||||||
|
/*
|
||||||
|
* why are there multiple places where the login is checked? shud be abtracted into
|
||||||
|
* new methoid?
|
||||||
|
* */
|
||||||
|
// if( !checkLoginStatus(request, response) )
|
||||||
|
// return null;
|
||||||
|
|
||||||
|
VitroRequest vreq = new VitroRequest(request);
|
||||||
|
|
||||||
|
Object obj = vreq.getSession().getAttribute("loginHandler");
|
||||||
|
LoginFormBean loginHandler = null;
|
||||||
|
|
||||||
|
|
||||||
|
if( obj != null && obj instanceof LoginFormBean )
|
||||||
|
loginHandler = ((LoginFormBean)obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* what is the speciality of 5 in the conditions?
|
||||||
|
*
|
||||||
|
if( loginHandler == null ||
|
||||||
|
! "authenticated".equalsIgnoreCase(loginHandler.getLoginStatus()) ||
|
||||||
|
Integer.parseInt(loginHandler.getLoginRole()) <= 5 ){
|
||||||
|
HttpSession session = request.getSession(true);
|
||||||
|
|
||||||
|
session.setAttribute("postLoginRequest",
|
||||||
|
vreq.getRequestURI()+( vreq.getQueryString()!=null?('?' + vreq.getQueryString()):"" ));
|
||||||
|
String redirectURL = request.getContextPath() + Controllers.SITE_ADMIN + "?login=block";
|
||||||
|
response.sendRedirect(redirectURL);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return vreq;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataSource setupJENADataSource(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, VitroRequest vreq,
|
||||||
|
String rdfResultFormatParam) {
|
||||||
|
|
||||||
|
Model model = vreq.getJenaOntModel(); // getModel()
|
||||||
|
if( model == null ){
|
||||||
|
doNoModelInContext(request,response);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("rdfResultFormat was: " + rdfResultFormatParam);
|
||||||
|
|
||||||
|
DataSource dataSource = DatasetFactory.create() ;
|
||||||
|
ModelMaker maker = (ModelMaker) getServletContext().getAttribute("vitroJenaModelMaker");
|
||||||
|
|
||||||
|
dataSource.setDefaultModel(model) ;
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doNoModelInContext(HttpServletRequest request, HttpServletResponse res){
|
||||||
|
try {
|
||||||
|
res.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
|
||||||
|
ServletOutputStream sos = res.getOutputStream();
|
||||||
|
sos.println("<html><body>this service is not supporeted by the current " +
|
||||||
|
"webapp configuration. A jena model is required in the servlet context.</body></html>" );
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Could not write to ServletOutputStream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage, HttpServletRequest request,
|
||||||
|
HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
VitroRequest vreq = new VitroRequest(request);
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.visualization;
|
||||||
|
|
||||||
|
public class VisualizationFrameworkConstants {
|
||||||
|
|
||||||
|
public static final String VIS_TYPE_URL_HANDLE = "vis";
|
||||||
|
public static final String VIS_CONTAINER_URL_HANDLE = "container";
|
||||||
|
public static final String INDIVIDUAL_URI_URL_HANDLE = "uri";
|
||||||
|
public static final String VIS_MODE_URL_HANDLE = "vis_mode";
|
||||||
|
public static final String RENDER_MODE_URL_HANDLE = "render_mode";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static final String STANDALONE_RENDER_MODE_URL_VALUE = "standalone";
|
||||||
|
public static final String DYNAMIC_RENDER_MODE_URL_VALUE = "dynamic";
|
||||||
|
public static final String DATA_RENDER_MODE_URL_VALUE = "data";
|
||||||
|
public static final String PDF_RENDER_MODE_URL_VALUE = "pdf";
|
||||||
|
public static final String IMAGE_VIS_MODE_URL_VALUE = "image";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,295 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Stroke;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import com.itextpdf.text.BadElementException;
|
||||||
|
import com.itextpdf.text.BaseColor;
|
||||||
|
import com.itextpdf.text.Chunk;
|
||||||
|
import com.itextpdf.text.Document;
|
||||||
|
import com.itextpdf.text.DocumentException;
|
||||||
|
import com.itextpdf.text.Element;
|
||||||
|
import com.itextpdf.text.Font;
|
||||||
|
import com.itextpdf.text.FontFactory;
|
||||||
|
import com.itextpdf.text.Image;
|
||||||
|
import com.itextpdf.text.Paragraph;
|
||||||
|
import com.itextpdf.text.Phrase;
|
||||||
|
import com.itextpdf.text.pdf.ColumnText;
|
||||||
|
import com.itextpdf.text.pdf.PdfContentByte;
|
||||||
|
import com.itextpdf.text.pdf.PdfGState;
|
||||||
|
import com.itextpdf.text.pdf.PdfPCell;
|
||||||
|
import com.itextpdf.text.pdf.PdfPTable;
|
||||||
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
|
|
||||||
|
public class PDFDocument{
|
||||||
|
|
||||||
|
|
||||||
|
static Stroke stroke = new BasicStroke(5.f, BasicStroke.CAP_ROUND,
|
||||||
|
BasicStroke.JOIN_ROUND);
|
||||||
|
|
||||||
|
final static Color bg = Color.green;
|
||||||
|
|
||||||
|
final static Color fg = Color.black;
|
||||||
|
|
||||||
|
public PDFDocument(String authorName,
|
||||||
|
Map<String, Integer> yearToPublicationCount,
|
||||||
|
Document document,
|
||||||
|
PdfWriter pdfWriter) {
|
||||||
|
|
||||||
|
// setPreferredSize(new Dimension(600,400));
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
document.addTitle("PDF Pipeline iText Prototype");
|
||||||
|
document.addAuthor(authorName);
|
||||||
|
document.addSubject("This example tests text, color, image, transparency & table functionality.");
|
||||||
|
document.addKeywords("text, color, image, transparency, table");
|
||||||
|
document.addCreator("Standalone PDF Renderer using iText");
|
||||||
|
|
||||||
|
Paragraph header = new Paragraph();
|
||||||
|
|
||||||
|
Font pageHeaderStyle = FontFactory.getFont(FontFactory.TIMES_ROMAN, 15, Font.BOLDITALIC | Font.UNDERLINE);
|
||||||
|
Font featureHeaderStyle = FontFactory.getFont(FontFactory.TIMES_ROMAN, 10, new BaseColor(Color.red));
|
||||||
|
|
||||||
|
header.add(new Chunk("PDF Pipeline Prototype v2 using iText\n",
|
||||||
|
pageHeaderStyle));
|
||||||
|
|
||||||
|
header.setSpacingAfter(15f);
|
||||||
|
|
||||||
|
|
||||||
|
document.add(header);
|
||||||
|
|
||||||
|
|
||||||
|
Paragraph content = new Paragraph();
|
||||||
|
|
||||||
|
content.add(new Chunk("Publication Count - Author Name - " + authorName,
|
||||||
|
featureHeaderStyle));
|
||||||
|
|
||||||
|
content.setSpacingAfter(15f);
|
||||||
|
|
||||||
|
document.add(content);
|
||||||
|
// step4
|
||||||
|
|
||||||
|
PdfPTable publicationCount = createTable(yearToPublicationCount);
|
||||||
|
|
||||||
|
document.add(publicationCount);
|
||||||
|
|
||||||
|
content = new Paragraph();
|
||||||
|
|
||||||
|
content.add(new Chunk("Transparency of Shapes",
|
||||||
|
featureHeaderStyle));
|
||||||
|
|
||||||
|
content.setSpacingAfter(15f);
|
||||||
|
|
||||||
|
document.add(content);
|
||||||
|
|
||||||
|
createTransparencyShapes(document, pdfWriter);
|
||||||
|
|
||||||
|
|
||||||
|
createImage(document, pdfWriter, featureHeaderStyle);
|
||||||
|
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createImage(Document document, PdfWriter writer,
|
||||||
|
Font featureHeaderStyle) throws BadElementException,
|
||||||
|
MalformedURLException, IOException, DocumentException {
|
||||||
|
Image imageSprite = Image.getInstance(new URL("http://lh3.ggpht.com/_4msVPAgKJv8/SCRYD-pPVKI/AAAAAAAAAYU/zUN963EPoZc/s1024/102_0609.JPG"));
|
||||||
|
imageSprite.setAbsolutePosition(400, 500);
|
||||||
|
imageSprite.scaleAbsolute(171.0f, 250.0f);
|
||||||
|
float imageSpriteY = document.getPageSize().getHeight() * 0.60f;
|
||||||
|
float imageSpriteX = document.getPageSize().getWidth() * 0.65f;
|
||||||
|
imageSprite.setAlignment(Image.UNDERLYING);
|
||||||
|
|
||||||
|
document.add(imageSprite);
|
||||||
|
|
||||||
|
PdfContentByte cb = writer.getDirectContent();
|
||||||
|
ColumnText ct = new ColumnText(cb);
|
||||||
|
Chunk imageHeader = new Chunk("Images",
|
||||||
|
featureHeaderStyle);
|
||||||
|
ct.addText(imageHeader);
|
||||||
|
ct.setAlignment(Element.ALIGN_LEFT);
|
||||||
|
ct.setSimpleColumn(imageSpriteX, imageSpriteY - imageSprite.getScaledHeight(),
|
||||||
|
imageSpriteX + imageSprite.getScaledWidth(), imageSpriteY + imageSprite.getScaledHeight() + 20);
|
||||||
|
ct.go();
|
||||||
|
|
||||||
|
ct = new ColumnText(cb);
|
||||||
|
Chunk imageFooter = new Chunk("Footer to be set for a figure. Similar to 'image cpation'.",
|
||||||
|
FontFactory.getFont(FontFactory.TIMES_ROMAN, 8));
|
||||||
|
ct.addText(imageFooter);
|
||||||
|
ct.setAlignment(Element.ALIGN_CENTER);
|
||||||
|
ct.setSimpleColumn(imageSpriteX, imageSpriteY - 150, imageSpriteX + imageSprite.getScaledWidth(), imageSpriteY);
|
||||||
|
ct.go();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTransparencyShapes(Document document,
|
||||||
|
PdfWriter writer) throws Exception {
|
||||||
|
PdfContentByte cb = writer.getDirectContent();
|
||||||
|
|
||||||
|
pictureBackdrop(document.leftMargin(), 350, cb);
|
||||||
|
cb.saveState();
|
||||||
|
PdfGState gs1 = new PdfGState();
|
||||||
|
gs1.setFillOpacity(0.5f);
|
||||||
|
cb.setGState(gs1);
|
||||||
|
pictureCircles(document.leftMargin(), 350, cb);
|
||||||
|
cb.restoreState();
|
||||||
|
|
||||||
|
cb.resetRGBColorFill();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a square and fills half of it with a gray rectangle.
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param cb
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void pictureBackdrop(float x, float y, PdfContentByte cb) throws Exception {
|
||||||
|
cb.setColorStroke(new BaseColor(Color.black));
|
||||||
|
cb.setColorFill(new BaseColor(Color.gray));
|
||||||
|
cb.rectangle(x, y, 100, 200);
|
||||||
|
cb.fill();
|
||||||
|
cb.setLineWidth(2);
|
||||||
|
cb.rectangle(x, y, 200, 200);
|
||||||
|
cb.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints 3 circles in different colors that intersect with eachother.
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param cb
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void pictureCircles(float x, float y, PdfContentByte cb) throws Exception {
|
||||||
|
|
||||||
|
cb.saveState();
|
||||||
|
PdfGState gs1 = new PdfGState();
|
||||||
|
gs1.setFillOpacity(1.0f);
|
||||||
|
cb.setGState(gs1);
|
||||||
|
cb.setColorFill(new BaseColor(Color.red));
|
||||||
|
cb.circle(x + 70, y + 70, 50);
|
||||||
|
cb.fill();
|
||||||
|
cb.restoreState();
|
||||||
|
|
||||||
|
cb.setColorFill(new BaseColor(Color.yellow));
|
||||||
|
cb.circle(x + 100, y + 130, 50);
|
||||||
|
cb.fill();
|
||||||
|
cb.setColorFill(new BaseColor(Color.blue));
|
||||||
|
cb.circle(x + 130, y + 70, 50);
|
||||||
|
cb.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PdfPTable createTable(Map<String, Integer> yearToPublicationCount) {
|
||||||
|
|
||||||
|
Font normalContentStyle = FontFactory.getFont(FontFactory.TIMES_ROMAN, 11);
|
||||||
|
Font summaryContentStyle = FontFactory.getFont(FontFactory.TIMES_ROMAN, 11, Font.BOLDITALIC);
|
||||||
|
BaseColor summaryBackgroundColor = new BaseColor(0xEE, 0xEE, 0xEE);
|
||||||
|
BaseColor headerBackgroundColor = new BaseColor(0xC3, 0xD9, 0xFF);
|
||||||
|
BaseColor bodyBackgroundColor = new BaseColor(Color.white);
|
||||||
|
|
||||||
|
PdfPTable table = new PdfPTable(2);
|
||||||
|
table.setWidthPercentage(36.0f);
|
||||||
|
|
||||||
|
table.setHorizontalAlignment(Element.ALIGN_LEFT);
|
||||||
|
table.getDefaultCell().setBorderWidth(0.0f);
|
||||||
|
table.setHeaderRows(2);
|
||||||
|
|
||||||
|
PdfPCell cell;
|
||||||
|
cell = new PdfPCell(new Phrase("Publications per year", normalContentStyle));
|
||||||
|
setTableCaptionStyle(summaryBackgroundColor, cell);
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
cell = new PdfPCell(new Phrase("Year", normalContentStyle));
|
||||||
|
setTableHeaderStyle(headerBackgroundColor, cell);
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
cell.setPhrase(new Phrase("Publications", normalContentStyle));
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setTableBodyStyle(bodyBackgroundColor, cell);
|
||||||
|
int totalPublications = 0;
|
||||||
|
|
||||||
|
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||||
|
|
||||||
|
cell.setPhrase(new Phrase(currentEntry.getKey(), normalContentStyle));
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
cell.setPhrase(new Phrase(currentEntry.getValue().toString(), normalContentStyle));
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
totalPublications += currentEntry.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTableFooterStyle(summaryBackgroundColor, cell);
|
||||||
|
cell.setPhrase(new Phrase("Total", summaryContentStyle));
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
cell.setPhrase(new Phrase(String.valueOf(totalPublications), summaryContentStyle));
|
||||||
|
table.addCell(cell);
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTableFooterStyle(BaseColor footerBackgroundColor,
|
||||||
|
PdfPCell cell) {
|
||||||
|
cell.setBorderWidth(0.0f);
|
||||||
|
cell.setBackgroundColor(footerBackgroundColor);
|
||||||
|
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
||||||
|
cell.setPaddingTop(5f);
|
||||||
|
cell.setPaddingRight(10f);
|
||||||
|
cell.setPaddingBottom(5f);
|
||||||
|
cell.setPaddingLeft(10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTableBodyStyle(BaseColor bodyBackgroundColor,
|
||||||
|
PdfPCell cell) {
|
||||||
|
cell.setBorderWidth(0.0f);
|
||||||
|
cell.setBackgroundColor(bodyBackgroundColor);
|
||||||
|
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
||||||
|
cell.setPaddingTop(5f);
|
||||||
|
cell.setPaddingRight(10f);
|
||||||
|
cell.setPaddingBottom(5f);
|
||||||
|
cell.setPaddingLeft(10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTableHeaderStyle(BaseColor headerBackgroundColor,
|
||||||
|
PdfPCell cell) {
|
||||||
|
cell.setBorderWidth(0.0f);
|
||||||
|
cell.setBackgroundColor(headerBackgroundColor);
|
||||||
|
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
||||||
|
cell.setPaddingTop(5f);
|
||||||
|
cell.setPaddingRight(10f);
|
||||||
|
cell.setPaddingBottom(5f);
|
||||||
|
cell.setPaddingLeft(10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTableCaptionStyle(BaseColor summaryBackgroundColor,
|
||||||
|
PdfPCell cell) {
|
||||||
|
cell.setBorderWidth(0.0f);
|
||||||
|
cell.setBackgroundColor(summaryBackgroundColor);
|
||||||
|
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
||||||
|
cell.setPaddingTop(5.0f);
|
||||||
|
cell.setPaddingRight(10.0f);
|
||||||
|
cell.setPaddingBottom(5.0f);
|
||||||
|
cell.setPaddingLeft(10.0f);
|
||||||
|
cell.setColspan(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.BidiMap;
|
||||||
|
import org.apache.commons.collections.MapIterator;
|
||||||
|
import org.apache.commons.collections.bidimap.TreeBidiMap;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.hp.hpl.jena.iri.IRIFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.GenericQueryMap;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||||
|
|
||||||
|
public class TestJava {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String uriStr = "http%3A%2F%2Fvivo.library.cornell.edu%2Fns%2F0.1%23individual8588";
|
||||||
|
IRIFactory factory = IRIFactory.jenaImplementation();
|
||||||
|
|
||||||
|
String[] sampleBlurns = {"Gold, J R [Reprint Author, Author]; Perkins, G A; Erb, H N; Ainsworth, D M | Journal of Veterinary Internal Medicine, 2006; 20(3): 720",
|
||||||
|
"Goldstein, Richard E; Lin, Rebecca C; Langston, Catherine E; Scrivani, Peter V; Erb, Hollis N; Barr, Stephen C | Journal of Veterinary Internal Medicine, 2006; 20(3): 489-494",
|
||||||
|
"McClellan, Jennifer M; Goldstein, Richard E; Erb, Hollis N; Dykes, Ned L; Cowgill, Larry D | American Journal of Veterinary Research, 2006; 67(4): 715-722",
|
||||||
|
"Cook, Christopher P; Scott, Danny W; Erb, Hollis N; Miller, William H | Vet Dermatol. 2005; 16(1): 47-51",
|
||||||
|
"Estrada, Amara; Moise, N Sydney; Erb, Hollis N; McDonough, Sean P; Renaud, Farrell, Shari | Journal of Veterinary Internal Medicine, 2006; 20(4): 862-872",
|
||||||
|
"Aguirre, A L [Reprint Author, Author]; Center, S A; Yeager, A E; Randolph, J F; Erb, H N | Journal of Veterinary Internal Medicine, 2006; 20(3): 787-788",
|
||||||
|
"MacLeod, K D; Scott, D W; Erb, H N | Journal of Veterinary Medicine Series A, 2004; 51(9-10): 400-404",
|
||||||
|
"Bailey, Dennis B; Rassnick, Kenneth M; Erb, Hollis N; Dykes, Nathan L; Hoopes, P Jack; Page, Rodney L | American Journal of Veterinary Research, 2004; 65(11): 1502-1507",
|
||||||
|
"Ainsworth, Dorothy M; Wagner, Bettina; Franchini, Marco; Grunig, Gabriele; Erb, Hollis N; Tan, Jean Yin | American Journal of Veterinary Research, 2006; 67(4): 669-677",
|
||||||
|
"Page, Richard B; Scrivani, Peter V; Dykes, Nathan L; Erb, Hollis N; Hobbs, Jeff M | Veterinary Radiology and Ultrasound, 2006; 47(2): 206-211",
|
||||||
|
"Scrivani, Peter V; Dykes, Nathan L; Erb, Hollis N | Veterinary Radiology and Ultrasound, 2004; 45(5): 419-423",
|
||||||
|
"Sepesy, Lisa M; Center, Sharon A; Randolph, John F; Warner, Karen L; Erb, Hollis N | Journal of the American Veterinary Medical Association, 2006; 229(2): 246-252",
|
||||||
|
"Dereszynski, D [Reprint Author, Author]; Center, S; Hadden, A; Randolph, J; Brooks, M; Palyada, K; McDonough, S; Messick, J; Bischoff, K; Erb, H; Gluckman, S; Sanders, S | Journal of Veterinary Internal Medicine, 2006; 20(3): 751-752",
|
||||||
|
"Kroll, Tracy L; Houpt, Katherine A; Erb, Hollis N | Journal of the American Animal Hospital Association, 2004; 40(1): 13-19",
|
||||||
|
"Fortier, Lisa A; Gregg, Abigail J; Erb, Hollis N; Fubini, Susan L | Vet Surg. 33(6): 661-7",
|
||||||
|
"Wagner, Bettina; Flaminio, Julia B F; Hillegas, Julie; Leibold, Wolfgang; Erb, Hollis N; Antczak, Douglas F | Veterinary Immunology and Immunopathology, 2006; 110(3-4): 269-278",
|
||||||
|
"Chalmers, H J; Scrivani, Peter V; Dykes, Nathan L; Erb, Hollis N; Hobbs, J M; Hubble, Lorna J | Veterinary Radiology and Ultrasound, 2006; 47(5): 507-509",
|
||||||
|
"Center, Sharon A; Warner, Karen L; McCabe, Jennifer; Foureman, Polly; Hoffmann, Walter E; Erb, Hollis N | Am J Vet Res. 2005; 66(2): 330-41"};
|
||||||
|
|
||||||
|
System.out.println(sampleBlurns);
|
||||||
|
for (String blurb : sampleBlurns) {
|
||||||
|
|
||||||
|
System.out.println(blurb.contains("author"));
|
||||||
|
}
|
||||||
|
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
yearToPublicationCount.put("2003", 5);
|
||||||
|
yearToPublicationCount.put("2005", 3);
|
||||||
|
yearToPublicationCount.put("2002", 1);
|
||||||
|
yearToPublicationCount.put("2090", 5);
|
||||||
|
yearToPublicationCount.put("Unknown", 6);
|
||||||
|
|
||||||
|
BidiMap map1 = new TreeBidiMap(yearToPublicationCount);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(map1 + " --- " + map1.inverseBidiMap());
|
||||||
|
|
||||||
|
Node egoNode;
|
||||||
|
|
||||||
|
|
||||||
|
MapIterator mapIterator = map1.inverseBidiMap().mapIterator();
|
||||||
|
|
||||||
|
|
||||||
|
while(mapIterator.hasNext()) {
|
||||||
|
|
||||||
|
Object next = mapIterator.next();
|
||||||
|
|
||||||
|
System.out.println(next + " %%% " + next);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
Map<String, Set<Integer>> biboDocumentURLToCoAuthors = new HashMap<String, Set<Integer>>();
|
||||||
|
|
||||||
|
Set<Integer> coAuthorsForCurrentBiboDocument;
|
||||||
|
|
||||||
|
if (biboDocumentURLToCoAuthors.containsKey("a")) {
|
||||||
|
coAuthorsForCurrentBiboDocument = biboDocumentURLToCoAuthors.get("a");
|
||||||
|
} else {
|
||||||
|
coAuthorsForCurrentBiboDocument = new HashSet<Integer>();
|
||||||
|
biboDocumentURLToCoAuthors.put("a", coAuthorsForCurrentBiboDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
coAuthorsForCurrentBiboDocument.add(1);
|
||||||
|
|
||||||
|
int actual_size = 4;
|
||||||
|
// int n = actual_size - 1;
|
||||||
|
|
||||||
|
for (int ii = 0; ii < actual_size - 1; ii++) {
|
||||||
|
for (int jj = ii + 1; jj < actual_size; jj++) {
|
||||||
|
System.out.println(ii + " - " + jj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(yearToPublicationCount);
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, Integer> saHashMap = new HashMap<String, Integer>(){{
|
||||||
|
put("sdsd", 4);
|
||||||
|
|
||||||
|
}};
|
||||||
|
System.out.println(saHashMap.keySet());
|
||||||
|
|
||||||
|
|
||||||
|
Set<String> keySet = new HashSet<String>(yearToPublicationCount.keySet());
|
||||||
|
keySet.remove("Unknown");
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.println(Collections.min(keySet));
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenericQueryMap stringToSetOfStrings = new GenericQueryMap();
|
||||||
|
|
||||||
|
stringToSetOfStrings.put("A", yearToPublicationCount.keySet());
|
||||||
|
stringToSetOfStrings.put("B", yearToPublicationCount.keySet());
|
||||||
|
stringToSetOfStrings.put("C", yearToPublicationCount.keySet());
|
||||||
|
stringToSetOfStrings.put("imageOffset", keySet);
|
||||||
|
|
||||||
|
Set<String> what = new HashSet<String>();
|
||||||
|
|
||||||
|
what.add("sup");
|
||||||
|
|
||||||
|
stringToSetOfStrings.put("imageOffset2", what);
|
||||||
|
|
||||||
|
|
||||||
|
String emptyString = "";
|
||||||
|
System.out.println(emptyString.isEmpty());
|
||||||
|
|
||||||
|
System.out.println(stringToSetOfStrings);
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
String json = gson.toJson(stringToSetOfStrings);
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(json);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println(Collections.max(yearToPublicationCount.keySet()));
|
||||||
|
// System.out.println(Collections.min(yearToPublicationCount.keySet()));
|
||||||
|
|
||||||
|
// yearToPublicationCount.put("2087", testIt(5, yearToPublicationCount.get("2087")));
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// factory.setEncoding("HEX");
|
||||||
|
// } catch (UnsupportedEncodingException e) {
|
||||||
|
// // TODO Auto-generated catch block
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
IRI iri = factory.create(uriStr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (iri.hasViolation(false) ) {
|
||||||
|
boolean validURI = false;
|
||||||
|
String errorMsg = ((Violation)iri.violations(false).next()).getShortMessage()+" ";
|
||||||
|
System.out.println("MURDER!!!!!" + errorMsg);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println(iri.hasViolation(true));
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer testIt(int i, Integer integer) {
|
||||||
|
// System.out.println("testit - " + i + " --- " + integer);
|
||||||
|
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,334 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||||
|
|
||||||
|
public class CoAuthorshipGraphMLWriter {
|
||||||
|
|
||||||
|
private StringBuilder coAuthorshipGraphMLContent;
|
||||||
|
|
||||||
|
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 CoAuthorshipGraphMLWriter(VisVOContainer visVOContainer) {
|
||||||
|
|
||||||
|
coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder getCoAuthorshipGraphMLContent() {
|
||||||
|
return coAuthorshipGraphMLContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuilder createCoAuthorshipGraphMLContent(
|
||||||
|
VisVOContainer visVOContainer) {
|
||||||
|
|
||||||
|
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(visVOContainer, graphMLContent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used to generate graph content. It will contain both the nodes & edge information.
|
||||||
|
* We are side-effecting "graphMLContent".
|
||||||
|
* */
|
||||||
|
generateGraphContent(visVOContainer, graphMLContent);
|
||||||
|
|
||||||
|
graphMLContent.append(GRAPHML_FOOTER);
|
||||||
|
|
||||||
|
return graphMLContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateGraphContent(VisVOContainer visVOContainer,
|
||||||
|
StringBuilder graphMLContent) {
|
||||||
|
|
||||||
|
graphMLContent.append("\n<graph edgedefault=\"undirected\">\n");
|
||||||
|
|
||||||
|
if (visVOContainer.getNodes() != null & visVOContainer.getNodes().size() > 0) {
|
||||||
|
generateNodeSectionContent(visVOContainer, graphMLContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visVOContainer.getEdges() != null & visVOContainer.getEdges().size() > 0) {
|
||||||
|
generateEdgeSectionContent(visVOContainer, graphMLContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphMLContent.append("</graph>\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateEdgeSectionContent(VisVOContainer visVOContainer,
|
||||||
|
StringBuilder graphMLContent) {
|
||||||
|
|
||||||
|
graphMLContent.append("<!-- edges -->\n");
|
||||||
|
|
||||||
|
Set<Edge> edges = visVOContainer.getEdges();
|
||||||
|
|
||||||
|
|
||||||
|
for (Edge currentEdge : edges) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method actually creates the XML code for a single edge. "graphMLContent"
|
||||||
|
* is being side-effected.
|
||||||
|
* */
|
||||||
|
getEdgeContent(graphMLContent, currentEdge);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getEdgeContent(StringBuilder graphMLContent, Edge 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_coauthored_works\">"
|
||||||
|
+ currentEdge.getNumOfCoAuthoredWorks()
|
||||||
|
+ "</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.
|
||||||
|
* I am feeling dirty just about now.
|
||||||
|
* */
|
||||||
|
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(VisVOContainer visVOContainer,
|
||||||
|
StringBuilder graphMLContent) {
|
||||||
|
|
||||||
|
graphMLContent.append("<!-- nodes -->\n");
|
||||||
|
|
||||||
|
Node egoNode = visVOContainer.getEgoNode();
|
||||||
|
Set<Node> authorNodes = visVOContainer.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-author vis. Ego should always come first.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
getNodeContent(graphMLContent, egoNode);
|
||||||
|
|
||||||
|
|
||||||
|
for (Node currNode : authorNodes) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have already printed the Ego Node info.
|
||||||
|
* */
|
||||||
|
if (currNode != egoNode) {
|
||||||
|
|
||||||
|
getNodeContent(graphMLContent, currNode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getNodeContent(StringBuilder graphMLContent, Node node) {
|
||||||
|
|
||||||
|
String profileURL = null;
|
||||||
|
try {
|
||||||
|
profileURL = "/individual?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(node.getNodeURL(),
|
||||||
|
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.getNodeURL() + "</data>\n");
|
||||||
|
graphMLContent.append("\t<data key=\"name\">" + node.getNodeName() + "</data>\n");
|
||||||
|
|
||||||
|
if (profileURL != null) {
|
||||||
|
graphMLContent.append("\t<data key=\"profile_url\">" + profileURL + "</data>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"number_of_authored_works\">"
|
||||||
|
+ node.getNumOfAuthoredWorks()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
if (node.getEarliestPublicationYearCount() != 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.getEarliestPublicationYearCount().entrySet()) {
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"earliest_publication\">"
|
||||||
|
+ publicationInfo.getKey()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"num_earliest_publication\">"
|
||||||
|
+ publicationInfo.getValue()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.getLatestPublicationYearCount() != null) {
|
||||||
|
|
||||||
|
for (Map.Entry<String, Integer> publicationInfo :
|
||||||
|
node.getLatestPublicationYearCount().entrySet()) {
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"latest_publication\">"
|
||||||
|
+ publicationInfo.getKey()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"num_latest_publication\">"
|
||||||
|
+ publicationInfo.getValue()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.getUnknownPublicationYearCount() != null) {
|
||||||
|
|
||||||
|
graphMLContent.append("\t<data key=\"num_unknown_publication\">"
|
||||||
|
+ node.getUnknownPublicationYearCount()
|
||||||
|
+ "</data>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
graphMLContent.append("</node>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateKeyDefinitionContent(VisVOContainer visVOContainer,
|
||||||
|
StringBuilder graphMLContent) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the key definition content for node.
|
||||||
|
* */
|
||||||
|
getKeyDefinitionFromSchema(visVOContainer.getNodeSchema(), graphMLContent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the key definition content for edge.
|
||||||
|
* */
|
||||||
|
getKeyDefinitionFromSchema(visVOContainer.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,441 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
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.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.UniqueIDGenerator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very dumb name of the class. change it.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QueryHandler {
|
||||||
|
|
||||||
|
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||||
|
|
||||||
|
private String egoURLParam, resultFormatParam, rdfResultFormatParam;
|
||||||
|
private Map<String, VivoCollegeOrSchool> collegeURLToVO = new HashMap<String, VivoCollegeOrSchool>();
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
private UniqueIDGenerator nodeIDGenerator;
|
||||||
|
|
||||||
|
private UniqueIDGenerator edgeIDGenerator;
|
||||||
|
|
||||||
|
public QueryHandler(String egoURLParam,
|
||||||
|
String resultFormatParam, String rdfResultFormatParam,
|
||||||
|
DataSource dataSource, Log log) {
|
||||||
|
|
||||||
|
this.egoURLParam = egoURLParam;
|
||||||
|
this.resultFormatParam = resultFormatParam;
|
||||||
|
this.rdfResultFormatParam = rdfResultFormatParam;
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
this.nodeIDGenerator = new UniqueIDGenerator();
|
||||||
|
this.edgeIDGenerator = new UniqueIDGenerator();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private VisVOContainer createJavaValueObjects(ResultSet resultSet) {
|
||||||
|
|
||||||
|
Set<Node> nodes = new HashSet<Node>();
|
||||||
|
|
||||||
|
Map<String, BiboDocument> biboDocumentURLToVO = new HashMap<String, BiboDocument>();
|
||||||
|
Map<String, Set<Node>> biboDocumentURLToCoAuthors = new HashMap<String, Set<Node>>();
|
||||||
|
Map<String, Node> nodeURLToVO = new HashMap<String, Node>();
|
||||||
|
|
||||||
|
Node egoNode = null;
|
||||||
|
|
||||||
|
Set<Edge> edges = new HashSet<Edge>();
|
||||||
|
|
||||||
|
while (resultSet.hasNext()) {
|
||||||
|
QuerySolution solution = resultSet.nextSolution();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only want to create only ONE ego node.
|
||||||
|
* */
|
||||||
|
RDFNode egoAuthorURLNode = solution.get(QueryFieldLabels.AUTHOR_URL);
|
||||||
|
if (nodeURLToVO.containsKey(egoAuthorURLNode.toString())) {
|
||||||
|
|
||||||
|
egoNode = nodeURLToVO.get(egoAuthorURLNode.toString());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
egoNode = new Node(egoAuthorURLNode.toString(), nodeIDGenerator);
|
||||||
|
nodes.add(egoNode);
|
||||||
|
nodeURLToVO.put(egoAuthorURLNode.toString(), egoNode);
|
||||||
|
|
||||||
|
RDFNode authorLabelNode = solution.get(QueryFieldLabels.AUTHOR_LABEL);
|
||||||
|
if (authorLabelNode != null) {
|
||||||
|
egoNode.setNodeName(authorLabelNode.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RDFNode documentNode = solution.get(QueryFieldLabels.DOCUMENT_URL);
|
||||||
|
BiboDocument biboDocument;
|
||||||
|
|
||||||
|
if (biboDocumentURLToVO.containsKey(documentNode.toString())) {
|
||||||
|
biboDocument = biboDocumentURLToVO.get(documentNode.toString());
|
||||||
|
} else {
|
||||||
|
biboDocument = createDocumentVO(solution, documentNode.toString());
|
||||||
|
biboDocumentURLToVO.put(documentNode.toString(), biboDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
egoNode.addAuthorDocument(biboDocument);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After some discussion we concluded that for the purpose of this visualization
|
||||||
|
* we do not want a co-author node or edge if the publication has only one
|
||||||
|
* author and that happens to be the ego.
|
||||||
|
* */
|
||||||
|
if (solution.get(QueryFieldLabels.AUTHOR_URL).toString().equalsIgnoreCase(
|
||||||
|
solution.get(QueryFieldLabels.CO_AUTHOR_URL).toString())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node coAuthorNode;
|
||||||
|
|
||||||
|
RDFNode coAuthorURLNode = solution.get(QueryFieldLabels.CO_AUTHOR_URL);
|
||||||
|
if (nodeURLToVO.containsKey(coAuthorURLNode.toString())) {
|
||||||
|
|
||||||
|
coAuthorNode = nodeURLToVO.get(coAuthorURLNode.toString());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
coAuthorNode = new Node(coAuthorURLNode.toString(), nodeIDGenerator);
|
||||||
|
nodes.add(coAuthorNode);
|
||||||
|
nodeURLToVO.put(coAuthorURLNode.toString(), coAuthorNode);
|
||||||
|
|
||||||
|
RDFNode coAuthorLabelNode = solution.get(QueryFieldLabels.CO_AUTHOR_LABEL);
|
||||||
|
if (coAuthorLabelNode != null) {
|
||||||
|
coAuthorNode.setNodeName(coAuthorLabelNode.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coAuthorNode.addAuthorDocument(biboDocument);
|
||||||
|
|
||||||
|
Set<Node> coAuthorsForCurrentBiboDocument;
|
||||||
|
|
||||||
|
if (biboDocumentURLToCoAuthors.containsKey(biboDocument.getDocumentURL())) {
|
||||||
|
coAuthorsForCurrentBiboDocument = biboDocumentURLToCoAuthors.get(biboDocument.getDocumentURL());
|
||||||
|
} else {
|
||||||
|
coAuthorsForCurrentBiboDocument = new HashSet<Node>();
|
||||||
|
biboDocumentURLToCoAuthors.put(biboDocument.getDocumentURL(), coAuthorsForCurrentBiboDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
coAuthorsForCurrentBiboDocument.add(coAuthorNode);
|
||||||
|
|
||||||
|
Edge egoCoAuthorEdge = getExistingEdge(egoNode, coAuthorNode, edges);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If "egoCoAuthorEdge" is null it means that no edge exists in between the egoNode & current
|
||||||
|
* coAuthorNode. Else create a new edge, add it to the edges set & add the collaborator document
|
||||||
|
* to it.
|
||||||
|
* */
|
||||||
|
if (egoCoAuthorEdge != null) {
|
||||||
|
egoCoAuthorEdge.addCollaboratorDocument(biboDocument);
|
||||||
|
} else {
|
||||||
|
egoCoAuthorEdge = new Edge(egoNode, coAuthorNode, biboDocument, edgeIDGenerator);
|
||||||
|
edges.add(egoCoAuthorEdge);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to create edges between 2 co-authors. E.g. On a paper there were 3 authors
|
||||||
|
* ego, A & B then we have already created edges like,
|
||||||
|
* ego - A
|
||||||
|
* ego - B
|
||||||
|
* The below sub-routine will take care of,
|
||||||
|
* A - B
|
||||||
|
*
|
||||||
|
* We are side-effecting "edges" here. The only reason to do this is because we are adding
|
||||||
|
* edges en masse for all the co-authors on all the publications considered so far. The other
|
||||||
|
* reason being we dont want to compare against 2 sets of edges (edges created before & co-
|
||||||
|
* author edges created during the course of this method) when we are creating a new edge.
|
||||||
|
* */
|
||||||
|
createCoAuthorEdges(biboDocumentURLToVO,
|
||||||
|
biboDocumentURLToCoAuthors,
|
||||||
|
edges);
|
||||||
|
|
||||||
|
|
||||||
|
/* System.out.println(collegeURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println(departmentURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println(employeeURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
*/
|
||||||
|
return new VisVOContainer(egoNode, nodes, edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createCoAuthorEdges(
|
||||||
|
Map<String, BiboDocument> biboDocumentURLToVO,
|
||||||
|
Map<String, Set<Node>> biboDocumentURLToCoAuthors, Set<Edge> edges) {
|
||||||
|
for (Map.Entry<String, Set<Node>> currentBiboDocumentEntry : biboDocumentURLToCoAuthors.entrySet()) {
|
||||||
|
/*
|
||||||
|
* If there was only one co-author (other than ego) then we dont have to create any edges. so
|
||||||
|
* the below condition will take care of that.
|
||||||
|
* */
|
||||||
|
if (currentBiboDocumentEntry.getValue().size() > 1) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to leverage the nested "for loop" for making edges between all the co=authors
|
||||||
|
* we need to create a list out of the set first.
|
||||||
|
* */
|
||||||
|
List<Node> coAuthorNodes = new ArrayList<Node>(currentBiboDocumentEntry.getValue());
|
||||||
|
|
||||||
|
int numOfCoAuthors = coAuthorNodes.size();
|
||||||
|
|
||||||
|
for (int ii = 0; ii < numOfCoAuthors - 1; ii++) {
|
||||||
|
for (int jj = ii + 1; jj < numOfCoAuthors; jj++) {
|
||||||
|
|
||||||
|
Node coAuthor1 = coAuthorNodes.get(ii);
|
||||||
|
Node coAuthor2 = coAuthorNodes.get(jj);
|
||||||
|
|
||||||
|
Edge coAuthor1_2Edge = getExistingEdge(coAuthor1, coAuthor2, edges);
|
||||||
|
|
||||||
|
BiboDocument currentBiboDocument = biboDocumentURLToVO
|
||||||
|
.get(currentBiboDocumentEntry.getKey());
|
||||||
|
|
||||||
|
if (coAuthor1_2Edge != null) {
|
||||||
|
coAuthor1_2Edge.addCollaboratorDocument(currentBiboDocument);
|
||||||
|
} else {
|
||||||
|
coAuthor1_2Edge = new Edge(coAuthor1, coAuthor2, currentBiboDocument, edgeIDGenerator);
|
||||||
|
edges.add(coAuthor1_2Edge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Edge getExistingEdge(
|
||||||
|
Node collaboratingNode1,
|
||||||
|
Node collaboratingNode2,
|
||||||
|
Set<Edge> edges) {
|
||||||
|
|
||||||
|
Edge duplicateEdge = null;
|
||||||
|
|
||||||
|
for (Edge currentEdge : edges) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We first check if either the source or target node of the current edge is
|
||||||
|
* the collaboratingNode1. If yes then we go on to check if the collaboratingNode2
|
||||||
|
* matches either the source or the target node. We dont care about the directionality
|
||||||
|
* of the edge.
|
||||||
|
* */
|
||||||
|
if (currentEdge.getSourceNode().getNodeID() == collaboratingNode1.getNodeID()
|
||||||
|
|| currentEdge.getTargetNode().getNodeID() == collaboratingNode1.getNodeID()) {
|
||||||
|
|
||||||
|
if (currentEdge.getSourceNode().getNodeID() == collaboratingNode2.getNodeID()
|
||||||
|
|| currentEdge.getTargetNode().getNodeID() == collaboratingNode2.getNodeID()) {
|
||||||
|
|
||||||
|
duplicateEdge = currentEdge;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return duplicateEdge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, VivoCollegeOrSchool> getCollegeURLToVO() {
|
||||||
|
return collegeURLToVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiboDocument createDocumentVO(QuerySolution solution, String documentURL) {
|
||||||
|
|
||||||
|
BiboDocument biboDocument = new BiboDocument(documentURL);
|
||||||
|
|
||||||
|
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 publicationYearNode = solution.get(QueryFieldLabels.DOCUMENT_PUBLICATION_YEAR);
|
||||||
|
if (publicationYearNode != null) {
|
||||||
|
biboDocument.setPublicationYear(publicationYearNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return biboDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet executeQuery(String queryText,
|
||||||
|
String resultFormatParam,
|
||||||
|
String rdfResultFormatParam,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
//remocve this if loop after knowing what is describe & construct sparql stuff.
|
||||||
|
if (query.isSelectType()){
|
||||||
|
return queryExecution.execSelect();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if(queryExecution != null) {
|
||||||
|
queryExecution.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateEgoCoAuthorshipSparqlQuery(String queryURI) {
|
||||||
|
// Resource uri1 = ResourceFactory.createResource(queryURI);
|
||||||
|
|
||||||
|
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||||
|
+ "SELECT "
|
||||||
|
+ " (str(<" + queryURI + ">) as ?" + QueryFieldLabels.AUTHOR_URL + ") "
|
||||||
|
+ " (str(?authorLabel) as ?" + QueryFieldLabels.AUTHOR_LABEL + ") "
|
||||||
|
+ " (str(?coAuthorPerson) as ?" + QueryFieldLabels.CO_AUTHOR_URL + ") "
|
||||||
|
+ " (str(?coAuthorPersonLabel) as ?" + QueryFieldLabels.CO_AUTHOR_LABEL + ") "
|
||||||
|
+ " (str(?document) as ?" + QueryFieldLabels.DOCUMENT_URL + ") "
|
||||||
|
+ " (str(?documentLabel) as ?" + QueryFieldLabels.DOCUMENT_LABEL + ") "
|
||||||
|
+ " (str(?documentMoniker) as ?" + QueryFieldLabels.DOCUMENT_MONIKER + ") "
|
||||||
|
+ " (str(?documentBlurb) as ?" + QueryFieldLabels.DOCUMENT_BLURB + ") "
|
||||||
|
+ " (str(?publicationYear) as ?" + QueryFieldLabels.DOCUMENT_PUBLICATION_YEAR + ") "
|
||||||
|
+ "WHERE { "
|
||||||
|
+ "<" + queryURI + "> rdf:type foaf:Person ; vivo:authorOf ?document ; rdfs:label ?authorLabel. "
|
||||||
|
+ "?document rdf:type bibo:Document . "
|
||||||
|
+ "?document rdfs:label ?documentLabel . "
|
||||||
|
+ "?document vivo:hasAuthor ?coAuthorPerson . "
|
||||||
|
+ "?coAuthorPerson rdfs:label ?coAuthorPersonLabel . "
|
||||||
|
+ "OPTIONAL { ?document vivo:publicationYear ?publicationYear } . "
|
||||||
|
+ "OPTIONAL { ?document vitro:moniker ?documentMoniker } . "
|
||||||
|
+ "OPTIONAL { ?document vitro:blurb ?documentBlurb } . "
|
||||||
|
+ "OPTIONAL { ?document vitro:description ?documentDescription } "
|
||||||
|
// + "FILTER (<" + queryURI + "> != ?coAuthorPerson ) . "
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
System.out.println(sparqlQuery);
|
||||||
|
|
||||||
|
return sparqlQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public VisVOContainer getVisualizationJavaValueObjects()
|
||||||
|
throws MalformedQueryParametersException {
|
||||||
|
|
||||||
|
if (this.egoURLParam == null || "".equals(egoURLParam)) {
|
||||||
|
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To test for the validity of the URI submitted.
|
||||||
|
* */
|
||||||
|
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||||
|
IRI iri = iRIFactory.create(this.egoURLParam);
|
||||||
|
if (iri.hasViolation(false)) {
|
||||||
|
String errorMsg = ((Violation)iri.violations(false).next()).getShortMessage()+" ";
|
||||||
|
log.error("Ego Co Authorship Vis Query " + errorMsg);
|
||||||
|
throw new MalformedQueryParametersException("URI provided for an individual is malformed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet resultSet = executeQuery(generateEgoCoAuthorshipSparqlQuery(this.egoURLParam),
|
||||||
|
this.resultFormatParam,
|
||||||
|
this.rdfResultFormatParam,
|
||||||
|
this.dataSource);
|
||||||
|
|
||||||
|
return createJavaValueObjects(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getYearToPublicationCount(
|
||||||
|
Set<BiboDocument> authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
for (BiboDocument curr : authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increment the count because there is an entry already available for
|
||||||
|
* that particular year.
|
||||||
|
* */
|
||||||
|
String publicationYear;
|
||||||
|
if (curr.getPublicationYear() != null
|
||||||
|
&& curr.getPublicationYear().length() != 0
|
||||||
|
&& curr.getPublicationYear().trim().length() != 0) {
|
||||||
|
publicationYear = curr.getPublicationYear();
|
||||||
|
} else {
|
||||||
|
publicationYear = curr.getParsedPublicationYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yearToPublicationCount.containsKey(publicationYear)) {
|
||||||
|
yearToPublicationCount.put(publicationYear,
|
||||||
|
yearToPublicationCount
|
||||||
|
.get(publicationYear) + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
yearToPublicationCount.put(publicationYear, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("****************************\n" + yearToPublicationCount);
|
||||||
|
return yearToPublicationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Edge;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||||
|
|
||||||
|
public class VisVOContainer {
|
||||||
|
|
||||||
|
private Set<Node> nodes;
|
||||||
|
private Set<Edge> edges;
|
||||||
|
private Node egoNode;
|
||||||
|
private Set<Map<String, String>> NODE_SCHEMA;
|
||||||
|
private Set<Map<String, String>> EDGE_SCHEMA;
|
||||||
|
|
||||||
|
public VisVOContainer(Node egoNode, Set<Node> nodes, Set<Edge> edges) {
|
||||||
|
this.egoNode = egoNode;
|
||||||
|
this.nodes = nodes;
|
||||||
|
this.edges = edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Node> getNodes() {
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Edge> getEdges() {
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getEgoNode() {
|
||||||
|
return egoNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Node Schema for graphML
|
||||||
|
* */
|
||||||
|
public Set<Map<String, String>> getNodeSchema() {
|
||||||
|
|
||||||
|
if (NODE_SCHEMA == null) {
|
||||||
|
NODE_SCHEMA = initializeNodeSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NODE_SCHEMA;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edge Schema for graphML
|
||||||
|
* */
|
||||||
|
public Set<Map<String, String>> getEdgeSchema() {
|
||||||
|
|
||||||
|
if (EDGE_SCHEMA == null) {
|
||||||
|
EDGE_SCHEMA = initializeEdgeSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
return EDGE_SCHEMA;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Map<String, String>> initializeEdgeSchema() {
|
||||||
|
|
||||||
|
Set<Map<String, String>> edgeSchema = new HashSet<Map<String,String>>();
|
||||||
|
|
||||||
|
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "collaborator1");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "collaborator1");
|
||||||
|
schemaAttributes.put("attr.type", "string");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "collaborator2");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "collaborator2");
|
||||||
|
schemaAttributes.put("attr.type", "string");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "number_of_coauthored_works");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "number_of_coauthored_works");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "earliest_collaboration");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "earliest_collaboration");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_earliest_collaboration");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "num_earliest_collaboration");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "latest_collaboration");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "latest_collaboration");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_latest_collaboration");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "num_latest_collaboration");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_unknown_collaboration");
|
||||||
|
schemaAttributes.put("for", "edge");
|
||||||
|
schemaAttributes.put("attr.name", "num_unknown_collaboration");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
edgeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
return edgeSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Set<Map<String, String>> initializeNodeSchema() {
|
||||||
|
|
||||||
|
Set<Map<String, String>> nodeSchema = new HashSet<Map<String,String>>();
|
||||||
|
|
||||||
|
Map<String, String> schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "url");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "url");
|
||||||
|
schemaAttributes.put("attr.type", "string");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "name");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "name");
|
||||||
|
schemaAttributes.put("attr.type", "string");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "profile_url");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "profile_url");
|
||||||
|
schemaAttributes.put("attr.type", "string");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "number_of_authored_works");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "number_of_authored_works");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "earliest_publication");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "earliest_publication");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_earliest_publication");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "num_earliest_publication");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "latest_publication");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "latest_publication");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_latest_publication");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "num_latest_publication");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
schemaAttributes = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
schemaAttributes.put("id", "num_unknown_publication");
|
||||||
|
schemaAttributes.put("for", "node");
|
||||||
|
schemaAttributes.put("attr.name", "num_unknown_publication");
|
||||||
|
schemaAttributes.put("attr.type", "int");
|
||||||
|
|
||||||
|
nodeSchema.add(schemaAttributes);
|
||||||
|
|
||||||
|
|
||||||
|
return nodeSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,643 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
|
||||||
|
|
||||||
|
|
||||||
|
public class VisualizationCodeGenerator {
|
||||||
|
|
||||||
|
private final static Map<String, String> visDivNames = new HashMap<String, String>() {{
|
||||||
|
|
||||||
|
put("SHORT_SPARK", "unique_coauthors_short_sparkline_vis");
|
||||||
|
put("FULL_SPARK", "unique_coauthors_full_sparkline_vis");
|
||||||
|
|
||||||
|
}};
|
||||||
|
|
||||||
|
private static final String visualizationStyleClass = "sparkline_style";
|
||||||
|
|
||||||
|
private static final String defaultVisContainerDivID = "unique_coauthors_vis_container";
|
||||||
|
|
||||||
|
public static final String SHORT_SPARKLINE_MODE_URL_HANDLE = "short";
|
||||||
|
|
||||||
|
public static final String FULL_SPARKLINE_MODE_URL_HANDLE = "full";
|
||||||
|
|
||||||
|
private Map<String, Integer> yearToUniqueCoauthorsCount;
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
private SparklineVOContainer valueObjectContainer;
|
||||||
|
|
||||||
|
private String contextPath;
|
||||||
|
|
||||||
|
private String individualURIParam;
|
||||||
|
|
||||||
|
public VisualizationCodeGenerator(String contextPath,
|
||||||
|
String individualURIParam,
|
||||||
|
String visMode,
|
||||||
|
String visContainer,
|
||||||
|
Map<String, Integer> yearToUniqueCoauthorsCount,
|
||||||
|
SparklineVOContainer valueObjectContainer,
|
||||||
|
Log log) {
|
||||||
|
|
||||||
|
this.contextPath = contextPath;
|
||||||
|
this.individualURIParam = individualURIParam;
|
||||||
|
|
||||||
|
this.yearToUniqueCoauthorsCount = yearToUniqueCoauthorsCount;
|
||||||
|
this.valueObjectContainer = valueObjectContainer;
|
||||||
|
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
|
||||||
|
generateVisualizationCode(visMode,
|
||||||
|
visContainer);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateVisualizationCode(String visMode,
|
||||||
|
String visContainer) {
|
||||||
|
|
||||||
|
valueObjectContainer.setSparklineContent(getMainVisualizationCode(visMode,
|
||||||
|
visContainer));
|
||||||
|
|
||||||
|
|
||||||
|
valueObjectContainer.setSparklineContext(getVisualizationContextCode(visMode));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMainVisualizationCode(String visMode,
|
||||||
|
String providedVisContainerID) {
|
||||||
|
|
||||||
|
int numOfYearsToBeRendered = 0;
|
||||||
|
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
int shortSparkMinYear = currentYear - 10 + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is required because when deciding the range of years over which the vis
|
||||||
|
* was rendered we dont want to be influenced by the "DEFAULT_PUBLICATION_YEAR".
|
||||||
|
* */
|
||||||
|
Set<String> publishedYears = new HashSet(yearToUniqueCoauthorsCount.keySet());
|
||||||
|
publishedYears.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are setting the default value of minPublishedYear to be 10 years before
|
||||||
|
* the current year (which is suitably represented by the shortSparkMinYear),
|
||||||
|
* this in case we run into invalid set of published years.
|
||||||
|
* */
|
||||||
|
int minPublishedYear = shortSparkMinYear;
|
||||||
|
|
||||||
|
String visContainerID = null;
|
||||||
|
|
||||||
|
StringBuilder visualizationCode = new StringBuilder();
|
||||||
|
|
||||||
|
// System.out.println(yearToPublicationCount);
|
||||||
|
if (yearToUniqueCoauthorsCount.size() > 0) {
|
||||||
|
try {
|
||||||
|
minPublishedYear = Integer.parseInt(Collections.min(publishedYears));
|
||||||
|
System.out.println("min pub year - " + minPublishedYear);
|
||||||
|
} catch (NoSuchElementException e1) {
|
||||||
|
log.debug("vis: " + e1.getMessage() + " error occurred for " + yearToUniqueCoauthorsCount.toString());
|
||||||
|
} catch (NumberFormatException e2) {
|
||||||
|
log.debug("vis: " + e2.getMessage() + " error occurred for " + yearToUniqueCoauthorsCount.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int minPubYearConsidered = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There might be a case that the author has made his first publication within the
|
||||||
|
* last 10 years but we want to make sure that the sparkline is representative of
|
||||||
|
* at least the last 10 years, so we will set the minPubYearConsidered to
|
||||||
|
* "currentYear - 10" which is also given by "shortSparkMinYear".
|
||||||
|
* */
|
||||||
|
if (minPublishedYear > shortSparkMinYear) {
|
||||||
|
minPubYearConsidered = shortSparkMinYear;
|
||||||
|
} else {
|
||||||
|
minPubYearConsidered = minPublishedYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
numOfYearsToBeRendered = currentYear - minPubYearConsidered + 1;
|
||||||
|
|
||||||
|
visualizationCode.append("<style type='text/css'>" +
|
||||||
|
"." + visualizationStyleClass + " table{" +
|
||||||
|
" margin: 0;" +
|
||||||
|
" padding: 0;" +
|
||||||
|
" width: auto;" +
|
||||||
|
" border-collapse: collapse;" +
|
||||||
|
" border-spacing: 0;" +
|
||||||
|
" vertical-align: inherit;" +
|
||||||
|
"}" +
|
||||||
|
/*".sparkline_wrapper_table table{" +
|
||||||
|
" vertical-align: bottom;" +
|
||||||
|
"}" +*/
|
||||||
|
"td.sparkline_number { text-align:right; padding-right:5px; }" +
|
||||||
|
"td.sparkline_text {text-align:left;}" +
|
||||||
|
/*"#sparkline_data_table {" +
|
||||||
|
"width: auto;" +
|
||||||
|
"}" +
|
||||||
|
"#sparkline_data_table tfoot {" +
|
||||||
|
"color: red;" +
|
||||||
|
"font-size:0.9em;" +
|
||||||
|
"}" +
|
||||||
|
".sparkline_text {" +
|
||||||
|
"margin-left:72px;" +
|
||||||
|
"position:absolute;" +
|
||||||
|
"}" +
|
||||||
|
".sparkline_range {" +
|
||||||
|
"color:#7BA69E;" +
|
||||||
|
"font-size:0.9em;" +
|
||||||
|
"font-style:italic;" +
|
||||||
|
"}" +*/
|
||||||
|
"</style>\n");
|
||||||
|
|
||||||
|
// .sparkline {display:inline; margin:0; padding:0; width:600px }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// td.sparkline-img {margin:0; padding:0; }
|
||||||
|
|
||||||
|
|
||||||
|
visualizationCode.append("<script type=\"text/javascript\">\n" +
|
||||||
|
"function drawUniqueCoauthorCountVisualization(providedSparklineImgTD) {\n" +
|
||||||
|
"var data = new google.visualization.DataTable();\n" +
|
||||||
|
"data.addColumn('string', 'Year');\n" +
|
||||||
|
"data.addColumn('number', 'Unique co-authors');\n" +
|
||||||
|
"data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||||
|
|
||||||
|
int uniqueCoAuthorCounter = 0;
|
||||||
|
int totalUniqueCoAuthors = 0;
|
||||||
|
int renderedFullSparks = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (int publicationYear = minPubYearConsidered; publicationYear <= currentYear; publicationYear++) {
|
||||||
|
|
||||||
|
String stringPublishedYear = String.valueOf(publicationYear);
|
||||||
|
Integer currentPublications = yearToUniqueCoauthorsCount.get(stringPublishedYear);
|
||||||
|
|
||||||
|
if (currentPublications == null) {
|
||||||
|
currentPublications = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
visualizationCode.append("data.setValue("
|
||||||
|
+ uniqueCoAuthorCounter
|
||||||
|
+ ", 0, '"
|
||||||
|
+ stringPublishedYear
|
||||||
|
+ "');\n");
|
||||||
|
|
||||||
|
visualizationCode.append("data.setValue("
|
||||||
|
+ uniqueCoAuthorCounter
|
||||||
|
+ ", 1, "
|
||||||
|
+ currentPublications
|
||||||
|
+ ");\n");
|
||||||
|
|
||||||
|
totalUniqueCoAuthors += currentPublications;
|
||||||
|
uniqueCoAuthorCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sparks that will be rendered in full mode will always be the one's which has any year
|
||||||
|
* associated with it. Hence.
|
||||||
|
* */
|
||||||
|
renderedFullSparks = totalUniqueCoAuthors;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Total publications will also consider publications that have no year associated with
|
||||||
|
* it. Hence.
|
||||||
|
* */
|
||||||
|
if (yearToUniqueCoauthorsCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR) != null) {
|
||||||
|
totalUniqueCoAuthors += yearToUniqueCoauthorsCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sparklineDisplayOptions = "{width: 63, height: 21, showAxisLines: false, " +
|
||||||
|
"showValueLabels: false, labelPosition: 'none'}";
|
||||||
|
|
||||||
|
if (providedVisContainerID != null) {
|
||||||
|
visContainerID = providedVisContainerID;
|
||||||
|
} else {
|
||||||
|
visContainerID = defaultVisContainerDivID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default these represents the range of the rendered sparks. Only in case of
|
||||||
|
* "short" sparkline mode we will set the Earliest RenderedPublication year to
|
||||||
|
* "currentYear - 10".
|
||||||
|
* */
|
||||||
|
valueObjectContainer.setEarliestRenderedPublicationYear(minPublishedYear);
|
||||||
|
valueObjectContainer.setLatestRenderedPublicationYear(currentYear);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Full Sparkline will be rendered by default. Only if the url has specific mention of
|
||||||
|
* SHORT_SPARKLINE_MODE_URL_HANDLE then we render the short sparkline and not otherwise.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since building StringBuilder objects (which is being used to store the vis code) is
|
||||||
|
* essentially a side-effecting process, we have both the activators method as side-effecting.
|
||||||
|
* They both side-effect "visualizationCode"
|
||||||
|
* */
|
||||||
|
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
|
||||||
|
|
||||||
|
valueObjectContainer.setEarliestRenderedPublicationYear(shortSparkMinYear);
|
||||||
|
generateShortSparklineVisualizationContent(currentYear,
|
||||||
|
shortSparkMinYear,
|
||||||
|
visContainerID,
|
||||||
|
visualizationCode,
|
||||||
|
totalUniqueCoAuthors,
|
||||||
|
sparklineDisplayOptions);
|
||||||
|
} else {
|
||||||
|
generateFullSparklineVisualizationContent(currentYear,
|
||||||
|
minPubYearConsidered,
|
||||||
|
visContainerID,
|
||||||
|
visualizationCode,
|
||||||
|
totalUniqueCoAuthors,
|
||||||
|
renderedFullSparks,
|
||||||
|
sparklineDisplayOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
log.debug(visualizationCode);
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
|
||||||
|
return visualizationCode.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||||
|
int shortSparkMinYear, String visContainerID,
|
||||||
|
StringBuilder visualizationCode, int totalUniqueCoAuthors,
|
||||||
|
String sparklineDisplayOptions) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a view of the data containing only the column pertaining to publication count.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var shortSparklineView = new google.visualization.DataView(data);\n" +
|
||||||
|
"shortSparklineView.setColumns([1]);\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the short view we only want the last 10 year's view of publication count,
|
||||||
|
* hence we filter the data we actually want to use for render.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("shortSparklineView.setRows(" +
|
||||||
|
"data.getFilteredRows([{column: 0, " +
|
||||||
|
"minValue: '" + shortSparkMinYear + "', " +
|
||||||
|
"maxValue: '" + currentYear+ "'}])" +
|
||||||
|
");\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the vis object and draw it in the div pertaining to short-sparkline.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var short_spark = new google.visualization.ImageSparkLine(" +
|
||||||
|
// "document.getElementById('" + visDivNames.get("SHORT_SPARK") + "')" +
|
||||||
|
"providedSparklineImgTD[0]" +
|
||||||
|
");\n" +
|
||||||
|
"short_spark.draw(shortSparklineView, " + sparklineDisplayOptions + ");\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We want to display how many publication counts were considered, so this is used
|
||||||
|
* to calculate this.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var shortSparkRows = shortSparklineView.getViewRows();\n" +
|
||||||
|
"var renderedShortSparks = 0;\n" +
|
||||||
|
"$.each(shortSparkRows, function(index, value) {" +
|
||||||
|
"renderedShortSparks += data.getValue(value, 1);" +
|
||||||
|
"});\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the text introducing the vis.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("$('#" + visDivNames.get("SHORT_SPARK") + " td.sparkline_number').text(renderedShortSparks);");
|
||||||
|
visualizationCode.append("var shortSparksText = ''" +
|
||||||
|
"+ ' Unique co-authors with year from '" +
|
||||||
|
"+ ' " + totalUniqueCoAuthors + " '" +
|
||||||
|
"+ ' total " +
|
||||||
|
"<span class=\"sparkline_range\">" +
|
||||||
|
"(" + shortSparkMinYear + " - " + currentYear + ")" +
|
||||||
|
"</span>'" +
|
||||||
|
"+ '';" +
|
||||||
|
"$('#" + visDivNames.get("SHORT_SPARK") + " td.sparkline_text').html(shortSparksText);");
|
||||||
|
|
||||||
|
visualizationCode.append("}\n ");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the code that will activate the visualization. It takes care of creating div elements to hold
|
||||||
|
* the actual sparkline image and then calling the drawUniqueCoauthorCountVisualization function.
|
||||||
|
* */
|
||||||
|
visualizationCode.append(generateVisualizationActivator(visDivNames.get("SHORT_SPARK"), visContainerID));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateFullSparklineVisualizationContent(
|
||||||
|
int currentYear, int minPubYearConsidered, String visContainerID, StringBuilder visualizationCode,
|
||||||
|
int totalUniqueCoAuthors, int renderedFullSparks,
|
||||||
|
String sparklineDisplayOptions) {
|
||||||
|
|
||||||
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getCSVDownloadURL() != null) {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\" class=\"inline_href\">(.CSV File)</a>";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
visualizationCode.append("var fullSparklineView = new google.visualization.DataView(data);\n" +
|
||||||
|
"fullSparklineView.setColumns([1]);\n");
|
||||||
|
|
||||||
|
visualizationCode.append("var full_spark = new google.visualization.ImageSparkLine(" +
|
||||||
|
// "document.getElementById('" + visDivNames.get("FULL_SPARK") + "')" +
|
||||||
|
"providedSparklineImgTD[0]" +
|
||||||
|
");\n" +
|
||||||
|
"full_spark.draw(fullSparklineView, " + sparklineDisplayOptions + ");\n");
|
||||||
|
|
||||||
|
visualizationCode.append("$('#" + visDivNames.get("FULL_SPARK") + " td.sparkline_number').text('" + renderedFullSparks + "');");
|
||||||
|
|
||||||
|
visualizationCode.append("var allSparksText = ''" +
|
||||||
|
"+ ' Unique co-authors '" +
|
||||||
|
"+ ' <span class=\"sparkline_range\">" +
|
||||||
|
"(" + minPubYearConsidered + " - " + currentYear + ")" +
|
||||||
|
"</span> '" +
|
||||||
|
"+ ' " + csvDownloadURLHref + " ';" +
|
||||||
|
"$('#" + visDivNames.get("FULL_SPARK") + " td.sparkline_text').html(allSparksText);");
|
||||||
|
|
||||||
|
visualizationCode.append("}\n ");
|
||||||
|
|
||||||
|
visualizationCode.append(generateVisualizationActivator(visDivNames.get("FULL_SPARK"), visContainerID));
|
||||||
|
|
||||||
|
}
|
||||||
|
private String generateVisualizationActivator(String sparklineID, String visContainerID) {
|
||||||
|
|
||||||
|
String sparklineTableWrapper = "\n" +
|
||||||
|
"var table = $('<table>');" +
|
||||||
|
"table.attr('class', 'sparkline_wrapper_table');" +
|
||||||
|
"var row = $('<tr>');" +
|
||||||
|
"sparklineImgTD = $('<td>');" +
|
||||||
|
"sparklineImgTD.attr('id', '" + sparklineID + "_img');" +
|
||||||
|
"sparklineImgTD.attr('width', '65');" +
|
||||||
|
"sparklineImgTD.attr('align', 'right');" +
|
||||||
|
"sparklineImgTD.attr('class', '" + visualizationStyleClass + "');" +
|
||||||
|
"row.append(sparklineImgTD);" +
|
||||||
|
"var sparklineNumberTD = $('<td>');" +
|
||||||
|
"sparklineNumberTD.attr('width', '36');" +
|
||||||
|
"sparklineNumberTD.attr('align', 'right');" +
|
||||||
|
"sparklineNumberTD.attr('class', 'sparkline_number');" +
|
||||||
|
"row.append(sparklineNumberTD);" +
|
||||||
|
"var sparklineTextTD = $('<td>');" +
|
||||||
|
"sparklineTextTD.attr('width', '350');" +
|
||||||
|
"sparklineTextTD.attr('class', 'sparkline_text');" +
|
||||||
|
"row.append(sparklineTextTD);" +
|
||||||
|
"table.append(row);" +
|
||||||
|
"table.prependTo('#" + sparklineID + "');\n";
|
||||||
|
|
||||||
|
return "$(document).ready(function() {" +
|
||||||
|
|
||||||
|
"var sparklineImgTD; " +
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a nuclear option (creating the container in which everything goes)
|
||||||
|
* the only reason this will be ever used is the API user never submitted a
|
||||||
|
* container ID in which everything goes. The alternative was to let the
|
||||||
|
* vis not appear in the calling page at all. So now atleast vis appears but
|
||||||
|
* appended at the bottom of the body.
|
||||||
|
* */
|
||||||
|
"if ($('#" + visContainerID + "').length === 0) {" +
|
||||||
|
" $('<div/>', {'id': '" + visContainerID + "'" +
|
||||||
|
" }).appendTo('body');" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"if ($('#" + sparklineID + "').length === 0) {" +
|
||||||
|
|
||||||
|
"$('<div/>', {'id': '" + sparklineID + "'," +
|
||||||
|
"'class': '" + visualizationStyleClass + "'" +
|
||||||
|
"}).prependTo('#" + visContainerID + "');" +
|
||||||
|
|
||||||
|
sparklineTableWrapper +
|
||||||
|
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"drawUniqueCoauthorCountVisualization(sparklineImgTD);" +
|
||||||
|
"});" +
|
||||||
|
"</script>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getVisualizationContextCode(String visMode) {
|
||||||
|
|
||||||
|
String visualizationContextCode = "";
|
||||||
|
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
|
||||||
|
visualizationContextCode = generateShortVisContext();
|
||||||
|
} else {
|
||||||
|
visualizationContextCode = generateFullVisContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
log.debug(visualizationContextCode);
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
|
||||||
|
return visualizationContextCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateFullVisContext() {
|
||||||
|
|
||||||
|
StringBuilder divContextCode = new StringBuilder();
|
||||||
|
|
||||||
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
if (yearToUniqueCoauthorsCount.size() > 0) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getCSVDownloadURL() != null) {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "Download data as <a href='" + getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||||
|
valueObjectContainer.setDownloadDataLink(getCSVDownloadURL());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
csvDownloadURLHref = "No data available to export.<br />";
|
||||||
|
}
|
||||||
|
|
||||||
|
String tableCode = generateDataTable();
|
||||||
|
|
||||||
|
divContextCode.append("<p>" + tableCode +
|
||||||
|
csvDownloadURLHref + "</p>");
|
||||||
|
|
||||||
|
valueObjectContainer.setTable(tableCode);
|
||||||
|
|
||||||
|
return divContextCode.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCSVDownloadURL()
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
|
||||||
|
if (yearToUniqueCoauthorsCount.size() > 0) {
|
||||||
|
|
||||||
|
String secondaryContextPath = "";
|
||||||
|
if (!contextPath.contains("/admin/visQuery")) {
|
||||||
|
secondaryContextPath = "/admin/visQuery";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String downloadURL = contextPath
|
||||||
|
+ secondaryContextPath
|
||||||
|
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationController
|
||||||
|
.COAUTHORSHIP_VIS_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&" + VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("sparkline",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
System.out.println(" ----- >>>> " + contextPath + " XX " + individualURIParam + " XX " + downloadURL);
|
||||||
|
|
||||||
|
return downloadURL;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String generateShortVisContext() {
|
||||||
|
|
||||||
|
StringBuilder divContextCode = new StringBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
String fullTimelineLink;
|
||||||
|
if (yearToUniqueCoauthorsCount.size() > 0) {
|
||||||
|
|
||||||
|
String secondaryContextPath = "";
|
||||||
|
if (!contextPath.contains("/admin/visQuery")) {
|
||||||
|
secondaryContextPath = "/admin/visQuery";
|
||||||
|
}
|
||||||
|
|
||||||
|
String fullTimelineNetworkURL = contextPath
|
||||||
|
+ secondaryContextPath
|
||||||
|
+ "?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("person_level",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("ego_sparkline",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.STANDALONE_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
System.out.println("context parth full n/w " + contextPath);
|
||||||
|
|
||||||
|
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View full timeline and co-author network</a><br />";
|
||||||
|
|
||||||
|
valueObjectContainer.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
divContextCode.append("<p>" + fullTimelineLink + "</p>");
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return divContextCode.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String generateDataTable() {
|
||||||
|
|
||||||
|
StringBuilder dataTable = new StringBuilder();
|
||||||
|
|
||||||
|
dataTable.append("<table id='sparkline_data_table'>" +
|
||||||
|
"<caption>Unique Co-Authors per year</caption>" +
|
||||||
|
"<thead>" +
|
||||||
|
"<tr>" +
|
||||||
|
"<th>Year</th>" +
|
||||||
|
"<th>Count</th>" +
|
||||||
|
"</tr>" +
|
||||||
|
"</thead>" +
|
||||||
|
"<tbody>");
|
||||||
|
|
||||||
|
for (Entry<String, Integer> currentEntry : yearToUniqueCoauthorsCount.entrySet()) {
|
||||||
|
dataTable.append("<tr>" +
|
||||||
|
"<td>" + currentEntry.getKey() + "</td>" +
|
||||||
|
"<td>" + currentEntry.getValue() + "</td>" +
|
||||||
|
"</tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
dataTable.append("</tbody>\n" +
|
||||||
|
// "<tfoot>" +
|
||||||
|
// "<tr><td colspan='2'>*DNA - Data not available</td></tr>" +
|
||||||
|
// "</tfoot>\n" +
|
||||||
|
"</table>\n");
|
||||||
|
|
||||||
|
|
||||||
|
return dataTable.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,343 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.skife.csv.CSVWriter;
|
||||||
|
import org.skife.csv.SimpleWriter;
|
||||||
|
|
||||||
|
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.Node;
|
||||||
|
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.visutils.UtilityFunctions;
|
||||||
|
|
||||||
|
public class VisualizationRequestHandler {
|
||||||
|
|
||||||
|
private VitroRequest vitroRequest;
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private HttpServletResponse response;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public VisualizationRequestHandler(VitroRequest vitroRequest,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Log log) {
|
||||||
|
|
||||||
|
this.vitroRequest = vitroRequest;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateVisualization(DataSource dataSource) {
|
||||||
|
|
||||||
|
String resultFormatParam = "RS_TEXT";
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
String egoURIParam = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
|
||||||
|
|
||||||
|
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visContainer = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE);
|
||||||
|
|
||||||
|
String sparklineVisMode = "sparkline";
|
||||||
|
|
||||||
|
QueryHandler queryManager =
|
||||||
|
new QueryHandler(egoURIParam,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
VisVOContainer authorNodesAndEdges = queryManager.getVisualizationJavaValueObjects();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to avoid unneeded computations we have pushed this "if" condition up.
|
||||||
|
* This case arises when the render mode is data. In that case we dont want to generate
|
||||||
|
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
|
||||||
|
* It is ugly!
|
||||||
|
* */
|
||||||
|
|
||||||
|
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We will be using the same visualization package for both sparkline & coauthorship flash
|
||||||
|
* vis. We will use "VIS_MODE_URL_HANDLE" as a modifier to differentiate between these two.
|
||||||
|
* The defualt will be to render the coauthorship network vis.
|
||||||
|
* */
|
||||||
|
|
||||||
|
if (sparklineVisMode.equalsIgnoreCase(visMode)) {
|
||||||
|
/*
|
||||||
|
* When the csv file is required - based on which sparkline visualization will
|
||||||
|
* be rendered.
|
||||||
|
* */
|
||||||
|
prepareVisualizationQuerySparklineDataResponse(authorNodesAndEdges);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* When the graphML file is required - based on which coauthorship network visualization
|
||||||
|
* will be rendered.
|
||||||
|
* */
|
||||||
|
prepareVisualizationQueryNetworkDataResponse(authorNodesAndEdges);
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*
|
||||||
|
VisualizationCodeGenerator visualizationCodeGenerator =
|
||||||
|
new VisualizationCodeGenerator(yearToPublicationCount, log);
|
||||||
|
|
||||||
|
String visContentCode = visualizationCodeGenerator
|
||||||
|
.getMainVisualizationCode(authorDocuments,
|
||||||
|
publishedYears,
|
||||||
|
visMode,
|
||||||
|
visContainer);
|
||||||
|
|
||||||
|
String visContextCode = visualizationCodeGenerator
|
||||||
|
.getVisualizationContextCode(vitroRequest.getRequestURI(),
|
||||||
|
collegeURIParam,
|
||||||
|
visMode);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the response of this method is just to redirect to
|
||||||
|
* a page with visualization on it.
|
||||||
|
* */
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = null;
|
||||||
|
|
||||||
|
prepareVisualizationQueryStandaloneResponse(egoURIParam, request, response, vitroRequest);
|
||||||
|
|
||||||
|
// requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.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 {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} catch (ServletException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryNetworkDataResponse(VisVOContainer authorNodesAndEdges) {
|
||||||
|
|
||||||
|
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.
|
||||||
|
* */
|
||||||
|
|
||||||
|
CoAuthorshipGraphMLWriter coAuthorShipGraphMLWriter = new CoAuthorshipGraphMLWriter(authorNodesAndEdges);
|
||||||
|
|
||||||
|
responseWriter.append(coAuthorShipGraphMLWriter.getCoAuthorshipGraphMLContent());
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQuerySparklineDataResponse(VisVOContainer authorNodesAndEdges) {
|
||||||
|
|
||||||
|
String outputFileName = "";
|
||||||
|
Map<String, Set<Node>> yearToCoauthors = new TreeMap<String, Set<Node>>();
|
||||||
|
|
||||||
|
if (authorNodesAndEdges.getNodes() == null || authorNodesAndEdges.getNodes().size() < 1 ) {
|
||||||
|
|
||||||
|
outputFileName = "no-coauthors" + ".csv";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
outputFileName = UtilityFunctions.slugify(authorNodesAndEdges.getEgoNode().getNodeName())
|
||||||
|
+ "-coauthors" + ".csv";
|
||||||
|
|
||||||
|
yearToCoauthors = getCoAuthorsStats(authorNodesAndEdges);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
PrintWriter responseWriter = response.getWriter();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||||
|
* object of the servlet.
|
||||||
|
* */
|
||||||
|
generateCsvFileBuffer(yearToCoauthors,
|
||||||
|
responseWriter);
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateCsvFileBuffer(Map<String, Set<Node>> yearToCoauthors, PrintWriter printWriter) {
|
||||||
|
|
||||||
|
printWriter.append("\"Year\", \"Number of Co-Authors\", \"Co-Author(s)\"\n");
|
||||||
|
|
||||||
|
for (Entry<String, Set<Node>> currentEntry : yearToCoauthors.entrySet()) {
|
||||||
|
|
||||||
|
printWriter.append("\"" + currentEntry.getKey() + "\","
|
||||||
|
+ "\"" + currentEntry.getValue().size() + "\","
|
||||||
|
+ "\"" + getCoauthorsString(currentEntry.getValue()) + "\"\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
printWriter.flush();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCoauthorsString(Set<Node> coAuthors) {
|
||||||
|
|
||||||
|
StringBuilder coAuthorsMerged = new StringBuilder();
|
||||||
|
|
||||||
|
for (Node currCoAuthor : coAuthors) {
|
||||||
|
coAuthorsMerged.append(currCoAuthor.getNodeName() + "; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return coAuthorsMerged.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Set<Node>> getCoAuthorsStats(VisVOContainer authorNodesAndEdges) {
|
||||||
|
|
||||||
|
Map<String, Set<Node>> yearToCoAuthors = new TreeMap<String, Set<Node>>();
|
||||||
|
|
||||||
|
Node egoNode = authorNodesAndEdges.getEgoNode();
|
||||||
|
|
||||||
|
for (Node currNode : authorNodesAndEdges.getNodes()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have already printed the Ego Node info.
|
||||||
|
* */
|
||||||
|
if (currNode != egoNode) {
|
||||||
|
|
||||||
|
for (String year : currNode.getYearToPublicationCount().keySet()) {
|
||||||
|
|
||||||
|
Set<Node> coAuthorNodes;
|
||||||
|
|
||||||
|
if (yearToCoAuthors.containsKey(year)) {
|
||||||
|
|
||||||
|
coAuthorNodes = yearToCoAuthors.get(year);
|
||||||
|
coAuthorNodes.add(currNode);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
coAuthorNodes = new HashSet<Node>();
|
||||||
|
coAuthorNodes.add(currNode);
|
||||||
|
yearToCoAuthors.put(year, coAuthorNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return yearToCoAuthors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryStandaloneResponse(String egoURIParam,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
VitroRequest vreq) {
|
||||||
|
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
// request.setAttribute("visContentCode", visContentCode);
|
||||||
|
// request.setAttribute("visContextCode", visContextCode);
|
||||||
|
|
||||||
|
request.setAttribute("egoURIParam", egoURIParam);
|
||||||
|
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/co_authorship.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
// request.setAttribute("title", "Individual Publication Count Visualization");
|
||||||
|
// request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Portal portal = vitroRequest.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,364 @@
|
||||||
|
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 java.util.TreeMap;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very dumb name of the class. change it.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QueryHandler {
|
||||||
|
|
||||||
|
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||||
|
|
||||||
|
private String collegeURIParam, resultFormatParam, rdfResultFormatParam;
|
||||||
|
private Map<String, VivoCollegeOrSchool> collegeURLToVO = new HashMap<String, VivoCollegeOrSchool>();
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public QueryHandler(String collegeURIParam,
|
||||||
|
String resultFormatParam, String rdfResultFormatParam,
|
||||||
|
DataSource dataSource, Log log) {
|
||||||
|
|
||||||
|
this.collegeURIParam = collegeURIParam;
|
||||||
|
this.resultFormatParam = resultFormatParam;
|
||||||
|
this.rdfResultFormatParam = rdfResultFormatParam;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* System.out.println(collegeURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println(departmentURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println(employeeURLToVO);
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
*/
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
return biboDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet executeQuery(String queryText,
|
||||||
|
String resultFormatParam,
|
||||||
|
String rdfResultFormatParam,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
//remocve this if loop after knowing what is describe & construct sparql stuff.
|
||||||
|
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 rdf:type bibo: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> getVisualizationJavaValueObjects()
|
||||||
|
throws MalformedQueryParametersException {
|
||||||
|
|
||||||
|
if (this.collegeURIParam == null || "".equals(collegeURIParam)) {
|
||||||
|
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To test for the validity of the URI submitted.
|
||||||
|
* */
|
||||||
|
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||||
|
IRI iri = iRIFactory.create(this.collegeURIParam);
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet resultSet = executeQuery(generateCollegeEmployeeSparqlQuery(this.collegeURIParam),
|
||||||
|
this.resultFormatParam,
|
||||||
|
this.rdfResultFormatParam,
|
||||||
|
this.dataSource);
|
||||||
|
|
||||||
|
return createJavaValueObjects(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getYearToPublicationCount(
|
||||||
|
Set<BiboDocument> authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
for (BiboDocument curr : authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increment the count because there is an entry already available for
|
||||||
|
* that particular year.
|
||||||
|
* */
|
||||||
|
String publicationYear;
|
||||||
|
if (curr.getPublicationYear() != null
|
||||||
|
&& curr.getPublicationYear().length() != 0
|
||||||
|
&& curr.getPublicationYear().trim().length() != 0) {
|
||||||
|
publicationYear = curr.getPublicationYear();
|
||||||
|
} else {
|
||||||
|
publicationYear = curr.getParsedPublicationYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yearToPublicationCount.containsKey(publicationYear)) {
|
||||||
|
yearToPublicationCount.put(publicationYear,
|
||||||
|
yearToPublicationCount
|
||||||
|
.get(publicationYear) + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
yearToPublicationCount.put(publicationYear, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("****************************\n" + yearToPublicationCount);
|
||||||
|
return yearToPublicationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,457 @@
|
||||||
|
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.RequestDispatcher;
|
||||||
|
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.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.PDFDocument;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.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.UtilityFunctions;
|
||||||
|
|
||||||
|
public class VisualizationRequestHandler {
|
||||||
|
|
||||||
|
private VitroRequest vitroRequest;
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private HttpServletResponse response;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public VisualizationRequestHandler(VitroRequest vitroRequest,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Log log) {
|
||||||
|
|
||||||
|
this.vitroRequest = vitroRequest;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateVisualization(DataSource dataSource) {
|
||||||
|
|
||||||
|
String resultFormatParam = "RS_TEXT";
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
String collegeURIParam = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
|
||||||
|
|
||||||
|
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visContainer = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE);
|
||||||
|
|
||||||
|
QueryHandler queryManager =
|
||||||
|
new QueryHandler(collegeURIParam,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Set<VivoEmployee> employees = queryManager.getVisualizationJavaValueObjects();
|
||||||
|
|
||||||
|
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 =
|
||||||
|
queryManager.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_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
prepareVisualizationQueryDataResponse(
|
||||||
|
departmentToPublicationsOverTime,
|
||||||
|
queryManager.getCollegeURLToVO());
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*
|
||||||
|
VisualizationCodeGenerator visualizationCodeGenerator =
|
||||||
|
new VisualizationCodeGenerator(yearToPublicationCount, log);
|
||||||
|
|
||||||
|
String visContentCode = visualizationCodeGenerator
|
||||||
|
.getMainVisualizationCode(authorDocuments,
|
||||||
|
publishedYears,
|
||||||
|
visMode,
|
||||||
|
visContainer);
|
||||||
|
|
||||||
|
String visContextCode = visualizationCodeGenerator
|
||||||
|
.getVisualizationContextCode(vitroRequest.getRequestURI(),
|
||||||
|
collegeURIParam,
|
||||||
|
visMode);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the response of this method is just to redirect to
|
||||||
|
* a page with visualization on it.
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*
|
||||||
|
RequestDispatcher requestDispatcher = null;
|
||||||
|
|
||||||
|
if (DYNAMIC_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
|
||||||
|
prepareVisualizationQueryDynamicResponse(request, response, vitroRequest,
|
||||||
|
visContentCode, visContextCode);
|
||||||
|
requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
prepareVisualizationQueryStandaloneResponse(request, response, vitroRequest,
|
||||||
|
visContentCode, visContextCode);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} 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;
|
||||||
|
|
||||||
|
// System.out.println("inside get updated dept pub obr time");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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>();
|
||||||
|
|
||||||
|
// System.out.println("new dept yr pub cnt");
|
||||||
|
|
||||||
|
} 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 prepareVisualizationQueryPDFResponse(Individual college,
|
||||||
|
List<BiboDocument> authorDocuments,
|
||||||
|
Map<String, Integer> yearToPublicationCount) {
|
||||||
|
|
||||||
|
String authorName = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To protect against cases where there are no author documents associated with the
|
||||||
|
* individual.
|
||||||
|
* */
|
||||||
|
if (authorDocuments.size() > 0) {
|
||||||
|
authorName = 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 prepareVisualizationQueryDataResponse(
|
||||||
|
Map<VivoDepartmentOrDivision, Map<String, Integer>> departmentToPublicationsOverTime,
|
||||||
|
Map<String, VivoCollegeOrSchool> collegeURLToVO) {
|
||||||
|
|
||||||
|
String collegeName = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To protect against cases where there are no author documents associated with the
|
||||||
|
* individual.
|
||||||
|
* */
|
||||||
|
// System.out.println(collegeURLToVO);
|
||||||
|
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 prepareVisualizationQueryStandaloneResponse(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 prepareVisualizationQueryDynamicResponse(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");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Portal portal = vitroRequest.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class QueryConstants {
|
||||||
|
|
||||||
|
public static final Map<String, String> PREFIX_TO_NAMESPACE = new HashMap<String, String>() {{
|
||||||
|
|
||||||
|
put("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
|
||||||
|
put("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
|
||||||
|
put("xsd", "http://www.w3.org/2001/XMLSchema#");
|
||||||
|
put("owl", "http://www.w3.org/2002/07/owl#");
|
||||||
|
put("swrl", "http://www.w3.org/2003/11/swrl#");
|
||||||
|
put("swrlb", "http://www.w3.org/2003/11/swrlb#");
|
||||||
|
put("vitro", "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#");
|
||||||
|
put("far", "http://vitro.mannlib.cornell.edu/ns/reporting#");
|
||||||
|
put("ai", "http://vitro.mannlib.cornell.edu/ns/hotel#");
|
||||||
|
put("aktp", "http://www.aktors.org/ontology/portal#");
|
||||||
|
put("akts", "http://www.aktors.org/ontology/support#");
|
||||||
|
put("bibo", "http://purl.org/ontology/bibo/");
|
||||||
|
put("hr", "http://vivo.cornell.edu/ns/hr/0.9/hr.owl#");
|
||||||
|
put("dcterms", "http://purl.org/dc/terms/");
|
||||||
|
put("dcelem", "http://purl.org/dc/elements/1.1/");
|
||||||
|
put("event", "http://purl.org/NET/c4dm/event.owl#");
|
||||||
|
put("foaf", "http://xmlns.com/foaf/0.1/");
|
||||||
|
put("geo", "http://aims.fao.org/aos/geopolitical.owl#");
|
||||||
|
put("mann", "http://vivo.cornell.edu/ns/mannadditions/0.1#");
|
||||||
|
put("pubmed", "http://vitro.mannlib.cornell.edu/ns/pubmed#");
|
||||||
|
put("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
|
||||||
|
put("rdfsyn", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
|
||||||
|
put("skos", "http://www.w3.org/2004/02/skos/core#");
|
||||||
|
put("socsci", "http://vivo.library.cornell.edu/ns/vivo/socsci/0.1#");
|
||||||
|
put("stars", "http://vitro.mannlib.cornell.edu/ns/cornell/stars/classes#");
|
||||||
|
put("temp", "http://vitro.mannlib.cornell.edu/ns/temp#");
|
||||||
|
put("wos", "http://vivo.mannlib.cornell.edu/ns/ThomsonWOS/0.1#");
|
||||||
|
put("core", "http://vivoweb.org/ontology/core#");
|
||||||
|
put("vivo", "http://vivo.library.cornell.edu/ns/0.1#");
|
||||||
|
|
||||||
|
}};
|
||||||
|
|
||||||
|
|
||||||
|
public static String getSparqlPrefixQuery() {
|
||||||
|
|
||||||
|
StringBuilder prefixSection = new StringBuilder();
|
||||||
|
|
||||||
|
for (Map.Entry prefixEntry : PREFIX_TO_NAMESPACE.entrySet()) {
|
||||||
|
prefixSection.append("PREFIX " + prefixEntry.getKey() + ": <" + prefixEntry.getValue() + ">\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return prefixSection.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
|
||||||
|
|
||||||
|
public class QueryFieldLabels {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic Query related field labels
|
||||||
|
* */
|
||||||
|
public static final String PREDICATE = "predicateLit";
|
||||||
|
public static final String OBJECT = "objectLit";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document related field labels
|
||||||
|
* */
|
||||||
|
public static final String DOCUMENT_URL = "documentLit";
|
||||||
|
public static final String DOCUMENT_MONIKER = "documentMonikerLit";
|
||||||
|
public static final String DOCUMENT_LABEL = "documentLabelLit";
|
||||||
|
public static final String DOCUMENT_BLURB = "documentBlurbLit";
|
||||||
|
public static final String DOCUMENT_DESCRIPTION = "documentDescriptionLit";
|
||||||
|
public static final String DOCUMENT_PUBLICATION_YEAR = "publicationYearLit";
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author related field labels
|
||||||
|
* */
|
||||||
|
public static final String AUTHOR_URL = "authPersonLit";
|
||||||
|
public static final String AUTHOR_LABEL = "authorLabelLit";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Co-Author related field labels
|
||||||
|
* */
|
||||||
|
public static final String CO_AUTHOR_URL = "coAuthPersonLit";
|
||||||
|
public static final String CO_AUTHOR_LABEL = "coAuthPersonLabelLit";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* College related field labels
|
||||||
|
* */
|
||||||
|
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
|
||||||
|
* */
|
||||||
|
public static final String ACADEMIC_FACULTY_EMPLOYEE_URL = "academicFacultyEmployeeLit";
|
||||||
|
public static final String ACADEMIC_STAFF_EMPLOYEE_URL = "academicStaffEmployeeLit";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
|
||||||
|
|
||||||
|
public class VOConstants {
|
||||||
|
|
||||||
|
public static final String DEFAULT_PUBLICATION_YEAR = "Unknown";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Employee related constants
|
||||||
|
* */
|
||||||
|
public static enum EmployeeType {
|
||||||
|
ACADEMIC_FACULTY_EMPLOYEE, ACADEMIC_STAFF_EMPLOYEE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.constants;
|
||||||
|
|
||||||
|
public class VisConstants {
|
||||||
|
|
||||||
|
public static final int MAX_NAME_TEXT_LENGTH = 10;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.exceptions;
|
||||||
|
|
||||||
|
public class DocumentFieldNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public DocumentFieldNotFoundException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentFieldNotFoundException(Exception cause) {
|
||||||
|
super(createMessage(cause), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createMessage(Exception cause) {
|
||||||
|
return "Document Field is empty " + cause.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.exceptions;
|
||||||
|
|
||||||
|
public class MalformedQueryParametersException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public MalformedQueryParametersException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MalformedQueryParametersException(Exception cause) {
|
||||||
|
super(createMessage(cause), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String createMessage(Exception cause) {
|
||||||
|
return "Malformed Query Params " + cause.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,423 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.personlevel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
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.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.coauthorship.CoAuthorshipGraphMLWriter;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisVOContainer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.VisualizationCodeGenerator;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Node;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
|
||||||
|
|
||||||
|
public class VisualizationRequestHandler {
|
||||||
|
|
||||||
|
private VitroRequest vitroRequest;
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private HttpServletResponse response;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public VisualizationRequestHandler(VitroRequest vitroRequest,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Log log) {
|
||||||
|
|
||||||
|
this.vitroRequest = vitroRequest;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateVisualization(DataSource dataSource) {
|
||||||
|
|
||||||
|
String resultFormatParam = "RS_TEXT";
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
String egoURIParam = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
|
||||||
|
|
||||||
|
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String coAuthorsListMode = "coauthors";
|
||||||
|
|
||||||
|
String egoPubSparklineVisContainerID = "ego_pub_sparkline";
|
||||||
|
String uniqueCoauthorsSparklineVisContainerID = "unique_coauthors_sparkline";
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.QueryHandler coAuthorshipQueryManager =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.QueryHandler(egoURIParam,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.QueryHandler publicationQueryManager =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.QueryHandler(egoURIParam,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisVOContainer coAuthorshipVO =
|
||||||
|
coAuthorshipQueryManager.getVisualizationJavaValueObjects();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to avoid unneeded computations we have pushed this "if" condition up.
|
||||||
|
* This case arises when the render mode is data. In that case we dont want to generate
|
||||||
|
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
|
||||||
|
* It is ugly!
|
||||||
|
* */
|
||||||
|
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We will be using the same visualization package for providing data for both
|
||||||
|
* list of unique coauthors & network of coauthors (used in the flash vis). We will
|
||||||
|
* use "VIS_MODE_URL_HANDLE" as a modifier to differentiate between these two.
|
||||||
|
* The defualt will be to provide data used to render the coauthorship network vis.
|
||||||
|
* */
|
||||||
|
|
||||||
|
if (coAuthorsListMode.equalsIgnoreCase(visMode)) {
|
||||||
|
/*
|
||||||
|
* When the csv file is required - containing the unique co-authors vs how many times
|
||||||
|
* they have co-authored with the ego.
|
||||||
|
* */
|
||||||
|
prepareVisualizationQueryListCoauthorsDataResponse(coAuthorshipVO);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* When the graphML file is required - based on which coauthorship network visualization
|
||||||
|
* will be rendered.
|
||||||
|
* */
|
||||||
|
prepareVisualizationQueryNetworkDataResponse(coAuthorshipVO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BiboDocument> authorDocuments = publicationQueryManager.getVisualizationJavaValueObjects();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount = publicationQueryManager
|
||||||
|
.getYearToPublicationCount(authorDocuments);
|
||||||
|
|
||||||
|
Map<String, Integer> yearToUniqueCoauthorCount = getUniqueCoauthorsCountPerYear(coAuthorshipVO);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computations required to generate HTML for the sparklines & related context.
|
||||||
|
* */
|
||||||
|
|
||||||
|
SparklineVOContainer publicationSparklineVO = new SparklineVOContainer();
|
||||||
|
SparklineVOContainer uniqueCoauthorsSparklineVO = new SparklineVOContainer();
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.VisualizationCodeGenerator personPubCountVisCodeGenerator =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.personpubcount.VisualizationCodeGenerator(
|
||||||
|
vitroRequest.getRequestURI(),
|
||||||
|
egoURIParam,
|
||||||
|
VisualizationCodeGenerator.FULL_SPARKLINE_MODE_URL_HANDLE,
|
||||||
|
egoPubSparklineVisContainerID,
|
||||||
|
authorDocuments,
|
||||||
|
yearToPublicationCount,
|
||||||
|
publicationSparklineVO,
|
||||||
|
log);
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisualizationCodeGenerator uniqueCoauthorsVisCodeGenerator =
|
||||||
|
new edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisualizationCodeGenerator(
|
||||||
|
vitroRequest.getRequestURI(),
|
||||||
|
egoURIParam,
|
||||||
|
VisualizationCodeGenerator.FULL_SPARKLINE_MODE_URL_HANDLE,
|
||||||
|
uniqueCoauthorsSparklineVisContainerID,
|
||||||
|
yearToUniqueCoauthorCount,
|
||||||
|
uniqueCoauthorsSparklineVO,
|
||||||
|
log);
|
||||||
|
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = null;
|
||||||
|
|
||||||
|
prepareVisualizationQueryStandaloneResponse(egoURIParam,
|
||||||
|
publicationSparklineVO,
|
||||||
|
uniqueCoauthorsSparklineVO,
|
||||||
|
coAuthorshipVO,
|
||||||
|
egoPubSparklineVisContainerID,
|
||||||
|
uniqueCoauthorsSparklineVisContainerID,
|
||||||
|
request,
|
||||||
|
response,
|
||||||
|
vitroRequest);
|
||||||
|
|
||||||
|
// requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||||
|
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 {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} catch (ServletException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> getUniqueCoauthorsCountPerYear(
|
||||||
|
edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisVOContainer coAuthorshipVO) {
|
||||||
|
Map<String, Integer> yearToUniqueCoauthorCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
Map<String, Set<Node>> yearToUniqueCoauthors = getUniqueCoAuthorsPerYear(coAuthorshipVO);
|
||||||
|
|
||||||
|
for (Entry<String, Set<Node>> currentEntry : yearToUniqueCoauthors.entrySet()) {
|
||||||
|
|
||||||
|
yearToUniqueCoauthorCount.put(currentEntry.getKey(), currentEntry.getValue().size());
|
||||||
|
|
||||||
|
}
|
||||||
|
return yearToUniqueCoauthorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Set<Node>> getUniqueCoAuthorsPerYear(edu.cornell.mannlib.vitro.webapp.visualization.coauthorship.VisVOContainer authorNodesAndEdges) {
|
||||||
|
|
||||||
|
Map<String, Set<Node>> yearToCoAuthors = new TreeMap<String, Set<Node>>();
|
||||||
|
|
||||||
|
Node egoNode = authorNodesAndEdges.getEgoNode();
|
||||||
|
|
||||||
|
for (Node currNode : authorNodesAndEdges.getNodes()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have already printed the Ego Node info.
|
||||||
|
* */
|
||||||
|
if (currNode != egoNode) {
|
||||||
|
|
||||||
|
for (String year : currNode.getYearToPublicationCount().keySet()) {
|
||||||
|
|
||||||
|
Set<Node> coAuthorNodes;
|
||||||
|
|
||||||
|
if (yearToCoAuthors.containsKey(year)) {
|
||||||
|
|
||||||
|
coAuthorNodes = yearToCoAuthors.get(year);
|
||||||
|
coAuthorNodes.add(currNode);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
coAuthorNodes = new HashSet<Node>();
|
||||||
|
coAuthorNodes.add(currNode);
|
||||||
|
yearToCoAuthors.put(year, coAuthorNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return yearToCoAuthors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryNetworkDataResponse(VisVOContainer coAuthorsipVO) {
|
||||||
|
|
||||||
|
String outputFileName = "";
|
||||||
|
|
||||||
|
if (coAuthorsipVO.getNodes() == null || coAuthorsipVO.getNodes().size() < 1) {
|
||||||
|
|
||||||
|
outputFileName = "no-coauthorship-net" + ".csv";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
outputFileName = UtilityFunctions.slugify(coAuthorsipVO.getEgoNode().getNodeName())
|
||||||
|
+ "-coauthor-net" + ".graphml";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
PrintWriter responseWriter = response.getWriter();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||||
|
* object of the servlet.
|
||||||
|
* */
|
||||||
|
CoAuthorshipGraphMLWriter coAuthorShipGraphMLWriter = new CoAuthorshipGraphMLWriter(coAuthorsipVO);
|
||||||
|
|
||||||
|
responseWriter.append(coAuthorShipGraphMLWriter.getCoAuthorshipGraphMLContent());
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryListCoauthorsDataResponse(VisVOContainer coAuthorsipVO) {
|
||||||
|
|
||||||
|
String outputFileName = "";
|
||||||
|
Map<String, Integer> coAuthorsToCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
if (coAuthorsipVO.getNodes() == null || coAuthorsipVO.getNodes().size() < 1 ) {
|
||||||
|
|
||||||
|
outputFileName = "no-coauthors-list" + ".csv";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
outputFileName = UtilityFunctions.slugify(coAuthorsipVO.getEgoNode().getNodeName())
|
||||||
|
+ "-coauthors-list" + ".csv";
|
||||||
|
|
||||||
|
coAuthorsToCount = getCoAuthorsList(coAuthorsipVO);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
PrintWriter responseWriter = response.getWriter();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||||
|
* object of the servlet.
|
||||||
|
* */
|
||||||
|
generateCsvFileBuffer(coAuthorsToCount,
|
||||||
|
responseWriter);
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Integer> getCoAuthorsList(VisVOContainer coAuthorsipVO) {
|
||||||
|
|
||||||
|
Map<String, Integer> coAuthorsToCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
for (Node currNode : coAuthorsipVO.getNodes()) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have already printed the Ego Node info.
|
||||||
|
* */
|
||||||
|
if (currNode != coAuthorsipVO.getEgoNode()) {
|
||||||
|
|
||||||
|
coAuthorsToCount.put(currNode.getNodeName(), currNode.getNumOfAuthoredWorks());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return coAuthorsToCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateCsvFileBuffer(Map<String, Integer> coAuthorsToCount, PrintWriter printWriter) {
|
||||||
|
|
||||||
|
printWriter.append("\"Co-Author\", \"Count\"\n");
|
||||||
|
|
||||||
|
for (Entry<String, Integer> currentEntry : coAuthorsToCount.entrySet()) {
|
||||||
|
|
||||||
|
printWriter.append("\"" + currentEntry.getKey() + "\","
|
||||||
|
+ "\"" + currentEntry.getValue() + "\"\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
printWriter.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryStandaloneResponse(
|
||||||
|
String egoURIParam,
|
||||||
|
SparklineVOContainer egoPubSparklineVO,
|
||||||
|
SparklineVOContainer uniqueCoauthorsSparklineVO,
|
||||||
|
VisVOContainer coAuthorshipVO,
|
||||||
|
String egoPubSparklineVisContainer,
|
||||||
|
String uniqueCoauthorsSparklineVisContainer,
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
VitroRequest vreq) {
|
||||||
|
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("egoURIParam", egoURIParam);
|
||||||
|
|
||||||
|
if (coAuthorshipVO.getNodes() != null) {
|
||||||
|
request.setAttribute("numOfAuthors", coAuthorshipVO.getNodes().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coAuthorshipVO.getEdges() != null) {
|
||||||
|
request.setAttribute("numOfCoAuthorShips", coAuthorshipVO.getEdges().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
request.setAttribute("egoPubSparklineVO", egoPubSparklineVO);
|
||||||
|
request.setAttribute("uniqueCoauthorsSparklineVO", uniqueCoauthorsSparklineVO);
|
||||||
|
|
||||||
|
request.setAttribute("egoPubSparklineContainerID", egoPubSparklineVisContainer);
|
||||||
|
request.setAttribute("uniqueCoauthorsSparklineVisContainerID", uniqueCoauthorsSparklineVisContainer);
|
||||||
|
|
||||||
|
request.setAttribute("title", "Person Level Visualization");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("scripts", "/templates/visualization/person_level_inject_head.jsp");
|
||||||
|
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/person_level.jsp");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Portal portal = vitroRequest.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.personpubcount;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
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.Individual;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very dumb name of the class. change it.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QueryHandler {
|
||||||
|
|
||||||
|
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||||
|
|
||||||
|
private String queryParam, resultFormatParam, rdfResultFormatParam;
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
private Individual author;
|
||||||
|
|
||||||
|
public Individual getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
private static final String SPARQL_QUERY_COMMON_SELECT_CLAUSE = "" +
|
||||||
|
"SELECT (str(?authorLabel) as ?authorLabelLit) " +
|
||||||
|
" (str(?document) as ?documentLit) " +
|
||||||
|
" (str(?documentMoniker) as ?documentMonikerLit) " +
|
||||||
|
" (str(?documentLabel) as ?documentLabelLit) " +
|
||||||
|
" (str(?documentBlurb) as ?documentBlurbLit) " +
|
||||||
|
" (str(?publicationYear) as ?publicationYearLit) " +
|
||||||
|
" (str(?documentDescription) as ?documentDescriptionLit) ";
|
||||||
|
|
||||||
|
private static final String SPARQL_QUERY_COMMON_WHERE_CLAUSE = "" +
|
||||||
|
"?document rdf:type bibo:Document ." +
|
||||||
|
"?document rdfs:label ?documentLabel ." +
|
||||||
|
"OPTIONAL { ?document vivo:publicationYear ?publicationYear } ." +
|
||||||
|
"OPTIONAL { ?document vitro:moniker ?documentMoniker } ." +
|
||||||
|
"OPTIONAL { ?document vitro:blurb ?documentBlurb } ." +
|
||||||
|
"OPTIONAL { ?document vitro:description ?documentDescription }";
|
||||||
|
|
||||||
|
public QueryHandler(String queryParam,
|
||||||
|
String resultFormatParam, String rdfResultFormatParam,
|
||||||
|
DataSource dataSource, Log log) {
|
||||||
|
|
||||||
|
this.queryParam = queryParam;
|
||||||
|
this.resultFormatParam = resultFormatParam;
|
||||||
|
this.rdfResultFormatParam = rdfResultFormatParam;
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BiboDocument> createJavaValueObjects(ResultSet resultSet) {
|
||||||
|
List<BiboDocument> authorDocuments = new ArrayList<BiboDocument>();
|
||||||
|
|
||||||
|
while (resultSet.hasNext()) {
|
||||||
|
QuerySolution solution = resultSet.nextSolution();
|
||||||
|
|
||||||
|
BiboDocument biboDocument = new BiboDocument(
|
||||||
|
solution.get(QueryFieldLabels.DOCUMENT_URL)
|
||||||
|
.toString());
|
||||||
|
|
||||||
|
RDFNode documentLabelNode = solution.get(QueryFieldLabels.DOCUMENT_LABEL);
|
||||||
|
if (documentLabelNode != null) {
|
||||||
|
biboDocument.setDocumentLabel(documentLabelNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RDFNode documentBlurbNode = solution.get(QueryFieldLabels.DOCUMENT_BLURB);
|
||||||
|
if (documentBlurbNode != null) {
|
||||||
|
biboDocument.setDocumentBlurb(documentBlurbNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
RDFNode documentmonikerNode = solution.get(QueryFieldLabels.DOCUMENT_MONIKER);
|
||||||
|
if (documentmonikerNode != null) {
|
||||||
|
biboDocument.setDocumentMoniker(documentmonikerNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
RDFNode documentDescriptionNode = solution.get(QueryFieldLabels.DOCUMENT_DESCRIPTION);
|
||||||
|
if (documentDescriptionNode != null) {
|
||||||
|
biboDocument.setDocumentDescription(documentDescriptionNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
RDFNode publicationYearNode = solution.get(QueryFieldLabels.DOCUMENT_PUBLICATION_YEAR);
|
||||||
|
if (publicationYearNode != null) {
|
||||||
|
biboDocument.setPublicationYear(publicationYearNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we are getting publication count for just one author at a time we need
|
||||||
|
* to create only one "Individual" instance. We test against the null for "author" to
|
||||||
|
* make sure that it has not already been instantiated.
|
||||||
|
* */
|
||||||
|
RDFNode authorURLNode = solution.get(QueryFieldLabels.AUTHOR_URL);
|
||||||
|
if (authorURLNode != null && author == null) {
|
||||||
|
author = new Individual(authorURLNode.toString());
|
||||||
|
RDFNode authorLabelNode = solution.get(QueryFieldLabels.AUTHOR_LABEL);
|
||||||
|
if (authorLabelNode != null) {
|
||||||
|
author.setIndividualLabel(authorLabelNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
authorDocuments.add(biboDocument);
|
||||||
|
}
|
||||||
|
return authorDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet executeQuery(String queryURI,
|
||||||
|
String resultFormatParam, String rdfResultFormatParam, DataSource dataSource) {
|
||||||
|
|
||||||
|
QueryExecution queryExecution = null;
|
||||||
|
try{
|
||||||
|
Query query = QueryFactory.create(generateSparqlQuery(queryURI), SYNTAX);
|
||||||
|
|
||||||
|
// QuerySolutionMap qs = new QuerySolutionMap();
|
||||||
|
// qs.add("authPerson", queryParam); // bind resource to s
|
||||||
|
|
||||||
|
queryExecution = QueryExecutionFactory.create(query, dataSource);
|
||||||
|
|
||||||
|
|
||||||
|
//remocve this if loop after knowing what is describe & construct sparql stuff.
|
||||||
|
if( query.isSelectType() ){
|
||||||
|
return queryExecution.execSelect();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if(queryExecution != null) {
|
||||||
|
queryExecution.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateSparqlQuery(String queryURI) {
|
||||||
|
// Resource uri1 = ResourceFactory.createResource(queryURI);
|
||||||
|
|
||||||
|
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||||
|
+ SPARQL_QUERY_COMMON_SELECT_CLAUSE
|
||||||
|
+ "(str(<" + queryURI + ">) as ?authPersonLit) "
|
||||||
|
+ "WHERE { "
|
||||||
|
+ "<" + queryURI + "> rdf:type foaf:Person ; vivo:authorOf ?document ; rdfs:label ?authorLabel. "
|
||||||
|
+ SPARQL_QUERY_COMMON_WHERE_CLAUSE
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
log.debug("SPARQL query for person pub count -> \n" + sparqlQuery);
|
||||||
|
|
||||||
|
return sparqlQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BiboDocument> getVisualizationJavaValueObjects()
|
||||||
|
throws MalformedQueryParametersException {
|
||||||
|
|
||||||
|
if(this.queryParam == null || "".equals(queryParam)) {
|
||||||
|
throw new MalformedQueryParametersException("URL parameter is either null or empty.");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To test for the validity of the URI submitted.
|
||||||
|
* */
|
||||||
|
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||||
|
IRI iri = iRIFactory.create(this.queryParam);
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ResultSet resultSet = executeQuery(this.queryParam,
|
||||||
|
this.resultFormatParam,
|
||||||
|
this.rdfResultFormatParam,
|
||||||
|
this.dataSource);
|
||||||
|
|
||||||
|
return createJavaValueObjects(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getYearToPublicationCount(
|
||||||
|
List<BiboDocument> authorDocuments) {
|
||||||
|
|
||||||
|
//List<Integer> publishedYears = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
for (BiboDocument curr : authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increment the count because there is an entry already available for
|
||||||
|
* that particular year.
|
||||||
|
* */
|
||||||
|
String publicationYear;
|
||||||
|
if (curr.getPublicationYear() != null
|
||||||
|
&& curr.getPublicationYear().length() != 0
|
||||||
|
&& curr.getPublicationYear().trim().length() != 0) {
|
||||||
|
publicationYear = curr.getPublicationYear();
|
||||||
|
} else {
|
||||||
|
publicationYear = curr.getParsedPublicationYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yearToPublicationCount.containsKey(publicationYear)) {
|
||||||
|
yearToPublicationCount.put(publicationYear,
|
||||||
|
yearToPublicationCount
|
||||||
|
.get(publicationYear) + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
yearToPublicationCount.put(publicationYear, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!parsedPublicationYear.equalsIgnoreCase(BiboDocument.DEFAULT_PUBLICATION_YEAR)) {
|
||||||
|
// publishedYears.add(Integer.parseInt(parsedPublicationYear));
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return yearToPublicationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,660 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.personpubcount;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
|
||||||
|
|
||||||
|
|
||||||
|
public class VisualizationCodeGenerator {
|
||||||
|
|
||||||
|
private final static Map<String, String> visDivNames = new HashMap<String, String>() {{
|
||||||
|
|
||||||
|
put("SHORT_SPARK", "pub_count_short_sparkline_vis");
|
||||||
|
put("FULL_SPARK", "pub_count_full_sparkline_vis");
|
||||||
|
|
||||||
|
}};
|
||||||
|
|
||||||
|
private static final String visualizationStyleClass = "sparkline_style";
|
||||||
|
|
||||||
|
private static final String defaultVisContainerDivID = "pub_count_vis_container";
|
||||||
|
|
||||||
|
public static final String SHORT_SPARKLINE_MODE_URL_HANDLE = "short";
|
||||||
|
|
||||||
|
public static final String FULL_SPARKLINE_MODE_URL_HANDLE = "full";
|
||||||
|
|
||||||
|
private Map<String, Integer> yearToPublicationCount;
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
private SparklineVOContainer valueObjectContainer;
|
||||||
|
|
||||||
|
private String contextPath;
|
||||||
|
|
||||||
|
private String individualURIParam;
|
||||||
|
|
||||||
|
public VisualizationCodeGenerator(String contextPath,
|
||||||
|
String individualURIParam,
|
||||||
|
String visMode,
|
||||||
|
String visContainer,
|
||||||
|
List<BiboDocument> authorDocuments,
|
||||||
|
Map<String, Integer> yearToPublicationCount,
|
||||||
|
SparklineVOContainer valueObjectContainer,
|
||||||
|
Log log) {
|
||||||
|
|
||||||
|
this.contextPath = contextPath;
|
||||||
|
this.individualURIParam = individualURIParam;
|
||||||
|
|
||||||
|
this.yearToPublicationCount = yearToPublicationCount;
|
||||||
|
this.valueObjectContainer = valueObjectContainer;
|
||||||
|
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
|
||||||
|
generateVisualizationCode(visMode,
|
||||||
|
visContainer,
|
||||||
|
authorDocuments);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateVisualizationCode(String visMode,
|
||||||
|
String visContainer,
|
||||||
|
List<BiboDocument> authorDocuments) {
|
||||||
|
|
||||||
|
valueObjectContainer.setSparklineContent(getMainVisualizationCode(authorDocuments,
|
||||||
|
visMode,
|
||||||
|
visContainer));
|
||||||
|
|
||||||
|
|
||||||
|
valueObjectContainer.setSparklineContext(getVisualizationContextCode(visMode));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMainVisualizationCode(List<BiboDocument> authorDocuments,
|
||||||
|
String visMode,
|
||||||
|
String providedVisContainerID) {
|
||||||
|
|
||||||
|
int numOfYearsToBeRendered = 0;
|
||||||
|
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
int shortSparkMinYear = currentYear - 10 + 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is required because when deciding the range of years over which the vis
|
||||||
|
* was rendered we dont want to be influenced by the "DEFAULT_PUBLICATION_YEAR".
|
||||||
|
* */
|
||||||
|
Set<String> publishedYears = new HashSet(yearToPublicationCount.keySet());
|
||||||
|
publishedYears.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are setting the default value of minPublishedYear to be 10 years before
|
||||||
|
* the current year (which is suitably represented by the shortSparkMinYear),
|
||||||
|
* this in case we run into invalid set of published years.
|
||||||
|
* */
|
||||||
|
int minPublishedYear = shortSparkMinYear;
|
||||||
|
|
||||||
|
String visContainerID = null;
|
||||||
|
|
||||||
|
StringBuilder visualizationCode = new StringBuilder();
|
||||||
|
|
||||||
|
// System.out.println(yearToPublicationCount);
|
||||||
|
if (yearToPublicationCount.size() > 0) {
|
||||||
|
try {
|
||||||
|
minPublishedYear = Integer.parseInt(Collections.min(publishedYears));
|
||||||
|
System.out.println("min pub year - " + minPublishedYear);
|
||||||
|
} catch (NoSuchElementException e1) {
|
||||||
|
log.debug("vis: " + e1.getMessage() + " error occurred for " + yearToPublicationCount.toString());
|
||||||
|
} catch (NumberFormatException e2) {
|
||||||
|
log.debug("vis: " + e2.getMessage() + " error occurred for " + yearToPublicationCount.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int minPubYearConsidered = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There might be a case that the author has made his first publication within the
|
||||||
|
* last 10 years but we want to make sure that the sparkline is representative of
|
||||||
|
* at least the last 10 years, so we will set the minPubYearConsidered to
|
||||||
|
* "currentYear - 10" which is also given by "shortSparkMinYear".
|
||||||
|
* */
|
||||||
|
if (minPublishedYear > shortSparkMinYear) {
|
||||||
|
minPubYearConsidered = shortSparkMinYear;
|
||||||
|
} else {
|
||||||
|
minPubYearConsidered = minPublishedYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
numOfYearsToBeRendered = currentYear - minPubYearConsidered + 1;
|
||||||
|
|
||||||
|
visualizationCode.append("<style type='text/css'>" +
|
||||||
|
"." + visualizationStyleClass + " table{" +
|
||||||
|
" margin: 0;" +
|
||||||
|
" padding: 0;" +
|
||||||
|
" width: auto;" +
|
||||||
|
" border-collapse: collapse;" +
|
||||||
|
" border-spacing: 0;" +
|
||||||
|
" vertical-align: inherit;" +
|
||||||
|
"}" +
|
||||||
|
"table.sparkline_wrapper_table td, th {" +
|
||||||
|
" vertical-align: bottom;" +
|
||||||
|
"}" +
|
||||||
|
".vis_link a{" +
|
||||||
|
" padding-top: 5px;" +
|
||||||
|
"}" +
|
||||||
|
"td.sparkline_number { text-align:right; padding-right:5px; }" +
|
||||||
|
"td.sparkline_text {text-align:left;}" +
|
||||||
|
/*"#sparkline_data_table {" +
|
||||||
|
"width: auto;" +
|
||||||
|
"}" +
|
||||||
|
"#sparkline_data_table tfoot {" +
|
||||||
|
"color: red;" +
|
||||||
|
"font-size:0.9em;" +
|
||||||
|
"}" +
|
||||||
|
".sparkline_text {" +
|
||||||
|
"margin-left:72px;" +
|
||||||
|
"position:absolute;" +
|
||||||
|
"}" +
|
||||||
|
".sparkline_range {" +
|
||||||
|
"color:#7BA69E;" +
|
||||||
|
"font-size:0.9em;" +
|
||||||
|
"font-style:italic;" +
|
||||||
|
"}" +*/
|
||||||
|
"</style>\n");
|
||||||
|
|
||||||
|
// .sparkline {display:inline; margin:0; padding:0; width:600px }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// td.sparkline-img {margin:0; padding:0; }
|
||||||
|
|
||||||
|
|
||||||
|
visualizationCode.append("<script type=\"text/javascript\">\n" +
|
||||||
|
"function drawPubCountVisualization(providedSparklineImgTD) {\n" +
|
||||||
|
"var data = new google.visualization.DataTable();\n" +
|
||||||
|
"data.addColumn('string', 'Year');\n" +
|
||||||
|
"data.addColumn('number', 'Publications');\n" +
|
||||||
|
"data.addRows(" + numOfYearsToBeRendered + ");\n");
|
||||||
|
|
||||||
|
int publicationCounter = 0;
|
||||||
|
int totalPublications = 0;
|
||||||
|
int renderedFullSparks = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (int publicationYear = minPubYearConsidered; publicationYear <= currentYear; publicationYear++) {
|
||||||
|
|
||||||
|
String stringPublishedYear = String.valueOf(publicationYear);
|
||||||
|
Integer currentPublications = yearToPublicationCount.get(stringPublishedYear);
|
||||||
|
|
||||||
|
if (currentPublications == null) {
|
||||||
|
currentPublications = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
visualizationCode.append("data.setValue("
|
||||||
|
+ publicationCounter
|
||||||
|
+ ", 0, '"
|
||||||
|
+ stringPublishedYear
|
||||||
|
+ "');\n");
|
||||||
|
|
||||||
|
visualizationCode.append("data.setValue("
|
||||||
|
+ publicationCounter
|
||||||
|
+ ", 1, "
|
||||||
|
+ currentPublications
|
||||||
|
+ ");\n");
|
||||||
|
|
||||||
|
totalPublications += currentPublications;
|
||||||
|
publicationCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sparks that will be rendered in full mode will always be the one's which has any year
|
||||||
|
* associated with it. Hence.
|
||||||
|
* */
|
||||||
|
renderedFullSparks = totalPublications;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Total publications will also consider publications that have no year associated with
|
||||||
|
* it. Hence.
|
||||||
|
* */
|
||||||
|
if (yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR) != null) {
|
||||||
|
totalPublications += yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
String sparklineDisplayOptions = "{width: 63, height: 21, showAxisLines: false, " +
|
||||||
|
"showValueLabels: false, labelPosition: 'none'}";
|
||||||
|
|
||||||
|
if (providedVisContainerID != null) {
|
||||||
|
visContainerID = providedVisContainerID;
|
||||||
|
} else {
|
||||||
|
visContainerID = defaultVisContainerDivID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By default these represents the range of the rendered sparks. Only in case of
|
||||||
|
* "short" sparkline mode we will set the Earliest RenderedPublication year to
|
||||||
|
* "currentYear - 10".
|
||||||
|
* */
|
||||||
|
valueObjectContainer.setEarliestRenderedPublicationYear(minPublishedYear);
|
||||||
|
valueObjectContainer.setLatestRenderedPublicationYear(currentYear);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Full Sparkline will be rendered by default. Only if the url has specific mention of
|
||||||
|
* SHORT_SPARKLINE_MODE_URL_HANDLE then we render the short sparkline and not otherwise.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since building StringBuilder objects (which is being used to store the vis code) is
|
||||||
|
* essentially a side-effecting process, we have both the activators method as side-effecting.
|
||||||
|
* They both side-effect "visualizationCode"
|
||||||
|
* */
|
||||||
|
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
|
||||||
|
|
||||||
|
valueObjectContainer.setEarliestRenderedPublicationYear(shortSparkMinYear);
|
||||||
|
generateShortSparklineVisualizationContent(currentYear,
|
||||||
|
shortSparkMinYear,
|
||||||
|
visContainerID,
|
||||||
|
visualizationCode,
|
||||||
|
totalPublications,
|
||||||
|
sparklineDisplayOptions);
|
||||||
|
} else {
|
||||||
|
generateFullSparklineVisualizationContent(currentYear,
|
||||||
|
minPubYearConsidered,
|
||||||
|
visContainerID,
|
||||||
|
visualizationCode,
|
||||||
|
totalPublications,
|
||||||
|
renderedFullSparks,
|
||||||
|
sparklineDisplayOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
log.debug(visualizationCode);
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
|
||||||
|
return visualizationCode.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateShortSparklineVisualizationContent(int currentYear,
|
||||||
|
int shortSparkMinYear, String visContainerID,
|
||||||
|
StringBuilder visualizationCode, int totalPublications,
|
||||||
|
String sparklineDisplayOptions) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a view of the data containing only the column pertaining to publication count.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var shortSparklineView = new google.visualization.DataView(data);\n" +
|
||||||
|
"shortSparklineView.setColumns([1]);\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the short view we only want the last 10 year's view of publication count,
|
||||||
|
* hence we filter the data we actually want to use for render.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("shortSparklineView.setRows(" +
|
||||||
|
"data.getFilteredRows([{column: 0, " +
|
||||||
|
"minValue: '" + shortSparkMinYear + "', " +
|
||||||
|
"maxValue: '" + currentYear+ "'}])" +
|
||||||
|
");\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the vis object and draw it in the div pertaining to short-sparkline.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var short_spark = new google.visualization.ImageSparkLine(" +
|
||||||
|
// "document.getElementById('" + visDivNames.get("SHORT_SPARK") + "')" +
|
||||||
|
"providedSparklineImgTD[0]" +
|
||||||
|
");\n" +
|
||||||
|
"short_spark.draw(shortSparklineView, " + sparklineDisplayOptions + ");\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We want to display how many publication counts were considered, so this is used
|
||||||
|
* to calculate this.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("var shortSparkRows = shortSparklineView.getViewRows();\n" +
|
||||||
|
"var renderedShortSparks = 0;\n" +
|
||||||
|
"$.each(shortSparkRows, function(index, value) {" +
|
||||||
|
"renderedShortSparks += data.getValue(value, 1);" +
|
||||||
|
"});\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the text introducing the vis.
|
||||||
|
* */
|
||||||
|
visualizationCode.append("$('#" + visDivNames.get("SHORT_SPARK") + " td.sparkline_number').text(renderedShortSparks);");
|
||||||
|
visualizationCode.append("var shortSparksText = ''" +
|
||||||
|
"+ ' Papers with year from '" +
|
||||||
|
"+ ' " + totalPublications + " '" +
|
||||||
|
"+ ' total " +
|
||||||
|
"<span class=\"sparkline_range\">" +
|
||||||
|
"(" + shortSparkMinYear + " - " + currentYear + ")" +
|
||||||
|
"</span>'" +
|
||||||
|
"+ '';" +
|
||||||
|
"$('#" + visDivNames.get("SHORT_SPARK") + " td.sparkline_text').html(shortSparksText);");
|
||||||
|
|
||||||
|
visualizationCode.append("}\n ");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the code that will activate the visualization. It takes care of creating div elements to hold
|
||||||
|
* the actual sparkline image and then calling the drawPubCountVisualization function.
|
||||||
|
* */
|
||||||
|
visualizationCode.append(generateVisualizationActivator(visDivNames.get("SHORT_SPARK"), visContainerID));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateFullSparklineVisualizationContent(
|
||||||
|
int currentYear, int minPubYearConsidered, String visContainerID, StringBuilder visualizationCode,
|
||||||
|
int totalPublications, int renderedFullSparks,
|
||||||
|
String sparklineDisplayOptions) {
|
||||||
|
|
||||||
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getCSVDownloadURL() != null) {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\" class=\"inline_href\">(.CSV File)</a>";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
visualizationCode.append("var fullSparklineView = new google.visualization.DataView(data);\n" +
|
||||||
|
"fullSparklineView.setColumns([1]);\n");
|
||||||
|
|
||||||
|
visualizationCode.append("var full_spark = new google.visualization.ImageSparkLine(" +
|
||||||
|
// "document.getElementById('" + visDivNames.get("FULL_SPARK") + "')" +
|
||||||
|
"providedSparklineImgTD[0]" +
|
||||||
|
");\n" +
|
||||||
|
"full_spark.draw(fullSparklineView, " + sparklineDisplayOptions + ");\n");
|
||||||
|
|
||||||
|
visualizationCode.append("$('#" + visDivNames.get("FULL_SPARK") + " td.sparkline_number').text('" + renderedFullSparks + "');");
|
||||||
|
|
||||||
|
visualizationCode.append("var allSparksText = ''" +
|
||||||
|
"+ ' papers with year from '" +
|
||||||
|
"+ ' " + totalPublications + " '" +
|
||||||
|
"+ ' total " +
|
||||||
|
"<span class=\"sparkline_range\">" +
|
||||||
|
"(" + minPubYearConsidered + " - " + currentYear + ")" +
|
||||||
|
"</span> '" +
|
||||||
|
"+ ' " + csvDownloadURLHref + " ';" +
|
||||||
|
"$('#" + visDivNames.get("FULL_SPARK") + " td.sparkline_text').html(allSparksText);");
|
||||||
|
|
||||||
|
visualizationCode.append("}\n ");
|
||||||
|
|
||||||
|
visualizationCode.append(generateVisualizationActivator(visDivNames.get("FULL_SPARK"), visContainerID));
|
||||||
|
|
||||||
|
}
|
||||||
|
private String generateVisualizationActivator(String sparklineID, String visContainerID) {
|
||||||
|
|
||||||
|
String sparklineTableWrapper = "\n" +
|
||||||
|
"var table = $('<table>');" +
|
||||||
|
"table.attr('class', 'sparkline_wrapper_table');" +
|
||||||
|
"var row = $('<tr>');" +
|
||||||
|
"sparklineImgTD = $('<td>');" +
|
||||||
|
"sparklineImgTD.attr('id', '" + sparklineID + "_img');" +
|
||||||
|
"sparklineImgTD.attr('width', '65');" +
|
||||||
|
"sparklineImgTD.attr('align', 'right');" +
|
||||||
|
"sparklineImgTD.attr('class', '" + visualizationStyleClass + "');" +
|
||||||
|
"row.append(sparklineImgTD);" +
|
||||||
|
"var sparklineNumberTD = $('<td>');" +
|
||||||
|
"sparklineNumberTD.attr('width', '36');" +
|
||||||
|
"sparklineNumberTD.attr('align', 'right');" +
|
||||||
|
"sparklineNumberTD.attr('class', 'sparkline_number');" +
|
||||||
|
"row.append(sparklineNumberTD);" +
|
||||||
|
"var sparklineTextTD = $('<td>');" +
|
||||||
|
"sparklineTextTD.attr('width', '350');" +
|
||||||
|
"sparklineTextTD.attr('class', 'sparkline_text');" +
|
||||||
|
"row.append(sparklineTextTD);" +
|
||||||
|
"table.append(row);" +
|
||||||
|
"table.prependTo('#" + sparklineID + "');\n";
|
||||||
|
|
||||||
|
return "$(document).ready(function() {" +
|
||||||
|
|
||||||
|
"var sparklineImgTD; " +
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a nuclear option (creating the container in which everything goes)
|
||||||
|
* the only reason this will be ever used is the API user never submitted a
|
||||||
|
* container ID in which everything goes. The alternative was to let the
|
||||||
|
* vis not appear in the calling page at all. So now atleast vis appears but
|
||||||
|
* appended at the bottom of the body.
|
||||||
|
* */
|
||||||
|
"if ($('#" + visContainerID + "').length === 0) {" +
|
||||||
|
" $('<div/>', {'id': '" + visContainerID + "'" +
|
||||||
|
" }).appendTo('body');" +
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"if ($('#" + sparklineID + "').length === 0) {" +
|
||||||
|
|
||||||
|
"$('<div/>', {'id': '" + sparklineID + "'," +
|
||||||
|
"'class': '" + visualizationStyleClass + "'" +
|
||||||
|
"}).prependTo('#" + visContainerID + "');" +
|
||||||
|
|
||||||
|
sparklineTableWrapper +
|
||||||
|
|
||||||
|
"}" +
|
||||||
|
|
||||||
|
"drawPubCountVisualization(sparklineImgTD);" +
|
||||||
|
"});" +
|
||||||
|
"</script>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getVisualizationContextCode(String visMode) {
|
||||||
|
|
||||||
|
String visualizationContextCode = "";
|
||||||
|
if (SHORT_SPARKLINE_MODE_URL_HANDLE.equalsIgnoreCase(visMode)) {
|
||||||
|
visualizationContextCode = generateShortVisContext();
|
||||||
|
} else {
|
||||||
|
visualizationContextCode = generateFullVisContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
log.debug(visualizationContextCode);
|
||||||
|
// System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
|
||||||
|
|
||||||
|
return visualizationContextCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateFullVisContext() {
|
||||||
|
|
||||||
|
StringBuilder divContextCode = new StringBuilder();
|
||||||
|
|
||||||
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
if (yearToPublicationCount.size() > 0) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getCSVDownloadURL() != null) {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "Download data as <a href='" + getCSVDownloadURL() + "'>.csv</a> file.<br />";
|
||||||
|
valueObjectContainer.setDownloadDataLink(getCSVDownloadURL());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
csvDownloadURLHref = "No data available to export.<br />";
|
||||||
|
}
|
||||||
|
|
||||||
|
String tableCode = generateDataTable();
|
||||||
|
|
||||||
|
divContextCode.append("<p>" + tableCode +
|
||||||
|
csvDownloadURLHref + "</p>");
|
||||||
|
|
||||||
|
valueObjectContainer.setTable(tableCode);
|
||||||
|
|
||||||
|
return divContextCode.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCSVDownloadURL()
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
|
||||||
|
if (yearToPublicationCount.size() > 0) {
|
||||||
|
|
||||||
|
String secondaryContextPath = "";
|
||||||
|
if (!contextPath.contains("/admin/visQuery")) {
|
||||||
|
secondaryContextPath = "/admin/visQuery";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String downloadURL = contextPath
|
||||||
|
+ secondaryContextPath
|
||||||
|
+ "?" + VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&" + VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationController
|
||||||
|
.PERSON_PUBLICATION_COUNT_VIS_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&" + VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
System.out.println(" ----- >>>> " + contextPath + " XX " + individualURIParam + " XX " + downloadURL);
|
||||||
|
return downloadURL;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String generateShortVisContext() {
|
||||||
|
|
||||||
|
StringBuilder divContextCode = new StringBuilder();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
String fullTimelineLink;
|
||||||
|
if (yearToPublicationCount.size() > 0) {
|
||||||
|
|
||||||
|
String secondaryContextPath = "";
|
||||||
|
if (!contextPath.contains("/admin/visQuery")) {
|
||||||
|
secondaryContextPath = "/admin/visQuery";
|
||||||
|
}
|
||||||
|
|
||||||
|
String fullTimelineNetworkURL = contextPath
|
||||||
|
+ secondaryContextPath
|
||||||
|
+ "?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("person_level",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.STANDALONE_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
System.out.println("context parth full n/w " + contextPath);
|
||||||
|
|
||||||
|
fullTimelineLink = "<a href='" + fullTimelineNetworkURL + "'>View full timeline and co-author network</a><br />";
|
||||||
|
|
||||||
|
valueObjectContainer.setFullTimelineNetworkLink(fullTimelineNetworkURL);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fullTimelineLink = "No data available to render full timeline.<br />";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
divContextCode.append("<span class=\"vis_link\">" + fullTimelineLink + "</span>");
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return divContextCode.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String generateDataTable() {
|
||||||
|
|
||||||
|
String csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (getCSVDownloadURL() != null) {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "<a href=\"" + getCSVDownloadURL() + "\">(.CSV File)</a>";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
csvDownloadURLHref = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder dataTable = new StringBuilder();
|
||||||
|
|
||||||
|
dataTable.append("<table id='sparkline_data_table'>" +
|
||||||
|
"<caption>Publications per year " + csvDownloadURLHref + "</caption>" +
|
||||||
|
"<thead>" +
|
||||||
|
"<tr>" +
|
||||||
|
"<th>Year</th>" +
|
||||||
|
"<th>Publications</th>" +
|
||||||
|
"</tr>" +
|
||||||
|
"</thead>" +
|
||||||
|
"<tbody>");
|
||||||
|
|
||||||
|
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||||
|
dataTable.append("<tr>" +
|
||||||
|
"<td>" + currentEntry.getKey() + "</td>" +
|
||||||
|
"<td>" + currentEntry.getValue() + "</td>" +
|
||||||
|
"</tr>");
|
||||||
|
}
|
||||||
|
|
||||||
|
dataTable.append("</tbody>\n" +
|
||||||
|
"</table>\n");
|
||||||
|
|
||||||
|
|
||||||
|
return dataTable.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,333 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.personpubcount;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
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.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.PDFDocument;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.UtilityFunctions;
|
||||||
|
|
||||||
|
public class VisualizationRequestHandler {
|
||||||
|
|
||||||
|
private VitroRequest vitroRequest;
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private HttpServletResponse response;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public VisualizationRequestHandler(VitroRequest vitroRequest,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Log log) {
|
||||||
|
|
||||||
|
this.vitroRequest = vitroRequest;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateVisualization(DataSource dataSource) {
|
||||||
|
|
||||||
|
String resultFormatParam = "RS_TEXT";
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
String individualURIParam = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
|
||||||
|
|
||||||
|
String renderMode = vitroRequest.getParameter(VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String visContainer = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_CONTAINER_URL_HANDLE);
|
||||||
|
|
||||||
|
QueryHandler queryManager =
|
||||||
|
new QueryHandler(individualURIParam,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<BiboDocument> authorDocuments = queryManager.getVisualizationJavaValueObjects();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount =
|
||||||
|
queryManager.getYearToPublicationCount(authorDocuments);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to avoid unneeded computations we have pushed this "if" condition up.
|
||||||
|
* This case arises when the render mode is data. In that case we dont want to generate
|
||||||
|
* HTML code to render sparkline, tables etc. Ideally I would want to avoid this flow.
|
||||||
|
* It is ugly!
|
||||||
|
* */
|
||||||
|
if (VisualizationFrameworkConstants.DATA_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
prepareVisualizationQueryDataResponse(queryManager.getAuthor(),
|
||||||
|
authorDocuments,
|
||||||
|
yearToPublicationCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (VisualizationFrameworkConstants.PDF_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
prepareVisualizationQueryPDFResponse(queryManager.getAuthor(),
|
||||||
|
authorDocuments,
|
||||||
|
yearToPublicationCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computations required to generate HTML for the sparklines & related context.
|
||||||
|
* */
|
||||||
|
|
||||||
|
SparklineVOContainer valueObjectContainer = new SparklineVOContainer();
|
||||||
|
|
||||||
|
VisualizationCodeGenerator visualizationCodeGenerator =
|
||||||
|
new VisualizationCodeGenerator(vitroRequest.getContextPath(),
|
||||||
|
individualURIParam,
|
||||||
|
visMode,
|
||||||
|
visContainer,
|
||||||
|
authorDocuments,
|
||||||
|
yearToPublicationCount,
|
||||||
|
valueObjectContainer,
|
||||||
|
log);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is side-effecting because the response of this method is just to redirect to
|
||||||
|
* a page with visualization on it.
|
||||||
|
* */
|
||||||
|
RequestDispatcher requestDispatcher = null;
|
||||||
|
|
||||||
|
if (VisualizationFrameworkConstants.DYNAMIC_RENDER_MODE_URL_VALUE.equalsIgnoreCase(renderMode)) {
|
||||||
|
|
||||||
|
prepareVisualizationQueryDynamicResponse(request, response, vitroRequest,
|
||||||
|
valueObjectContainer);
|
||||||
|
requestDispatcher = request.getRequestDispatcher("/templates/page/blankPage.jsp");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
prepareVisualizationQueryStandaloneResponse(request, response, vitroRequest,
|
||||||
|
valueObjectContainer);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} catch (ServletException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryPDFResponse(Individual author, List<BiboDocument> authorDocuments,
|
||||||
|
Map<String, Integer> yearToPublicationCount) {
|
||||||
|
|
||||||
|
String authorName = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To protect against cases where there are no author documents associated with the
|
||||||
|
* individual.
|
||||||
|
* */
|
||||||
|
if (authorDocuments.size() > 0) {
|
||||||
|
authorName = author.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To make sure that null/empty records for author names do not cause any mischief.
|
||||||
|
* */
|
||||||
|
if (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();
|
||||||
|
|
||||||
|
// setting some response headers & content type
|
||||||
|
response.setHeader("Expires", "0");
|
||||||
|
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
|
||||||
|
response.setHeader("Pragma", "public");
|
||||||
|
response.setContentLength(baos.size());
|
||||||
|
// write ByteArrayOutputStream to the ServletOutputStream
|
||||||
|
baos.writeTo(responseOutputStream);
|
||||||
|
responseOutputStream.flush();
|
||||||
|
responseOutputStream.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryDataResponse(Individual author, List<BiboDocument> authorDocuments,
|
||||||
|
Map<String, Integer> yearToPublicationCount) {
|
||||||
|
|
||||||
|
String authorName = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To protect against cases where there are no author documents associated with the
|
||||||
|
* individual.
|
||||||
|
* */
|
||||||
|
if (authorDocuments.size() > 0) {
|
||||||
|
authorName = author.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To make sure that null/empty records for author names do not cause any mischief.
|
||||||
|
* */
|
||||||
|
if (authorName == null) {
|
||||||
|
authorName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String outputFileName = UtilityFunctions.slugify(authorName) + "pub-count-sparkline" + ".csv";
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition","attachment;filename=" + outputFileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
PrintWriter responseWriter = response.getWriter();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are side-effecting responseWriter since we are directly manipulating the response
|
||||||
|
* object of the servlet.
|
||||||
|
* */
|
||||||
|
generateCsvFileBuffer(yearToPublicationCount,
|
||||||
|
responseWriter);
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateCsvFileBuffer(Map<String, Integer> yearToPublicationCount,
|
||||||
|
PrintWriter responseWriter) {
|
||||||
|
|
||||||
|
CSVWriter csvWriter = new SimpleWriter(responseWriter);
|
||||||
|
|
||||||
|
try {
|
||||||
|
csvWriter.append(new String[]{"Year", "Publications"});
|
||||||
|
for (Entry<String, Integer> currentEntry : yearToPublicationCount.entrySet()) {
|
||||||
|
csvWriter.append(new Object[]{currentEntry.getKey(), currentEntry.getValue()});
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
responseWriter.flush();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryStandaloneResponse(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, VitroRequest vreq,
|
||||||
|
SparklineVOContainer valueObjectContainer) {
|
||||||
|
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("sparklineVO", valueObjectContainer);
|
||||||
|
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/publication_count.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Individual Publication Count visualization");
|
||||||
|
request.setAttribute("scripts", "/templates/visualization/visualization_scripts.jsp");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryDynamicResponse(HttpServletRequest request,
|
||||||
|
HttpServletResponse response, VitroRequest vreq, SparklineVOContainer valueObjectContainer) {
|
||||||
|
|
||||||
|
Portal portal = vreq.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("sparklineVO", valueObjectContainer);
|
||||||
|
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/ajax_vis_content.jsp");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Portal portal = vitroRequest.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,268 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.utilities;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
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.controller.visualization.VisualizationController;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.visualization.VisualizationFrameworkConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.QueryConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.exceptions.MalformedQueryParametersException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.GenericQueryMap;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.visutils.GenericQueryHandler;
|
||||||
|
|
||||||
|
public class VisualizationRequestHandler {
|
||||||
|
|
||||||
|
private VitroRequest vitroRequest;
|
||||||
|
private HttpServletRequest request;
|
||||||
|
private HttpServletResponse response;
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public VisualizationRequestHandler(VitroRequest vitroRequest,
|
||||||
|
HttpServletRequest request, HttpServletResponse response, Log log) {
|
||||||
|
|
||||||
|
this.vitroRequest = vitroRequest;
|
||||||
|
this.request = request;
|
||||||
|
this.response = response;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateVisualization(DataSource dataSource) {
|
||||||
|
|
||||||
|
String individualURIParam = vitroRequest.getParameter(VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE);
|
||||||
|
|
||||||
|
String visMode = vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_URL_HANDLE);
|
||||||
|
|
||||||
|
String profileInfoMode = "PROFILE_INFO";
|
||||||
|
String profileVisMode = "PROFILE_URL";
|
||||||
|
String coAuthorVisMode = "COAUTHORSHIP_URL";
|
||||||
|
String personLevelVisMode = "PERSON_LEVEL_URL";
|
||||||
|
String imageVisMode = "IMAGE_URL";
|
||||||
|
|
||||||
|
String resultFormatParam = "RS_TEXT";
|
||||||
|
String rdfResultFormatParam = "RDF/XML-ABBREV";
|
||||||
|
|
||||||
|
String preparedURL = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the info being requested is about a profile which includes the name, moniker
|
||||||
|
* & image url.
|
||||||
|
* */
|
||||||
|
if (profileInfoMode.equalsIgnoreCase(visMode)) {
|
||||||
|
|
||||||
|
|
||||||
|
String filterRule = "?predicate = vitro:imageThumb || ?predicate = vitro:moniker || ?predicate = rdfs:label";
|
||||||
|
GenericQueryHandler imageQueryHandler = new GenericQueryHandler(individualURIParam,
|
||||||
|
filterRule,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
GenericQueryMap profilePropertiesToValues = imageQueryHandler.getJavaValueObjects();
|
||||||
|
|
||||||
|
profilePropertiesToValues.addEntry("imageContextPath", request.getContextPath() + "/images/");
|
||||||
|
|
||||||
|
Gson profileInformation = new Gson();
|
||||||
|
|
||||||
|
prepareVisualizationQueryResponse(profileInformation.toJson(profilePropertiesToValues));
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
} catch (MalformedQueryParametersException e) {
|
||||||
|
try {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} catch (ServletException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (imageVisMode.equalsIgnoreCase(visMode)) {
|
||||||
|
/*
|
||||||
|
* If the url being requested is about a standalone image, which is used when we want
|
||||||
|
* to render an image & other info for a co-author OR ego for that matter.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
String filterRule = "?predicate = vitro:imageThumb";
|
||||||
|
GenericQueryHandler imageQueryHandler = new GenericQueryHandler(individualURIParam,
|
||||||
|
filterRule,
|
||||||
|
resultFormatParam,
|
||||||
|
rdfResultFormatParam,
|
||||||
|
dataSource,
|
||||||
|
log);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
GenericQueryMap imagePropertyToValues = imageQueryHandler.getJavaValueObjects();
|
||||||
|
|
||||||
|
String imagePath = "";
|
||||||
|
|
||||||
|
if (imagePropertyToValues.size() > 0) {
|
||||||
|
|
||||||
|
String vitroSparqlNamespace = QueryConstants.PREFIX_TO_NAMESPACE.get("vitro");
|
||||||
|
String imageThumbProperty = vitroSparqlNamespace + "imageThumb";
|
||||||
|
|
||||||
|
Set<String> personImageThumbPaths = imagePropertyToValues.get(imageThumbProperty);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Although we know that there can be only one imagePath we are restricted by Java's
|
||||||
|
* expression power.
|
||||||
|
* */
|
||||||
|
for (String providedImagePath : personImageThumbPaths) {
|
||||||
|
imagePath = request.getContextPath() + "/images/" + providedImagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareVisualizationQueryResponse(imagePath);
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
} catch (MalformedQueryParametersException e) {
|
||||||
|
try {
|
||||||
|
handleMalformedParameters(e.getMessage());
|
||||||
|
} catch (ServletException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.error(e1.getStackTrace());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else if (coAuthorVisMode.equalsIgnoreCase(visMode)) {
|
||||||
|
/*
|
||||||
|
* By default we will be generating profile url else some specific url like coAuthorShip vis
|
||||||
|
* url for that individual.
|
||||||
|
* */
|
||||||
|
|
||||||
|
preparedURL += request.getContextPath()
|
||||||
|
+ "/admin/visQuery"
|
||||||
|
+ "?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("coauthorship",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.STANDALONE_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
|
||||||
|
prepareVisualizationQueryResponse(preparedURL);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (personLevelVisMode.equalsIgnoreCase(visMode)) {
|
||||||
|
/*
|
||||||
|
* By default we will be generating profile url else some specific url like coAuthorShip vis
|
||||||
|
* url for that individual.
|
||||||
|
* */
|
||||||
|
|
||||||
|
preparedURL += request.getContextPath()
|
||||||
|
+ "/admin/visQuery"
|
||||||
|
+ "?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.VIS_TYPE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode("person_level",
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString()
|
||||||
|
+ "&"
|
||||||
|
+ VisualizationFrameworkConstants.RENDER_MODE_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(VisualizationFrameworkConstants.STANDALONE_RENDER_MODE_URL_VALUE,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
prepareVisualizationQueryResponse(preparedURL);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
preparedURL += request.getContextPath()
|
||||||
|
+ "/individual"
|
||||||
|
+ "?"
|
||||||
|
+ VisualizationFrameworkConstants.INDIVIDUAL_URI_URL_HANDLE
|
||||||
|
+ "=" + URLEncoder.encode(individualURIParam,
|
||||||
|
VisualizationController.URL_ENCODING_SCHEME).toString();
|
||||||
|
|
||||||
|
prepareVisualizationQueryResponse(preparedURL);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
log.error(e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareVisualizationQueryResponse(String preparedURL) {
|
||||||
|
|
||||||
|
response.setContentType("text/plain");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
PrintWriter responseWriter = response.getWriter();
|
||||||
|
|
||||||
|
responseWriter.append(preparedURL);
|
||||||
|
|
||||||
|
responseWriter.close();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMalformedParameters(String errorMessage)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
Portal portal = vitroRequest.getPortal();
|
||||||
|
|
||||||
|
request.setAttribute("error", errorMessage);
|
||||||
|
|
||||||
|
RequestDispatcher requestDispatcher = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||||
|
request.setAttribute("bodyJsp", "/templates/visualization/visualization_error.jsp");
|
||||||
|
request.setAttribute("portalBean", portal);
|
||||||
|
request.setAttribute("title", "Visualization Query Error - Individual Publication Count");
|
||||||
|
|
||||||
|
try {
|
||||||
|
requestDispatcher.forward(request, response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("EntityEditController could not forward to view.");
|
||||||
|
log.error(e.getMessage());
|
||||||
|
log.error(e.getStackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VOConstants;
|
||||||
|
|
||||||
|
public class BiboDocument extends Individual{
|
||||||
|
|
||||||
|
public static final int MINIMUM_PUBLICATION_YEAR = 1800;
|
||||||
|
private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR);
|
||||||
|
|
||||||
|
private String documentMoniker;
|
||||||
|
private String documentBlurb;
|
||||||
|
private String documentDescription;
|
||||||
|
private String publicationYear;
|
||||||
|
private String parsedPublicationYear = VOConstants.DEFAULT_PUBLICATION_YEAR;
|
||||||
|
|
||||||
|
public BiboDocument(String documentURL) {
|
||||||
|
super(documentURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentURL() {
|
||||||
|
return this.getIndividualURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentMoniker() {
|
||||||
|
return documentMoniker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDocumentMoniker(String documentMoniker) {
|
||||||
|
this.documentMoniker = documentMoniker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentLabel() {
|
||||||
|
return this.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDocumentLabel(String documentLabel) {
|
||||||
|
this.setIndividualLabel(documentLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentBlurb() {
|
||||||
|
return documentBlurb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDocumentBlurb(String documentBlurb) {
|
||||||
|
this.documentBlurb = documentBlurb;
|
||||||
|
|
||||||
|
if (documentBlurb != null) {
|
||||||
|
this.setParsedPublicationYear(parsePublicationYear(documentBlurb));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parsePublicationYear(String documentBlurb) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pattern will match all group of numbers which have only 4 digits
|
||||||
|
* delimited by the word boundary.
|
||||||
|
* */
|
||||||
|
// String pattern = "\\b\\d{4}\\b";
|
||||||
|
String pattern = "(?<!-)\\b\\d{4}\\b(?=[^-])";
|
||||||
|
|
||||||
|
Pattern yearPattern = Pattern.compile(pattern);
|
||||||
|
String publishedYear = VOConstants.DEFAULT_PUBLICATION_YEAR;
|
||||||
|
|
||||||
|
Matcher yearMatcher = yearPattern.matcher(documentBlurb);
|
||||||
|
|
||||||
|
while (yearMatcher.find()) {
|
||||||
|
|
||||||
|
String yearCandidate = yearMatcher.group();
|
||||||
|
|
||||||
|
Integer candidateYearInteger = Integer.valueOf(yearCandidate);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Published year has to be equal or less than the current year
|
||||||
|
* and more than a minimum default year.
|
||||||
|
* */
|
||||||
|
if (candidateYearInteger <= CURRENT_YEAR
|
||||||
|
&& candidateYearInteger >= MINIMUM_PUBLICATION_YEAR) {
|
||||||
|
publishedYear = candidateYearInteger.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return publishedYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDocumentDescription() {
|
||||||
|
return documentDescription;
|
||||||
|
}
|
||||||
|
public void setDocumentDescription(String documentDescription) {
|
||||||
|
this.documentDescription = documentDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only the
|
||||||
|
* */
|
||||||
|
private void setParsedPublicationYear(String parsedPublicationYear) {
|
||||||
|
this.parsedPublicationYear = parsedPublicationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParsedPublicationYear() {
|
||||||
|
return parsedPublicationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This publicationYear value is directly from the data supported by the ontology. If this is empty only
|
||||||
|
* then use the parsedPublicationYear.
|
||||||
|
* */
|
||||||
|
public String getPublicationYear() {
|
||||||
|
return publicationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicationYear(String publicationYear) {
|
||||||
|
this.publicationYear = publicationYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
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 is the Value Object for storing edge information mainly for co-author vis.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Edge {
|
||||||
|
|
||||||
|
private int edgeID;
|
||||||
|
private Map<String, Integer> yearToPublicationCount;
|
||||||
|
private Set<BiboDocument> collaboratorDocuments = new HashSet<BiboDocument>();
|
||||||
|
private Node sourceNode;
|
||||||
|
private Node targetNode;
|
||||||
|
|
||||||
|
public Edge(Node sourceNode, Node targetNode, BiboDocument seedCoAuthoredDocument,
|
||||||
|
UniqueIDGenerator uniqueIDGenerator) {
|
||||||
|
edgeID = uniqueIDGenerator.getNextNumericID();
|
||||||
|
this.sourceNode = sourceNode;
|
||||||
|
this.targetNode = targetNode;
|
||||||
|
this.collaboratorDocuments.add(seedCoAuthoredDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEdgeID() {
|
||||||
|
return edgeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getSourceNode() {
|
||||||
|
return sourceNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getTargetNode() {
|
||||||
|
return targetNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<BiboDocument> getCollaboratorDocuments() {
|
||||||
|
return collaboratorDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumOfCoAuthoredWorks() {
|
||||||
|
return collaboratorDocuments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCollaboratorDocument(BiboDocument authorDocument) {
|
||||||
|
this.collaboratorDocuments.add(authorDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getEarliest, Latest & Unknown Publication YearCount should only be used after
|
||||||
|
* the parsing of the entire sparql is done. Else it will give results based on
|
||||||
|
* incomplete dataset.
|
||||||
|
* */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public Map<String, Integer> getEarliestCollaborationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(collaboratorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not want to consider the default publication year when we are checking
|
||||||
|
* for the min or max publication year.
|
||||||
|
* */
|
||||||
|
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||||
|
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There can be a case when the only publication the author has no attached year to it
|
||||||
|
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||||
|
* NoSuchElementException.
|
||||||
|
*
|
||||||
|
* If there is no maximum year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (yearsToBeConsidered.size() > 0) {
|
||||||
|
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||||
|
final Integer earliestYearPubCount = yearToPublicationCount.get(earliestYear);
|
||||||
|
|
||||||
|
return new HashMap<String, Integer>(){{
|
||||||
|
put(earliestYear, earliestYearPubCount);
|
||||||
|
}};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public Map<String, Integer> getLatestCollaborationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(collaboratorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not want to consider the default publication year when we are checking
|
||||||
|
* for the min or max publication year.
|
||||||
|
* */
|
||||||
|
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||||
|
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There can be a case when the only publication the author has no attached year to it
|
||||||
|
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||||
|
* NoSuchElementException.
|
||||||
|
*
|
||||||
|
* If there is no maximum year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (yearsToBeConsidered.size() > 0) {
|
||||||
|
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||||
|
final Integer latestYearPubCount = yearToPublicationCount.get(latestYear);
|
||||||
|
|
||||||
|
return new HashMap<String, Integer>(){{
|
||||||
|
put(latestYear, latestYearPubCount);
|
||||||
|
}};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public Integer getUnknownCollaborationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(collaboratorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer unknownYearPubCount = yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is no unknown year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (unknownYearPubCount != null) {
|
||||||
|
return unknownYearPubCount;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Right now this is just acting as a hashmap but in future we would want to provide
|
||||||
|
* more detailed info other than just what properties had what values. E.g. we
|
||||||
|
* could parse properties (& its values) to look for what namespaces are used.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class GenericQueryMap extends HashMap<String, Set<String>> {
|
||||||
|
|
||||||
|
public GenericQueryMap() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEntry(String property, String value) {
|
||||||
|
|
||||||
|
Set<String> values;
|
||||||
|
|
||||||
|
if (this.containsKey(property)) {
|
||||||
|
|
||||||
|
values = this.get(property);
|
||||||
|
values.add(value);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
values = new HashSet<String>();
|
||||||
|
values.add(value);
|
||||||
|
this.put(property, values);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
public class Individual {
|
||||||
|
|
||||||
|
private String individualLabel;
|
||||||
|
private String individualURL;
|
||||||
|
|
||||||
|
public Individual(String individualURL, String individualLabel) {
|
||||||
|
this.individualURL = individualURL;
|
||||||
|
this.individualLabel = individualLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Individual(String individualURL) {
|
||||||
|
this(individualURL, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIndividualLabel() {
|
||||||
|
return individualLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndividualLabel(String individualLabel) {
|
||||||
|
this.individualLabel = individualLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIndividualURL() {
|
||||||
|
return individualURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
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 is the Value Object for storing node information mainly for co-author vis.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Node extends Individual {
|
||||||
|
|
||||||
|
private int nodeID;
|
||||||
|
private Map<String, Integer> yearToPublicationCount;
|
||||||
|
|
||||||
|
private Set<BiboDocument> authorDocuments = new HashSet<BiboDocument>();
|
||||||
|
|
||||||
|
public Node(String nodeURL,
|
||||||
|
UniqueIDGenerator uniqueIDGenerator) {
|
||||||
|
super(nodeURL);
|
||||||
|
nodeID = uniqueIDGenerator.getNextNumericID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNodeID() {
|
||||||
|
return nodeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNodeURL() {
|
||||||
|
return this.getIndividualURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNodeName() {
|
||||||
|
return this.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeName(String nodeName) {
|
||||||
|
this.setIndividualLabel(nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<BiboDocument> getAuthorDocuments() {
|
||||||
|
return authorDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumOfAuthoredWorks() {
|
||||||
|
return authorDocuments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAuthorDocument(BiboDocument authorDocument) {
|
||||||
|
this.authorDocuments.add(authorDocument);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, Integer> getYearToPublicationCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||||
|
}
|
||||||
|
return yearToPublicationCount;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* getEarliest, Latest & Unknown Publication YearCount should only be used after
|
||||||
|
* the parsing of the entire sparql is done. Else it will give results based on
|
||||||
|
* incomplete dataset.
|
||||||
|
* */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public Map<String, Integer> getEarliestPublicationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not want to consider the default publication year when we are checking
|
||||||
|
* for the min or max publication year.
|
||||||
|
* */
|
||||||
|
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||||
|
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There can be a case when the only publication the author has no attached year to it
|
||||||
|
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||||
|
* NoSuchElementException.
|
||||||
|
*
|
||||||
|
* If there is no maximum year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (yearsToBeConsidered.size() > 0) {
|
||||||
|
final String earliestYear = Collections.min(yearsToBeConsidered);
|
||||||
|
final Integer earliestYearPubCount = yearToPublicationCount.get(earliestYear);
|
||||||
|
|
||||||
|
return new HashMap<String, Integer>(){{
|
||||||
|
put(earliestYear, earliestYearPubCount);
|
||||||
|
}};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public Map<String, Integer> getLatestPublicationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not want to consider the default publication year when we are checking
|
||||||
|
* for the min or max publication year.
|
||||||
|
* */
|
||||||
|
Set<String> yearsToBeConsidered = new HashSet<String>(yearToPublicationCount.keySet());
|
||||||
|
yearsToBeConsidered.remove(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There can be a case when the only publication the author has no attached year to it
|
||||||
|
* so essentially an "Unknown". In that case Collections.max or min will throw an
|
||||||
|
* NoSuchElementException.
|
||||||
|
*
|
||||||
|
* If there is no maximum year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (yearsToBeConsidered.size() > 0) {
|
||||||
|
final String latestYear = Collections.max(yearsToBeConsidered);
|
||||||
|
final Integer latestYearPubCount = yearToPublicationCount.get(latestYear);
|
||||||
|
|
||||||
|
return new HashMap<String, Integer>(){{
|
||||||
|
put(latestYear, latestYearPubCount);
|
||||||
|
}};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getUnknownPublicationYearCount() {
|
||||||
|
if (yearToPublicationCount == null) {
|
||||||
|
yearToPublicationCount = UtilityFunctions.getYearToPublicationCount(authorDocuments);
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer unknownYearPubCount = yearToPublicationCount.get(VOConstants.DEFAULT_PUBLICATION_YEAR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is no unknown year available then we should imply so by returning a "null".
|
||||||
|
* */
|
||||||
|
if (unknownYearPubCount != null) {
|
||||||
|
return unknownYearPubCount;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
public class SparklineVOContainer {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now sparklineNumPublicationsText & sparklinePublicationRangeText is left
|
||||||
|
* as empty but later on we would want to leverage the granularity that this
|
||||||
|
* provides.
|
||||||
|
* */
|
||||||
|
private String sparklineNumPublicationsText = "";
|
||||||
|
private String sparklinePublicationRangeText = "";
|
||||||
|
|
||||||
|
private Integer earliestRenderedPublicationYear;
|
||||||
|
private Integer latestRenderedPublicationYear;
|
||||||
|
|
||||||
|
private String table = "";
|
||||||
|
|
||||||
|
private String downloadDataLink = "";
|
||||||
|
private String fullTimelineNetworkLink = "";
|
||||||
|
|
||||||
|
private String sparklineContent;
|
||||||
|
private String sparklineContext;
|
||||||
|
|
||||||
|
public String getSparklineNumPublicationsText() {
|
||||||
|
return sparklineNumPublicationsText;
|
||||||
|
}
|
||||||
|
public void setSparklineNumPublicationsText(String sparklineNumPublicationsText) {
|
||||||
|
this.sparklineNumPublicationsText = sparklineNumPublicationsText;
|
||||||
|
}
|
||||||
|
public String getSparklinePublicationRangeText() {
|
||||||
|
return sparklinePublicationRangeText;
|
||||||
|
}
|
||||||
|
public void setSparklinePublicationRangeText(
|
||||||
|
String sparklinePublicationRangeText) {
|
||||||
|
this.sparklinePublicationRangeText = sparklinePublicationRangeText;
|
||||||
|
}
|
||||||
|
public Integer getEarliestRenderedPublicationYear() {
|
||||||
|
return earliestRenderedPublicationYear;
|
||||||
|
}
|
||||||
|
public void setEarliestRenderedPublicationYear(
|
||||||
|
Integer earliestRenderedPublicationYear) {
|
||||||
|
this.earliestRenderedPublicationYear = earliestRenderedPublicationYear;
|
||||||
|
}
|
||||||
|
public Integer getLatestRenderedPublicationYear() {
|
||||||
|
return latestRenderedPublicationYear;
|
||||||
|
}
|
||||||
|
public void setLatestRenderedPublicationYear(
|
||||||
|
Integer latestRenderedPublicationYear) {
|
||||||
|
this.latestRenderedPublicationYear = latestRenderedPublicationYear;
|
||||||
|
}
|
||||||
|
public String getTable() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
public void setTable(String table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
public String getDownloadDataLink() {
|
||||||
|
return downloadDataLink;
|
||||||
|
}
|
||||||
|
public void setDownloadDataLink(String downloadDataLink) {
|
||||||
|
this.downloadDataLink = downloadDataLink;
|
||||||
|
}
|
||||||
|
public String getFullTimelineNetworkLink() {
|
||||||
|
return fullTimelineNetworkLink;
|
||||||
|
}
|
||||||
|
public void setFullTimelineNetworkLink(String fullTimelineNetworkLink) {
|
||||||
|
this.fullTimelineNetworkLink = fullTimelineNetworkLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSparklineContent() {
|
||||||
|
return sparklineContent;
|
||||||
|
}
|
||||||
|
public void setSparklineContent(String shortSparklineContent) {
|
||||||
|
this.sparklineContent = shortSparklineContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSparklineContext() {
|
||||||
|
return sparklineContext;
|
||||||
|
}
|
||||||
|
public void setSparklineContext(String shortSparklineContext) {
|
||||||
|
this.sparklineContext = shortSparklineContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This is the Value Object equivalent for vivo:CollegeOrSchoolWithinUniversity object type.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class VivoCollegeOrSchool extends Individual {
|
||||||
|
|
||||||
|
private Set<VivoDepartmentOrDivision> departments = new HashSet<VivoDepartmentOrDivision>();
|
||||||
|
|
||||||
|
public VivoCollegeOrSchool(String collegeURL) {
|
||||||
|
super(collegeURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<VivoDepartmentOrDivision> getDepartments() {
|
||||||
|
return departments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDepartment(VivoDepartmentOrDivision department) {
|
||||||
|
this.departments.add(department);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCollegeURL() {
|
||||||
|
return this.getIndividualURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCollegeLabel() {
|
||||||
|
return this.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCollegeLabel(String collegeLabel) {
|
||||||
|
this.setIndividualLabel(collegeLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.valueobjects;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This is the Value Object equivalent for vivo:AcademicDepartmentOrDivision object type.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class VivoDepartmentOrDivision extends Individual {
|
||||||
|
|
||||||
|
private Set<VivoCollegeOrSchool> parentColleges = new HashSet<VivoCollegeOrSchool>();
|
||||||
|
|
||||||
|
public VivoDepartmentOrDivision(String departmentURL, VivoCollegeOrSchool parentCollege) {
|
||||||
|
super(departmentURL);
|
||||||
|
addParentCollege(parentCollege);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<VivoCollegeOrSchool> getParentCollege() {
|
||||||
|
return parentColleges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addParentCollege(VivoCollegeOrSchool parentCollege) {
|
||||||
|
this.parentColleges.add(parentCollege);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartmentURL() {
|
||||||
|
return this.getIndividualURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartmentLabel() {
|
||||||
|
return this.getIndividualLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartmentLabel(String departmentLabel) {
|
||||||
|
this.setIndividualLabel(departmentLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
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 Value Object 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 getEmployeeURL() {
|
||||||
|
return this.getIndividualURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
|
||||||
|
|
||||||
|
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.GenericQueryMap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Very dumb name of the class. change it.
|
||||||
|
* @author cdtank
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GenericQueryHandler {
|
||||||
|
|
||||||
|
protected static final Syntax SYNTAX = Syntax.syntaxARQ;
|
||||||
|
|
||||||
|
private String filterRule, individualURLParam, resultFormatParam, rdfResultFormatParam;
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public GenericQueryHandler(String individualURLParam,
|
||||||
|
String filterRule,
|
||||||
|
String resultFormatParam,
|
||||||
|
String rdfResultFormatParam,
|
||||||
|
DataSource dataSource,
|
||||||
|
Log log) {
|
||||||
|
|
||||||
|
this.individualURLParam = individualURLParam;
|
||||||
|
this.filterRule = filterRule;
|
||||||
|
this.resultFormatParam = resultFormatParam;
|
||||||
|
this.rdfResultFormatParam = rdfResultFormatParam;
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
this.log = log;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private GenericQueryMap createJavaValueObjects(ResultSet resultSet) {
|
||||||
|
|
||||||
|
GenericQueryMap queryResultVO = new GenericQueryMap();
|
||||||
|
|
||||||
|
while (resultSet.hasNext()) {
|
||||||
|
QuerySolution solution = resultSet.nextSolution();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only want to create only ONE ego node.
|
||||||
|
* */
|
||||||
|
RDFNode predicateNode = solution.get(QueryFieldLabels.PREDICATE);
|
||||||
|
RDFNode objectNode = solution.get(QueryFieldLabels.OBJECT);
|
||||||
|
|
||||||
|
if (predicateNode != null && objectNode != null) {
|
||||||
|
queryResultVO.addEntry(predicateNode.toString(),
|
||||||
|
objectNode.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryResultVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ResultSet executeQuery(String queryText,
|
||||||
|
String resultFormatParam,
|
||||||
|
String rdfResultFormatParam,
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
//remocve this if loop after knowing what is describe & construct sparql stuff.
|
||||||
|
if (query.isSelectType()){
|
||||||
|
return queryExecution.execSelect();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if(queryExecution != null) {
|
||||||
|
queryExecution.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateGenericSparqlQuery(String queryURI, String filterRule) {
|
||||||
|
// Resource uri1 = ResourceFactory.createResource(queryURI);
|
||||||
|
String filterClause;
|
||||||
|
|
||||||
|
if (filterRule == null || filterRule.trim().isEmpty()) {
|
||||||
|
filterClause = "";
|
||||||
|
} else {
|
||||||
|
filterClause = "FILTER ( " + filterRule + " ) . ";
|
||||||
|
}
|
||||||
|
|
||||||
|
String sparqlQuery = QueryConstants.getSparqlPrefixQuery()
|
||||||
|
+ "SELECT "
|
||||||
|
+ " (str(?predicate) as ?" + QueryFieldLabels.PREDICATE + ") "
|
||||||
|
+ " (str(?object) as ?" + QueryFieldLabels.OBJECT + ") "
|
||||||
|
+ "WHERE { "
|
||||||
|
+ "<" + queryURI + "> ?predicate ?object. "
|
||||||
|
+ filterClause
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
System.out.println(sparqlQuery);
|
||||||
|
|
||||||
|
return sparqlQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public GenericQueryMap getJavaValueObjects()
|
||||||
|
throws MalformedQueryParametersException {
|
||||||
|
|
||||||
|
if (this.individualURLParam == null || "".equals(individualURLParam)) {
|
||||||
|
throw new MalformedQueryParametersException("URI parameter is either null or empty.");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To test for the validity of the URI submitted.
|
||||||
|
* */
|
||||||
|
IRIFactory iRIFactory = IRIFactory.jenaImplementation();
|
||||||
|
IRI iri = iRIFactory.create(this.individualURLParam);
|
||||||
|
if (iri.hasViolation(false)) {
|
||||||
|
String errorMsg = ((Violation)iri.violations(false).next()).getShortMessage()+" ";
|
||||||
|
log.error("Generic Query " + errorMsg);
|
||||||
|
throw new MalformedQueryParametersException("URI provided for an individual is malformed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultSet resultSet = executeQuery(generateGenericSparqlQuery(this.individualURLParam, this.filterRule),
|
||||||
|
this.resultFormatParam,
|
||||||
|
this.rdfResultFormatParam,
|
||||||
|
this.dataSource);
|
||||||
|
|
||||||
|
return createJavaValueObjects(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
|
||||||
|
|
||||||
|
public class UniqueIDGenerator {
|
||||||
|
|
||||||
|
private int nextNumericID = 1;
|
||||||
|
|
||||||
|
public int getNextNumericID() {
|
||||||
|
int nextNumericID = this.nextNumericID;
|
||||||
|
this.nextNumericID++;
|
||||||
|
|
||||||
|
return nextNumericID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.visualization.visutils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.constants.VisConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.BiboDocument;
|
||||||
|
|
||||||
|
public class UtilityFunctions {
|
||||||
|
|
||||||
|
public static Map<String, Integer> getYearToPublicationCount(
|
||||||
|
Set<BiboDocument> authorDocuments) {
|
||||||
|
|
||||||
|
//List<Integer> publishedYears = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a map from the year to number of publications. Use the BiboDocument's
|
||||||
|
* parsedPublicationYear to populate the data.
|
||||||
|
* */
|
||||||
|
Map<String, Integer> yearToPublicationCount = new TreeMap<String, Integer>();
|
||||||
|
|
||||||
|
for (BiboDocument curr : authorDocuments) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Increment the count because there is an entry already available for
|
||||||
|
* that particular year.
|
||||||
|
* */
|
||||||
|
String publicationYear;
|
||||||
|
if (curr.getPublicationYear() != null
|
||||||
|
&& curr.getPublicationYear().length() != 0
|
||||||
|
&& curr.getPublicationYear().trim().length() != 0) {
|
||||||
|
publicationYear = curr.getPublicationYear();
|
||||||
|
} else {
|
||||||
|
publicationYear = curr.getParsedPublicationYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yearToPublicationCount.containsKey(publicationYear)) {
|
||||||
|
yearToPublicationCount.put(publicationYear,
|
||||||
|
yearToPublicationCount
|
||||||
|
.get(publicationYear) + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
yearToPublicationCount.put(publicationYear, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!parsedPublicationYear.equalsIgnoreCase(BiboDocument.DEFAULT_PUBLICATION_YEAR)) {
|
||||||
|
// publishedYears.add(Integer.parseInt(parsedPublicationYear));
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return yearToPublicationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently the approach for slugifying filenames is naive. In future if there is need,
|
||||||
|
* we can write more sophisticated method.
|
||||||
|
* @param textToBeSlugified
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String slugify(String textToBeSlugified) {
|
||||||
|
return textToBeSlugified.toLowerCase().replaceAll("[^a-zA-Z0-9-]", "-")
|
||||||
|
.substring(0, VisConstants.MAX_NAME_TEXT_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
webapp/web/images/people/erb_hollis_thumb.gif
Normal file
BIN
webapp/web/images/people/erb_hollis_thumb.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
292
webapp/web/js/visualization/coauthorship/AC_OETags.js
Normal file
292
webapp/web/js/visualization/coauthorship/AC_OETags.js
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
// Flash Player Version Detection - Rev 1.6
|
||||||
|
// Detect Client Browser type
|
||||||
|
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
|
||||||
|
var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
|
||||||
|
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
|
||||||
|
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
|
||||||
|
|
||||||
|
function ControlVersion()
|
||||||
|
{
|
||||||
|
var version;
|
||||||
|
var axo;
|
||||||
|
var e;
|
||||||
|
|
||||||
|
// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
|
||||||
|
|
||||||
|
try {
|
||||||
|
// version will be set for 7.X or greater players
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 6.X players only
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
|
||||||
|
|
||||||
|
// installed player is some revision of 6.0
|
||||||
|
// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
|
||||||
|
// so we have to be careful.
|
||||||
|
|
||||||
|
// default to the first public version
|
||||||
|
version = "WIN 6,0,21,0";
|
||||||
|
|
||||||
|
// throws if AllowScripAccess does not exist (introduced in 6.0r47)
|
||||||
|
axo.AllowScriptAccess = "always";
|
||||||
|
|
||||||
|
// safe to call for 6.0r47 or greater
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 4.X or 5.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||||
|
version = axo.GetVariable("$version");
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 3.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
|
||||||
|
version = "WIN 3,0,18,0";
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// version will be set for 2.X player
|
||||||
|
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
|
||||||
|
version = "WIN 2,0,0,11";
|
||||||
|
} catch (e) {
|
||||||
|
version = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JavaScript helper required to detect Flash Player PlugIn version information
|
||||||
|
function GetSwfVer(){
|
||||||
|
// NS/Opera version >= 3 check for Flash plugin in plugin array
|
||||||
|
var flashVer = -1;
|
||||||
|
|
||||||
|
if (navigator.plugins != null && navigator.plugins.length > 0) {
|
||||||
|
if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
|
||||||
|
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
|
||||||
|
var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
|
||||||
|
var descArray = flashDescription.split(" ");
|
||||||
|
var tempArrayMajor = descArray[2].split(".");
|
||||||
|
var versionMajor = tempArrayMajor[0];
|
||||||
|
var versionMinor = tempArrayMajor[1];
|
||||||
|
var versionRevision = descArray[3];
|
||||||
|
if (versionRevision == "") {
|
||||||
|
versionRevision = descArray[4];
|
||||||
|
}
|
||||||
|
if (versionRevision[0] == "d") {
|
||||||
|
versionRevision = versionRevision.substring(1);
|
||||||
|
} else if (versionRevision[0] == "r") {
|
||||||
|
versionRevision = versionRevision.substring(1);
|
||||||
|
if (versionRevision.indexOf("d") > 0) {
|
||||||
|
versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
|
||||||
|
}
|
||||||
|
} else if (versionRevision[0] == "b") {
|
||||||
|
versionRevision = versionRevision.substring(1);
|
||||||
|
}
|
||||||
|
var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// MSN/WebTV 2.6 supports Flash 4
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
|
||||||
|
// WebTV 2.5 supports Flash 3
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
|
||||||
|
// older WebTV supports Flash 2
|
||||||
|
else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
|
||||||
|
else if ( isIE && isWin && !isOpera ) {
|
||||||
|
flashVer = ControlVersion();
|
||||||
|
}
|
||||||
|
return flashVer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
|
||||||
|
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
|
||||||
|
{
|
||||||
|
versionStr = GetSwfVer();
|
||||||
|
if (versionStr == -1 ) {
|
||||||
|
return false;
|
||||||
|
} else if (versionStr != 0) {
|
||||||
|
if(isIE && isWin && !isOpera) {
|
||||||
|
// Given "WIN 2,0,0,11"
|
||||||
|
tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"]
|
||||||
|
tempString = tempArray[1]; // "2,0,0,11"
|
||||||
|
versionArray = tempString.split(","); // ['2', '0', '0', '11']
|
||||||
|
} else {
|
||||||
|
versionArray = versionStr.split(".");
|
||||||
|
}
|
||||||
|
var versionMajor = versionArray[0];
|
||||||
|
var versionMinor = versionArray[1];
|
||||||
|
var versionRevision = versionArray[2];
|
||||||
|
|
||||||
|
// is the major.revision >= requested major.revision AND the minor version >= requested minor
|
||||||
|
if (versionMajor > parseFloat(reqMajorVer)) {
|
||||||
|
return true;
|
||||||
|
} else if (versionMajor == parseFloat(reqMajorVer)) {
|
||||||
|
if (versionMinor > parseFloat(reqMinorVer))
|
||||||
|
return true;
|
||||||
|
else if (versionMinor == parseFloat(reqMinorVer)) {
|
||||||
|
if (versionRevision >= parseFloat(reqRevision))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_AddExtension(src, ext)
|
||||||
|
{
|
||||||
|
var qIndex = src.indexOf('?');
|
||||||
|
if ( qIndex != -1)
|
||||||
|
{
|
||||||
|
// Add the extention (if needed) before the query params
|
||||||
|
var path = src.substring(0, qIndex);
|
||||||
|
if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length))
|
||||||
|
return src;
|
||||||
|
else
|
||||||
|
return src.replace(/\?/, ext+'?');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the extension (if needed) to the end of the URL
|
||||||
|
if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length))
|
||||||
|
return src; // Already have extension
|
||||||
|
else
|
||||||
|
return src + ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_Generateobj(objAttrs, params, embedAttrs)
|
||||||
|
{
|
||||||
|
var str = '';
|
||||||
|
if (isIE && isWin && !isOpera)
|
||||||
|
{
|
||||||
|
str += '<object ';
|
||||||
|
for (var i in objAttrs)
|
||||||
|
str += i + '="' + objAttrs[i] + '" ';
|
||||||
|
str += '>';
|
||||||
|
for (var i in params)
|
||||||
|
str += '<param name="' + i + '" value="' + params[i] + '" /> ';
|
||||||
|
str += '</object>';
|
||||||
|
} else {
|
||||||
|
str += '<embed ';
|
||||||
|
for (var i in embedAttrs)
|
||||||
|
str += i + '="' + embedAttrs[i] + '" ';
|
||||||
|
str += '> </embed>';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_FL_RunContent(){
|
||||||
|
var ret =
|
||||||
|
AC_GetArgs
|
||||||
|
( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
|
||||||
|
, "application/x-shockwave-flash"
|
||||||
|
);
|
||||||
|
AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
|
||||||
|
var ret = new Object();
|
||||||
|
ret.embedAttrs = new Object();
|
||||||
|
ret.params = new Object();
|
||||||
|
ret.objAttrs = new Object();
|
||||||
|
for (var i=0; i < args.length; i=i+2){
|
||||||
|
var currArg = args[i].toLowerCase();
|
||||||
|
|
||||||
|
switch (currArg){
|
||||||
|
case "classid":
|
||||||
|
break;
|
||||||
|
case "pluginspage":
|
||||||
|
ret.embedAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "src":
|
||||||
|
case "movie":
|
||||||
|
args[i+1] = AC_AddExtension(args[i+1], ext);
|
||||||
|
ret.embedAttrs["src"] = args[i+1];
|
||||||
|
ret.params[srcParamName] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "onafterupdate":
|
||||||
|
case "onbeforeupdate":
|
||||||
|
case "onblur":
|
||||||
|
case "oncellchange":
|
||||||
|
case "onclick":
|
||||||
|
case "ondblClick":
|
||||||
|
case "ondrag":
|
||||||
|
case "ondragend":
|
||||||
|
case "ondragenter":
|
||||||
|
case "ondragleave":
|
||||||
|
case "ondragover":
|
||||||
|
case "ondrop":
|
||||||
|
case "onfinish":
|
||||||
|
case "onfocus":
|
||||||
|
case "onhelp":
|
||||||
|
case "onmousedown":
|
||||||
|
case "onmouseup":
|
||||||
|
case "onmouseover":
|
||||||
|
case "onmousemove":
|
||||||
|
case "onmouseout":
|
||||||
|
case "onkeypress":
|
||||||
|
case "onkeydown":
|
||||||
|
case "onkeyup":
|
||||||
|
case "onload":
|
||||||
|
case "onlosecapture":
|
||||||
|
case "onpropertychange":
|
||||||
|
case "onreadystatechange":
|
||||||
|
case "onrowsdelete":
|
||||||
|
case "onrowenter":
|
||||||
|
case "onrowexit":
|
||||||
|
case "onrowsinserted":
|
||||||
|
case "onstart":
|
||||||
|
case "onscroll":
|
||||||
|
case "onbeforeeditfocus":
|
||||||
|
case "onactivate":
|
||||||
|
case "onbeforedeactivate":
|
||||||
|
case "ondeactivate":
|
||||||
|
case "type":
|
||||||
|
case "codebase":
|
||||||
|
ret.objAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
case "id":
|
||||||
|
case "width":
|
||||||
|
case "height":
|
||||||
|
case "align":
|
||||||
|
case "vspace":
|
||||||
|
case "hspace":
|
||||||
|
case "class":
|
||||||
|
case "title":
|
||||||
|
case "accesskey":
|
||||||
|
case "name":
|
||||||
|
case "tabindex":
|
||||||
|
ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.objAttrs["classid"] = classid;
|
||||||
|
if (mimeType) ret.embedAttrs["type"] = mimeType;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
274
webapp/web/js/visualization/coauthorship/co_authorship.js
Normal file
274
webapp/web/js/visualization/coauthorship/co_authorship.js
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
function getWellFormedURLs(given_uri, type) {
|
||||||
|
|
||||||
|
// general best practice is to put javascript code inside document.ready
|
||||||
|
// but in this case when i do that the function does not get called
|
||||||
|
// properly.
|
||||||
|
// so removing it for now.
|
||||||
|
|
||||||
|
// $(document).ready(function() {
|
||||||
|
|
||||||
|
if (type == "coauthorship") {
|
||||||
|
|
||||||
|
var finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "COAUTHORSHIP_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
// console.log("COA - " + data);
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
|
||||||
|
} else if (type == "profile") {
|
||||||
|
|
||||||
|
var finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "PROFILE_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
} else if (type == "image") {
|
||||||
|
|
||||||
|
var finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "IMAGE_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
} else if (type == "profile_info") {
|
||||||
|
|
||||||
|
var profileInfoJSON = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "PROFILE_INFO", uri: given_uri}),
|
||||||
|
dataType: "json",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return profileInfoJSON;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.image = function(src, successFunc, failureFunc){
|
||||||
|
return this.each(function(){
|
||||||
|
var profileImage = new Image();
|
||||||
|
profileImage.src = src;
|
||||||
|
profileImage.width = 150;
|
||||||
|
profileImage.onerror = failureFunc;
|
||||||
|
profileImage.onload = successFunc;
|
||||||
|
|
||||||
|
|
||||||
|
return profileImage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileImage(imageContainerID, rawPath, contextPath) {
|
||||||
|
|
||||||
|
if (imageContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var imageLink = contextPath + rawPath;
|
||||||
|
|
||||||
|
var imageContainer = $("#" + imageContainerID);
|
||||||
|
imageContainer.image(imageLink,
|
||||||
|
function(){
|
||||||
|
imageContainer.empty().append(this);
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
//For performing any action on failure to
|
||||||
|
//find the image.
|
||||||
|
imageContainer.empty();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileMoniker(monikerContainerID, moniker) {
|
||||||
|
|
||||||
|
if (monikerContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#" + monikerContainerID).empty().text(moniker);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileName(nameContainerID, name) {
|
||||||
|
|
||||||
|
if (nameContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#" + nameContainerID).empty().text(name);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function processProfileInformation(nameContainerID,
|
||||||
|
monikerContainerID,
|
||||||
|
imageContainerID,
|
||||||
|
profileInfoJSON) {
|
||||||
|
|
||||||
|
|
||||||
|
var name, imageRawPath, imageContextPath, moniker;
|
||||||
|
|
||||||
|
$.each(profileInfoJSON, function(key, set){
|
||||||
|
|
||||||
|
if (key.search(/imageThumb/i) > -1) {
|
||||||
|
|
||||||
|
imageRawPath = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/imageContextPath/i) > -1) {
|
||||||
|
|
||||||
|
imageContextPath = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/moniker/i) > -1) {
|
||||||
|
|
||||||
|
moniker = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/label/i) > -1) {
|
||||||
|
|
||||||
|
name = set[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
setProfileName(nameContainerID, name);
|
||||||
|
setProfileMoniker(monikerContainerID, moniker);
|
||||||
|
setProfileImage(imageContainerID, imageRawPath, imageContextPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function nodeClickedJS(json){
|
||||||
|
|
||||||
|
var obj = jQuery.parseJSON(json);
|
||||||
|
|
||||||
|
$("#newsLetter").attr("style","visibility:visible");
|
||||||
|
$("#authorName").empty().append(obj.name);
|
||||||
|
$("#works").empty().append(obj.number_of_authored_works);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here obj.url points to the uri of that individual
|
||||||
|
*/
|
||||||
|
if(obj.url){
|
||||||
|
$("#profileUrl").attr("href", getWellFormedURLs(obj.url, "profile"));
|
||||||
|
$("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, "coauthorship"));
|
||||||
|
processProfileInformation("",
|
||||||
|
"profileMoniker",
|
||||||
|
"profileImage",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs(obj.url, "profile_info")));
|
||||||
|
|
||||||
|
} else{
|
||||||
|
$("#profileUrl").attr("href","#");
|
||||||
|
$("#coAuthorshipVisUrl").attr("href","#");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#coAuthorName").empty().append(obj.name);
|
||||||
|
|
||||||
|
$("#coAuthors").empty().append(obj.num_coauthors);
|
||||||
|
$("#firstPublication").empty().append((obj.earliest_publication)?obj.earliest_publication+" First Publication":"");
|
||||||
|
$("#lastPublication").empty().append((obj.latest_publication)?obj.latest_publication+" Last Publication":"");
|
||||||
|
|
||||||
|
// obj.url:the url parameter for node
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderSparklineVisualization(visualizationURL) {
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
//$("#ego_sparkline").empty().html('<img src="${loadingImageLink}" />');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: visualizationURL,
|
||||||
|
dataType: "html",
|
||||||
|
success:function(data){
|
||||||
|
$("#ego_sparkline").html(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCoAuthorshipVisualization() {
|
||||||
|
|
||||||
|
//Version check for the Flash Player that has the ability to start Player
|
||||||
|
//Product Install (6.0r65)
|
||||||
|
var hasProductInstall = DetectFlashVer(6, 0, 65);
|
||||||
|
|
||||||
|
//Version check based upon the values defined in globals
|
||||||
|
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
|
||||||
|
|
||||||
|
if ( hasProductInstall && !hasRequestedVersion ) {
|
||||||
|
// DO NOT MODIFY THE FOLLOWING FOUR LINES
|
||||||
|
// Location visited after installation is complete if installation is
|
||||||
|
// required
|
||||||
|
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
|
||||||
|
var MMredirectURL = window.location;
|
||||||
|
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
|
||||||
|
var MMdoctitle = document.title;
|
||||||
|
|
||||||
|
AC_FL_RunContent(
|
||||||
|
"src", "playerProductInstall",
|
||||||
|
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
|
||||||
|
"width", "600",
|
||||||
|
"height", "800",
|
||||||
|
"align", "middle",
|
||||||
|
"id", "CoAuthor",
|
||||||
|
"quality", "high",
|
||||||
|
"bgcolor", "#ffffff",
|
||||||
|
"name", "CoAuthor",
|
||||||
|
"allowScriptAccess","sameDomain",
|
||||||
|
"type", "application/x-shockwave-flash",
|
||||||
|
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||||
|
);
|
||||||
|
} else if (hasRequestedVersion) {
|
||||||
|
// if we've detected an acceptable version
|
||||||
|
// embed the Flash Content SWF when all tests are passed
|
||||||
|
AC_FL_RunContent(
|
||||||
|
"src", swfLink,
|
||||||
|
"flashVars", "graphmlUrl=" + egoCoAuthorshipDataURL,
|
||||||
|
"width", "600",
|
||||||
|
"height", "800",
|
||||||
|
"align", "middle",
|
||||||
|
"id", "CoAuthor",
|
||||||
|
"quality", "high",
|
||||||
|
"bgcolor", "#ffffff",
|
||||||
|
"name", "CoAuthor",
|
||||||
|
"allowScriptAccess","sameDomain",
|
||||||
|
"type", "application/x-shockwave-flash",
|
||||||
|
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||||
|
);
|
||||||
|
} else { // flash is too old or we can't detect the plugin
|
||||||
|
var alternateContent = 'Alternate HTML content should be placed here. '
|
||||||
|
+ 'This content requires the Adobe Flash Player. '
|
||||||
|
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
|
||||||
|
document.write(alternateContent); // insert non-flash content
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
318
webapp/web/js/visualization/personlevel/person_level.js
Normal file
318
webapp/web/js/visualization/personlevel/person_level.js
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
function getWellFormedURLs(given_uri, type) {
|
||||||
|
|
||||||
|
// general best practice is to put javascript code inside document.ready
|
||||||
|
// but in this case when i do that the function does not get called
|
||||||
|
// properly.
|
||||||
|
// so removing it for now.
|
||||||
|
|
||||||
|
// $(document).ready(function() {
|
||||||
|
|
||||||
|
var finalURL;
|
||||||
|
|
||||||
|
if (type == "coauthorship") {
|
||||||
|
|
||||||
|
finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "PERSON_LEVEL_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
// console.log("COA - " + data);
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
|
||||||
|
} else if (type == "profile") {
|
||||||
|
|
||||||
|
finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "PROFILE_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
} else if (type == "image") {
|
||||||
|
|
||||||
|
finalURL = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "IMAGE_URL", uri: given_uri}),
|
||||||
|
dataType: "text",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return finalURL;
|
||||||
|
|
||||||
|
} else if (type == "profile_info") {
|
||||||
|
|
||||||
|
var profileInfoJSON = $.ajax({
|
||||||
|
url: contextPath + "/admin/visQuery",
|
||||||
|
data: ({vis: "utilities", vis_mode: "PROFILE_INFO", uri: given_uri}),
|
||||||
|
dataType: "json",
|
||||||
|
async: false,
|
||||||
|
success:function(data){
|
||||||
|
}
|
||||||
|
}).responseText;
|
||||||
|
|
||||||
|
return profileInfoJSON;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.image = function(src, successFunc, failureFunc){
|
||||||
|
return this.each(function(){
|
||||||
|
var profileImage = new Image();
|
||||||
|
profileImage.src = src;
|
||||||
|
profileImage.width = 90;
|
||||||
|
profileImage.onerror = failureFunc;
|
||||||
|
profileImage.onload = successFunc;
|
||||||
|
|
||||||
|
|
||||||
|
return profileImage;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function setProfileImage(imageContainerID, rawPath, contextPath) {
|
||||||
|
|
||||||
|
|
||||||
|
if (imageContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageLink = contextPath + rawPath;
|
||||||
|
|
||||||
|
var imageContainer = $("#" + imageContainerID);
|
||||||
|
imageContainer.image(imageLink,
|
||||||
|
function(){
|
||||||
|
imageContainer.empty().append(this);
|
||||||
|
},
|
||||||
|
function(){
|
||||||
|
// For performing any action on failure to
|
||||||
|
// find the image.
|
||||||
|
imageContainer.empty();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileMoniker(monikerContainerID, moniker, doEllipsis) {
|
||||||
|
|
||||||
|
if (monikerContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var finalDisplayMoniker;
|
||||||
|
|
||||||
|
if (moniker.length > 30 && doEllipsis) {
|
||||||
|
|
||||||
|
finalDisplayMoniker = moniker.substr(0,30) + "...";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
finalDisplayMoniker = moniker;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#" + monikerContainerID).empty().text(finalDisplayMoniker);
|
||||||
|
$("#" + monikerContainerID).attr('title', moniker);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProfileName(nameContainerID, name) {
|
||||||
|
|
||||||
|
if (nameContainerID == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#" + nameContainerID).empty().text(name);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function processProfileInformation(nameContainerID,
|
||||||
|
monikerContainerID,
|
||||||
|
imageContainerID,
|
||||||
|
profileInfoJSON,
|
||||||
|
doMonikerEllipsis) {
|
||||||
|
|
||||||
|
|
||||||
|
var name, imageRawPath, imageContextPath, moniker;
|
||||||
|
|
||||||
|
$.each(profileInfoJSON, function(key, set){
|
||||||
|
|
||||||
|
if (key.search(/imageThumb/i) > -1) {
|
||||||
|
|
||||||
|
imageRawPath = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/imageContextPath/i) > -1) {
|
||||||
|
|
||||||
|
imageContextPath = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/moniker/i) > -1) {
|
||||||
|
|
||||||
|
moniker = set[0];
|
||||||
|
|
||||||
|
} else if (key.search(/label/i) > -1) {
|
||||||
|
|
||||||
|
name = set[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
setProfileName(nameContainerID, name);
|
||||||
|
setProfileMoniker(monikerContainerID, moniker, doMonikerEllipsis);
|
||||||
|
setProfileImage(imageContainerID, imageRawPath, imageContextPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function visLoaded(nodes){
|
||||||
|
|
||||||
|
var jsonedNodes = jQuery.parseJSON(nodes);
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
createTable("coauthorships_table", "coauth_table_container", jsonedNodes.slice(1));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTable(tableID, tableContainer, tableData) {
|
||||||
|
|
||||||
|
var table = $('<table>');
|
||||||
|
table.attr('id', tableID);
|
||||||
|
|
||||||
|
table.append($('<caption>').html("Co-Authors <a href=\"" + egoCoAuthorsListDataFileURL + "\">(.CSV File)</a>"));
|
||||||
|
|
||||||
|
var header = $('<thead>');
|
||||||
|
|
||||||
|
var row = $('<tr>');
|
||||||
|
|
||||||
|
var authorTH = $('<th>');
|
||||||
|
authorTH.html("Author");
|
||||||
|
row.append(authorTH);
|
||||||
|
|
||||||
|
row.append($('<th>').html("Publications with <br />" + $('#ego_label').text()));
|
||||||
|
|
||||||
|
header.append(row);
|
||||||
|
|
||||||
|
table.append(header);
|
||||||
|
|
||||||
|
$.each(tableData, function(i, item){
|
||||||
|
|
||||||
|
var row = $('<tr>');
|
||||||
|
|
||||||
|
row.append($('<td>').html(item.name));
|
||||||
|
row.append($('<td>').html(item.number_of_authored_works));
|
||||||
|
|
||||||
|
table.append(row);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
table.prependTo('#' + tableContainer);
|
||||||
|
$('#' + tableContainer + " #loadingData").remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function nodeClickedJS(json){
|
||||||
|
|
||||||
|
var obj = jQuery.parseJSON(json);
|
||||||
|
|
||||||
|
$("#dataPanel").attr("style","visibility:visible");
|
||||||
|
$("#authorName").empty().append(obj.name);
|
||||||
|
$("#works").empty().append(obj.number_of_authored_works);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here obj.url points to the uri of that individual
|
||||||
|
*/
|
||||||
|
if(obj.url){
|
||||||
|
$("#profileUrl").attr("href", getWellFormedURLs(obj.url, "profile"));
|
||||||
|
$("#coAuthorshipVisUrl").attr("href", getWellFormedURLs(obj.url, "coauthorship"));
|
||||||
|
processProfileInformation("",
|
||||||
|
"profileMoniker",
|
||||||
|
"profileImage",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs(obj.url, "profile_info")),
|
||||||
|
true);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
$("#profileUrl").attr("href","#");
|
||||||
|
$("#coAuthorshipVisUrl").attr("href","#");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#coAuthorName").empty().append(obj.name);
|
||||||
|
|
||||||
|
$("#coAuthors").empty().append(obj.num_coauthors);
|
||||||
|
|
||||||
|
$("#firstPublication").empty().append(obj.earliest_publication);
|
||||||
|
(obj.earliest_publication)?$("#fPub").attr("style","visibility:visible"):$("#fPub").attr("style","visibility:hidden");
|
||||||
|
$("#lastPublication").empty().append(obj.latest_publication);
|
||||||
|
(obj.latest_publication)?$("#lPub").attr("style","visibility:visible"):$("#lPub").attr("style","visibility:hidden");
|
||||||
|
|
||||||
|
// obj.url:the url parameter for node
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCoAuthorshipVisualization() {
|
||||||
|
|
||||||
|
// Version check for the Flash Player that has the ability to start Player
|
||||||
|
// Product Install (6.0r65)
|
||||||
|
var hasProductInstall = DetectFlashVer(6, 0, 65);
|
||||||
|
|
||||||
|
// Version check based upon the values defined in globals
|
||||||
|
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
|
||||||
|
|
||||||
|
if ( hasProductInstall && !hasRequestedVersion ) {
|
||||||
|
// DO NOT MODIFY THE FOLLOWING FOUR LINES
|
||||||
|
// Location visited after installation is complete if installation is
|
||||||
|
// required
|
||||||
|
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
|
||||||
|
var MMredirectURL = window.location;
|
||||||
|
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
|
||||||
|
var MMdoctitle = document.title;
|
||||||
|
|
||||||
|
AC_FL_RunContent(
|
||||||
|
"src", "playerProductInstall",
|
||||||
|
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
|
||||||
|
"width", "600",
|
||||||
|
"height", "840",
|
||||||
|
"align", "middle",
|
||||||
|
"id", "CoAuthor",
|
||||||
|
"quality", "high",
|
||||||
|
"bgcolor", "#ffffff",
|
||||||
|
"name", "CoAuthor",
|
||||||
|
"allowScriptAccess","sameDomain",
|
||||||
|
"type", "application/x-shockwave-flash",
|
||||||
|
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||||
|
);
|
||||||
|
} else if (hasRequestedVersion) {
|
||||||
|
// if we've detected an acceptable version
|
||||||
|
// embed the Flash Content SWF when all tests are passed
|
||||||
|
AC_FL_RunContent(
|
||||||
|
"src", swfLink,
|
||||||
|
"flashVars", "graphmlUrl=" + egoCoAuthorshipDataFeederURL,
|
||||||
|
"width", "600",
|
||||||
|
"height", "790",
|
||||||
|
"align", "top",
|
||||||
|
"id", "CoAuthor",
|
||||||
|
"quality", "high",
|
||||||
|
"bgcolor", "#ffffff",
|
||||||
|
"name", "CoAuthor",
|
||||||
|
"allowScriptAccess","sameDomain",
|
||||||
|
"type", "application/x-shockwave-flash",
|
||||||
|
"pluginspage", "http://www.adobe.com/go/getflashplayer"
|
||||||
|
);
|
||||||
|
} else { // flash is too old or we can't detect the plugin
|
||||||
|
var alternateContent = 'Alternate HTML content should be placed here. '
|
||||||
|
+ 'This content requires the Adobe Flash Player. '
|
||||||
|
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
|
||||||
|
document.write(alternateContent); // insert non-flash content
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -122,6 +122,10 @@ if (VitroRequestPrep.isSelfEditing(request) || LoginFormBean.loggedIn(request, L
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</div> <!-- end labelAndMoniker -->
|
</div> <!-- end labelAndMoniker -->
|
||||||
|
|
||||||
|
<!-- START Sparkline Visualization -->
|
||||||
|
<jsp:include page="sparklineVisualization.jsp"/>
|
||||||
|
<!-- END Sparkline Visualization -->
|
||||||
|
|
||||||
<%-- Links --%>
|
<%-- Links --%>
|
||||||
<c:if test="${ showEdits || !empty entity.url || !empty entity.linksList }">
|
<c:if test="${ showEdits || !empty entity.url || !empty entity.linksList }">
|
||||||
<div id="dprop-vitro-links" class="propsItem ${editingClass}">
|
<div id="dprop-vitro-links" class="propsItem ${editingClass}">
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
<c:url var="vitroControls" value="/js/controls.js"/>
|
<c:url var="vitroControls" value="/js/controls.js"/>
|
||||||
<c:url var="jqueryForm" value="/js/jquery_plugins/jquery.form.js"/>
|
<c:url var="jqueryForm" value="/js/jquery_plugins/jquery.form.js"/>
|
||||||
<c:url var="tinyMCE" value="/js/tiny_mce/tiny_mce.js"/>
|
<c:url var="tinyMCE" value="/js/tiny_mce/tiny_mce.js"/>
|
||||||
|
<c:url var="googleVisualizationAPI" value="http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D"/>
|
||||||
|
|
||||||
<script type="text/javascript" src="${jquery}"></script>
|
<script type="text/javascript" src="${jquery}"></script>
|
||||||
<script type="text/javascript" src="${getURLParam}"></script>
|
<script type="text/javascript" src="${getURLParam}"></script>
|
||||||
|
@ -34,3 +35,4 @@
|
||||||
<script type="text/javascript" src="${jqueryForm}"></script>
|
<script type="text/javascript" src="${jqueryForm}"></script>
|
||||||
<script type="text/javascript" src="${tinyMCE}"></script>
|
<script type="text/javascript" src="${tinyMCE}"></script>
|
||||||
<script type="text/javascript" src="${vitroControls}"></script>
|
<script type="text/javascript" src="${vitroControls}"></script>
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
||||||
|
|
156
webapp/web/templates/entity/sparklineVisualization.jsp
Normal file
156
webapp/web/templates/entity/sparklineVisualization.jsp
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean"%>
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.Individual" %>
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.beans.VClass" %>
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.flags.PortalFlagChoices" %>
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
|
||||||
|
<%@ page errorPage="/error.jsp"%>
|
||||||
|
<% /***********************************************
|
||||||
|
Displays the little group of things at the bottom of the page
|
||||||
|
for administrators and editors.
|
||||||
|
|
||||||
|
request.attributes:
|
||||||
|
an Entity object with the name "entity"
|
||||||
|
|
||||||
|
|
||||||
|
request.parameters:
|
||||||
|
None, should only work with requestScope attributes for security reasons.
|
||||||
|
|
||||||
|
Consider sticking < % = MiscWebUtils.getReqInfo(request) % > in the html output
|
||||||
|
for debugging info.
|
||||||
|
|
||||||
|
bdc34 2006-01-22 created
|
||||||
|
**********************************************/
|
||||||
|
Individual entity = (Individual)request.getAttribute("entity");
|
||||||
|
boolean displayVisualization = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (entity == null){
|
||||||
|
String e = "sparklineVisuzalition.jsp expects that request attribute 'entity' be set to the Entity object to display.";
|
||||||
|
displayVisualization = false;
|
||||||
|
throw new JspException(e);
|
||||||
|
} else {
|
||||||
|
for (VClass currClass : entity.getVClasses()) {
|
||||||
|
//System.out.println(">> " + currClass.getName());
|
||||||
|
if (currClass.getName().equalsIgnoreCase("Person")) {
|
||||||
|
displayVisualization = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("visualization is supposed to be displayed? > " + displayVisualization);
|
||||||
|
if (displayVisualization) {
|
||||||
|
|
||||||
|
%>
|
||||||
|
|
||||||
|
|
||||||
|
<c:set var='portalBean' value='${currentPortal}'/>
|
||||||
|
<c:set var="themeDir"><c:out value="${portalBean.themeDir}" /></c:set>
|
||||||
|
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||||
|
|
||||||
|
<!-- START Visualization Code -->
|
||||||
|
<c:url var="visualizationURL" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="dynamic"/>
|
||||||
|
<c:param name="container" value="vis_container"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="short"/>
|
||||||
|
<c:param name="uri" value="${entity.URI}"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<%-- PDF Visualization URL
|
||||||
|
|
||||||
|
For now we have disabled this.
|
||||||
|
|
||||||
|
<c:url var="pdfURL" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="pdf"/>
|
||||||
|
<c:param name="container" value="vis_container"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="full"/>
|
||||||
|
<c:param name="uri" value="${entity.URI}"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
--%>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
#vis_container {
|
||||||
|
cursor:pointer;
|
||||||
|
/*height:36px;
|
||||||
|
margin-left:24%;
|
||||||
|
margin-top:-2%;
|
||||||
|
position:absolute;*/
|
||||||
|
/*width:380px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
function renderVisualization(visualizationURL) {
|
||||||
|
|
||||||
|
$("#vis_container").empty().html('<img src="${loadingImageLink}" />');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: visualizationURL,
|
||||||
|
dataType: "html",
|
||||||
|
success:function(data){
|
||||||
|
$("#vis_container").html(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderVisualization('${visualizationURL}');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
<div id="vis_container">
|
||||||
|
${entity.URI}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--[if IE]>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
#vis_container a{
|
||||||
|
padding-bottom:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vis_link a{
|
||||||
|
padding:10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<%--
|
||||||
|
|
||||||
|
For now we have disabled PDF report vis.
|
||||||
|
|
||||||
|
<div id="pdf_url">
|
||||||
|
This is the <a href="${pdfURL}">link</a> to PDF report.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
--%>
|
||||||
|
|
||||||
|
<!-- END Visualization Code -->
|
||||||
|
|
||||||
|
<%
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
%>
|
46
webapp/web/templates/page/blankPage.jsp
Normal file
46
webapp/web/templates/page/blankPage.jsp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
|
||||||
|
<% /***********************************************
|
||||||
|
Display a single Page in the most basic fashion.
|
||||||
|
The html <HEAD> is generated followed by the banners and menu.
|
||||||
|
After that the result of the jsp in the attribute bodyJsp is inserted.
|
||||||
|
Finally comes the footer.
|
||||||
|
|
||||||
|
request.attributes:
|
||||||
|
"bodyJsp" - jsp of the body of this page.
|
||||||
|
"title" - title of page
|
||||||
|
"css" - optional additional css for page
|
||||||
|
"scripts" - optional name of file containing <script> elements to be included in the page
|
||||||
|
"bodyAttr" - optional attributes for the <body> tag, e.g. 'onload': use leading space
|
||||||
|
"portalBean" - PortalBean object for request.
|
||||||
|
|
||||||
|
Consider sticking < % = MiscWebUtils.getReqInfo(request) % > in the html output
|
||||||
|
for debugging info.
|
||||||
|
|
||||||
|
bdc34 2006-02-03 created
|
||||||
|
**********************************************/
|
||||||
|
/*
|
||||||
|
String e = "";
|
||||||
|
if (request.getAttribute("bodyJsp") == null){
|
||||||
|
e+="basicPage.jsp expects that request parameter 'bodyJsp' be set to the jsp to display as the page body.\n";
|
||||||
|
}
|
||||||
|
if (request.getAttribute("title") == null){
|
||||||
|
e+="basicPage.jsp expects that request parameter 'title' be set to the title to use for page.\n";
|
||||||
|
}
|
||||||
|
if (request.getAttribute("css") == null){
|
||||||
|
e+="basicPage.jsp expects that request parameter 'css' be set to css to include in page.\n";
|
||||||
|
}
|
||||||
|
if( request.getAttribute("portalBean") == null){
|
||||||
|
e+="basicPage.jsp expects that request attribute 'portalBean' be set.\n";
|
||||||
|
}
|
||||||
|
if( request.getAttribute("appBean") == null){
|
||||||
|
e+="basicPage.jsp expects that request attribute 'appBean' be set.\n";
|
||||||
|
}
|
||||||
|
if( e.length() > 0 ){
|
||||||
|
throw new JspException(e);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
%>
|
||||||
|
|
||||||
|
<c:set var="bodyJsp"><c:out value="${requestScope.bodyJsp}" default="/debug.jsp"/></c:set>
|
||||||
|
<c:import url="${bodyJsp}"/>
|
7
webapp/web/templates/visualization/ajax_vis_content.jsp
Normal file
7
webapp/web/templates/visualization/ajax_vis_content.jsp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
|
||||||
|
<c:set var='sparkline' value='${requestScope.sparklineVO}'/>
|
||||||
|
|
||||||
|
${sparkline.sparklineContent}
|
||||||
|
${sparkline.sparklineContext}
|
277
webapp/web/templates/visualization/co_authorship.jsp
Normal file
277
webapp/web/templates/visualization/co_authorship.jsp
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
<%@ 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="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="egoCoAuthorshipDataURL" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="coauthorship" />
|
||||||
|
<c:param name="render_mode" value="data" />
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||||
|
<c:param name="labelField" value="name" />
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="egoSparklineVisURL" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="dynamic"/>
|
||||||
|
<c:param name="container" value="ego_sparkline"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="full"/>
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="jquery" value="/js/jquery.js" />
|
||||||
|
<c:url var="adobeFlashDetector" value="/js/visualization/coauthorship/AC_OETags.js" />
|
||||||
|
<c:url var="coAuthorShipJavaScript" value="/js/visualization/coauthorship/co_authorship.js" />
|
||||||
|
<c:url var="googleVisualizationAPI" value="http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D"/>
|
||||||
|
<c:url var="style" value="/${themeDir}css/visualization/coauthorship/style.css" />
|
||||||
|
<c:url var="noImage" value="/${themeDir}site_icons/visualization/coauthorship/no_image.png" />
|
||||||
|
<c:url var="swfLink" value="/${themeDir}site_icons/visualization/coauthorship/CoAuthor.swf" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||||
|
|
||||||
|
|
||||||
|
<title>Co-Authorship Visualization</title>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${adobeFlashDetector}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Globals
|
||||||
|
// Major version of Flash required
|
||||||
|
var requiredMajorVersion = 10;
|
||||||
|
// Minor version of Flash required
|
||||||
|
var requiredMinorVersion = 0;
|
||||||
|
// Minor version of Flash required
|
||||||
|
var requiredRevision = 0;
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
var swfLink = "${swfLink}";
|
||||||
|
var egoCoAuthorshipDataURL = "${egoCoAuthorshipDataURL}";
|
||||||
|
var contextPath = "${contextPath}";
|
||||||
|
|
||||||
|
|
||||||
|
// -->
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${jquery}"></script>
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
||||||
|
<link href="${style}" rel="stylesheet" type="text/css" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${coAuthorShipJavaScript}"></script>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
#ego_sparkline {
|
||||||
|
cursor:pointer;
|
||||||
|
height:36px;
|
||||||
|
margin-left:24%;
|
||||||
|
/*margin-top:-18%;*/
|
||||||
|
position:absolute;
|
||||||
|
width:471px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="body">
|
||||||
|
|
||||||
|
|
||||||
|
<%-- Label --%>
|
||||||
|
<div class="datatypePropertyValue">
|
||||||
|
<div class="statementWrap">
|
||||||
|
<span id="ego_label"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%-- Moniker--%>
|
||||||
|
<div class="datatypeProperties">
|
||||||
|
<div class="datatypePropertyValue">
|
||||||
|
<div class="statementWrap">
|
||||||
|
<span id="ego_moniker" class="moniker"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%-- Image --%>
|
||||||
|
<div class="datatypeProperties">
|
||||||
|
<div class="datatypePropertyValue">
|
||||||
|
<div id="ego_profile-image" class="statementWrap thumbnail">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%-- Sparkline --%>
|
||||||
|
<div class="datatypeProperties">
|
||||||
|
<div class="datatypePropertyValue">
|
||||||
|
<div id="ego_sparkline">
|
||||||
|
|
||||||
|
${requestScope.egoURIParam}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="topShadow"></div>
|
||||||
|
<div id="bodyPannel" style="height: 900px;"><br class="spacer" />
|
||||||
|
<div id="visPanel" style="float: left; width: 610px;">
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
renderCoAuthorshipVisualization();
|
||||||
|
|
||||||
|
//-->
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="dataPanel" style="float: left; width: 150px;"><br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div id="newsLetter" style="visibility: hidden">
|
||||||
|
<span class="nltop"></span>
|
||||||
|
<div class="middle" id="nodeData">
|
||||||
|
<div id="profileImage"></div>
|
||||||
|
<div class="bold"><strong><span id="authorName"> </span></strong></div>
|
||||||
|
<div class="italicize"><span id="profileMoniker"></span></div>
|
||||||
|
<div class="works"><span class="numbers" style="width: 40px;"
|
||||||
|
id="works">6</span> <span class="title">Works</span></div>
|
||||||
|
<div class="works"><span class="numbers" style="width: 40px;"
|
||||||
|
id="coAuthors">78</span> <span>Co-author(s)</span></div>
|
||||||
|
<br />
|
||||||
|
<div id="firstPublication"><span></span> <span>First
|
||||||
|
Publication</span></div>
|
||||||
|
<div id="lastPublication"><span></span> Last Publication</div>
|
||||||
|
<br />
|
||||||
|
<div><a href="#" id="profileUrl">VIVO profile</a></div>
|
||||||
|
<br />
|
||||||
|
<div><a href="#" id="coAuthorshipVisUrl">Co-author network of <span id="coAuthorName"></span></a></div>
|
||||||
|
</div>
|
||||||
|
<br class="spacer"> <span class="nlbottom"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Download co-authorship newtwork as <a href="/vivo1/admin/visQuery?uri=http%3A%2F%2Fvivo.library.cornell.edu%2Fns%2F0.1%23individual5748&vis=person_pub_count&render_mode=data">.graphml</a> file.
|
||||||
|
|
||||||
|
<div id="bottomShadow"></div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br class="spacer" />
|
||||||
|
|
||||||
|
<table id="publications_data_table">
|
||||||
|
<caption>Publications per year</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Publications</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>2004</td>
|
||||||
|
<td>4</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>2005</td>
|
||||||
|
<td>2</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>11</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Unknown</td>
|
||||||
|
<td>1</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
Download data as <a href="/vivo1/admin/visQuery?uri=http%3A%2F%2Fvivo.library.cornell.edu%2Fns%2F0.1%23individual5748&vis=person_pub_count&render_mode=data">.csv</a> file.
|
||||||
|
|
||||||
|
<table id="coauthorships_data_table">
|
||||||
|
<caption>Co - Authorhips</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Publications</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>2004</td>
|
||||||
|
<td>4</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>2005</td>
|
||||||
|
<td>2</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>11</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Unknown</td>
|
||||||
|
<td>1</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
processProfileInformation("ego_label",
|
||||||
|
"ego_moniker",
|
||||||
|
"ego_profile-image",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs("${requestScope.egoURIParam}", "profile_info")));
|
||||||
|
|
||||||
|
renderSparklineVisualization("${egoSparklineVisURL}");
|
||||||
|
|
||||||
|
|
||||||
|
var obj = jQuery.parseJSON('{"name":"John"}');
|
||||||
|
//console.log(obj)
|
||||||
|
|
||||||
|
var obj = jQuery.parseJSON('{"imageOffset2":["sup"],"A":["2001","2002","2003","2090","Unknown"],"B":["2001","2002","2003","2090","Unknown"],"C":["2001","2002","2003","2090","Unknown"],"imageOffset":["2090","2002","2003","2001"]}');
|
||||||
|
//console.log(obj)
|
||||||
|
|
||||||
|
$.each(obj, function(i, item){
|
||||||
|
//console.log("i - " + i + " item - " + item);
|
||||||
|
$.each(item, function(index, vals) {
|
||||||
|
//console.log(index + " - val - " + vals);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
407
webapp/web/templates/visualization/dummy_vis_client.jsp
Normal file
407
webapp/web/templates/visualization/dummy_vis_client.jsp
Normal file
|
@ -0,0 +1,407 @@
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
|
||||||
|
|
||||||
|
<c:set var="portal" value="${requestScope.portalBean}"/>
|
||||||
|
<c:set var="themeDir"><c:out value="${portal.themeDir}" /></c:set>
|
||||||
|
|
||||||
|
<c:url var="staticHref" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="standalone"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5156"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="staticHref2" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="short"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5611"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="staticHref_d" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="dynamic"/>
|
||||||
|
<c:param name="container" value="ajax_recipient"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="short"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5156"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="staticHref2_d" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="dynamic"/>
|
||||||
|
<c:param name="container" value="ajax_recipient"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="full"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5611"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="staticHref3" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="vis_mode" value="short"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5748"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="staticHref3_d" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="dynamic"/>
|
||||||
|
<c:param name="vis" value="person_pub_count"/>
|
||||||
|
<c:param name="container" value="ajax_recipient"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual22919"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="collegeCSV" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="college_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5249"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="collegeCSV2" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="college_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual134"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="collegeCSV3" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="college_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual249"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="collegeCSV4" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="college_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual250"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="collegeCSV5" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="college_pub_count"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="vis_mode" value="wth"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual192"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship1Data" value="/admin/visQuery">
|
||||||
|
<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#individual5748"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship2Data" value="/admin/visQuery">
|
||||||
|
<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#individual5156"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship3Data" value="/admin/visQuery">
|
||||||
|
<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#individual5611"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="coAuthorship4Data" value="/admin/visQuery">
|
||||||
|
<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#individual5412"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship1" value="/admin/visQuery">
|
||||||
|
<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#individual5748"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship2" value="/admin/visQuery">
|
||||||
|
<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#individual5156"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship3" value="/admin/visQuery">
|
||||||
|
<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#individual5611"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship4" value="/admin/visQuery">
|
||||||
|
<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#individual5412"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="coAuthorship5" value="/admin/visQuery">
|
||||||
|
<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#individual5714"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship5Data" value="/admin/visQuery">
|
||||||
|
<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#individual5714"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="coAuthorship6" value="/admin/visQuery">
|
||||||
|
<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#individual240"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship6Data" value="/admin/visQuery">
|
||||||
|
<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#individual240"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship7" value="/admin/visQuery">
|
||||||
|
<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#individual37"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship7Data" value="/admin/visQuery">
|
||||||
|
<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#individual37"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship8" value="/admin/visQuery">
|
||||||
|
<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#individual5355"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship8Data" value="/admin/visQuery">
|
||||||
|
<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#individual5355"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship9" value="/admin/visQuery">
|
||||||
|
<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#individual5734"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="coAuthorship9Data" value="/admin/visQuery">
|
||||||
|
<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#individual5734"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship10" value="/admin/visQuery">
|
||||||
|
<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:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorship10Data" value="/admin/visQuery">
|
||||||
|
<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:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorshipSparklineData" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="coauthorship"/>
|
||||||
|
<c:param name="vis_mode" value="sparkline"/>
|
||||||
|
<c:param name="render_mode" value="data"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5748"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="personLevel1" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_level"/>
|
||||||
|
<c:param name="render_mode" value="standalone"/>
|
||||||
|
<c:param name="container" value="ego_sparkline"/>
|
||||||
|
<c:param name="uri" value="http://vivo.library.cornell.edu/ns/0.1#individual5748"/>
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.get_vis {
|
||||||
|
background-color:Yellow;
|
||||||
|
color:blue;
|
||||||
|
cursor:pointer;
|
||||||
|
height:36px;
|
||||||
|
width:225px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
<!--
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
function renderVisualization(visualizationURL) {
|
||||||
|
|
||||||
|
$("#ajax_recipient").empty().html('<img src="${loadingImageLink}" />');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: visualizationURL,
|
||||||
|
dataType: "html",
|
||||||
|
success:function(data){
|
||||||
|
$("#ajax_recipient").html(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#ajax_activator").click(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: '${staticHref3_d}',
|
||||||
|
dataType: "html",
|
||||||
|
success:function(data){
|
||||||
|
|
||||||
|
|
||||||
|
$("#ajax_recipient").text(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#ajax_activator_1").click(function() {
|
||||||
|
|
||||||
|
renderVisualization('${staticHref_d}');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#ajax_activator_2").click(function() {
|
||||||
|
|
||||||
|
renderVisualization('${staticHref2_d}');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#ajax_activator_3").click(function() {
|
||||||
|
|
||||||
|
renderVisualization('${staticHref3_d}');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="staticPageBackground">
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
#test-bed {
|
||||||
|
background-color:red;
|
||||||
|
color:white;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h1 id="test-bed">Visualization Testbed (Not to be seen by eventual end users)</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a href='<c:out value="${coAuthorship1}"/>'>vis link for coauthorship -> "Erb, Hollis Nancy"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship1Data}"/>'>Data</a>
|
||||||
|
<a href='<c:out value="${personLevel1}"/>'>Person Level</a>
|
||||||
|
<a href='<c:out value="${coAuthorshipSparklineData}"/>'>Unique Coauthors CSV Data</a>
|
||||||
|
<br />
|
||||||
|
<a href='<c:out value="${coAuthorship2}"/>'>vis link for coauthorship -> "Not Working" {"Crane, Brian"}</a>
|
||||||
|
<a href='<c:out value="${coAuthorship2Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship3}"/>'>vis link for coauthorship -> "Merwin, Ian A"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship3Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship4}"/>'>vis link for coauthorship -> "Thies, Janice"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship4Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship5}"/>'>vis link for coauthorship -> "Not Working"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship5Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship6}"/>'>vis link for coauthorship -> "Boor, Kathryn Jean"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship6Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship7}"/>'>vis link for coauthorship -> "Wiedmann, Martin"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship7Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship8}"/>'>vis link for coauthorship -> "Not Working"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship8Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship9}"/>'>vis link for coauthorship -> "Not Working"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship9Data}"/>'>Data</a><br />
|
||||||
|
<a href='<c:out value="${coAuthorship10}"/>'>vis link for coauthorship -> "Not Working"</a>
|
||||||
|
<a href='<c:out value="${coAuthorship10Data}"/>'>Data</a><br />
|
||||||
|
|
||||||
|
<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 />
|
||||||
|
<a href='<c:out value="${collegeCSV4}"/>'>vis data query for college -> "College of Engineering"</a><br />
|
||||||
|
<a href='<c:out value="${collegeCSV5}"/>'>vis data query for college -> "Joan and Sanford I. Weill Medical College"</a><br />
|
||||||
|
|
||||||
|
<a href='<c:out value="${staticHref}"/>'>vis query for person -> "Crane, Brian"</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="ajax_activator_1" class="get_vis">
|
||||||
|
Click to render this Person's vis via AJAX.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<a href='<c:out value="${staticHref2}"/>'>vis query for person -> "Merwin, Ian A"</a>
|
||||||
|
|
||||||
|
<div id="ajax_activator_2" class="get_vis">
|
||||||
|
Click to render this Person's vis via AJAX.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
<a href='<c:out value="${staticHref3}"/>'>vis query for person -> "Erb, Hollis Nancy"</a>
|
||||||
|
|
||||||
|
<div id="ajax_activator_3" class="get_vis">
|
||||||
|
Click to render this Person's vis via AJAX.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div id="ajax_activator" class="get_vis">
|
||||||
|
AJAX Content in Text (only for research)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="ajax_recipient">
|
||||||
|
vis Content via AJAX here
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
<div id="pub_count_areachart_vis">AREA CHART</div>
|
||||||
|
|
||||||
|
<div id="pub_count_sparkline_vis">pub sparkline chart</div>
|
||||||
|
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
284
webapp/web/templates/visualization/person_level.jsp
Normal file
284
webapp/web/templates/visualization/person_level.jsp
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer"%>
|
||||||
|
|
||||||
|
<%@ 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:url var="visImageContextPath" value="/${themeDir}site_icons/visualization/" />
|
||||||
|
<c:url var="loadingImageLink" value="/${themeDir}site_icons/visualization/ajax-loader.gif"></c:url>
|
||||||
|
|
||||||
|
<c:set var='egoPubSparkline' value='${requestScope.egoPubSparklineVO}' />
|
||||||
|
<c:set var='uniqueCoauthorsSparkline' value='${requestScope.uniqueCoauthorsSparklineVO}' />
|
||||||
|
|
||||||
|
<c:set var='egoPubSparklineContainerID' value='${requestScope.egoPubSparklineContainerID}' />
|
||||||
|
<c:set var='uniqueCoauthorsSparklineVisContainerID' value='${requestScope.uniqueCoauthorsSparklineVisContainerID}' />
|
||||||
|
|
||||||
|
<c:set var='numOfAuthors' value='${requestScope.numOfAuthors}' />
|
||||||
|
<c:set var='numOfCoAuthorShips' value='${requestScope.numOfCoAuthorShips}' />
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="egoSparklineDataURL" value="/admin/visQuery">
|
||||||
|
<c:param name="render_mode" value="data" />
|
||||||
|
<c:param name="vis" value="person_pub_count" />
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="coAuthorshipDownloadFile" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_level" />
|
||||||
|
<c:param name="render_mode" value="data" />
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<div id="body">
|
||||||
|
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
#body h1 {
|
||||||
|
margin:0.0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sparkline_wrapper_table {
|
||||||
|
display: inline;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author_name {
|
||||||
|
color: #13968c;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neutral_author_name {
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author_moniker {
|
||||||
|
color: #9C9C9C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub_headings {
|
||||||
|
color: #121b3c;
|
||||||
|
padding-top: 10px;
|
||||||
|
margin-bottom: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub_headings a {
|
||||||
|
font-size:0.7em;
|
||||||
|
font-weight:normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.sparkline_wrapper_table td, th {
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline_href {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ego_profile {
|
||||||
|
padding-left:10px;
|
||||||
|
padding-top:10px;
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ego_label {
|
||||||
|
font-size:1.1em;
|
||||||
|
/*margin-left:100px;
|
||||||
|
margin-top:9px;
|
||||||
|
position:absolute;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#ego_moniker {
|
||||||
|
/*margin-left:100px;
|
||||||
|
margin-top:27px;
|
||||||
|
position:absolute;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#ego_profile_image {
|
||||||
|
float:left;
|
||||||
|
padding-right: 5px;
|
||||||
|
|
||||||
|
/*width: 100px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#ego_sparkline {
|
||||||
|
cursor:pointer;
|
||||||
|
height:36px;
|
||||||
|
/*
|
||||||
|
margin-left:10px;
|
||||||
|
margin-top:69px;
|
||||||
|
position:absolute;*/
|
||||||
|
width:471px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dataPanel {
|
||||||
|
/*
|
||||||
|
float: left;
|
||||||
|
width: 150px;
|
||||||
|
visibility:hidden;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#coauthorships_table th {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--[if IE]>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
#${egoPubSparklineContainerID},
|
||||||
|
#${uniqueCoauthorsSparklineVisContainerID} {
|
||||||
|
padding-bottom:15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ego_label {
|
||||||
|
margin-left:-3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<div id="ego_profile">
|
||||||
|
|
||||||
|
|
||||||
|
<%-- Image --%>
|
||||||
|
<span id="ego_profile_image"></span>
|
||||||
|
|
||||||
|
<%-- Label --%>
|
||||||
|
<h1><span id="ego_label" class="author_name"></span></h1>
|
||||||
|
|
||||||
|
<%-- Moniker--%>
|
||||||
|
<span id="ego_moniker" class="author_moniker"></span>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
|
<%-- Sparkline --%>
|
||||||
|
<h2 class="sub_headings">General Statistics</h2>
|
||||||
|
<div id="${egoPubSparklineContainerID}">
|
||||||
|
${egoPubSparkline.sparklineContent}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="${uniqueCoauthorsSparklineVisContainerID}">
|
||||||
|
${uniqueCoauthorsSparkline.sparklineContent}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="sub_headings">Co-Author Network
|
||||||
|
<%-- A simple if/else condition --%>
|
||||||
|
<c:choose>
|
||||||
|
<c:when test="${numOfCoAuthorShips > 0 || numOfAuthors > 0}">
|
||||||
|
<a href="${coAuthorshipDownloadFile}">(.GraphML File)</a></h2>
|
||||||
|
</c:when>
|
||||||
|
<c:otherwise>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<c:if test='${numOfAuthors > 0}'>
|
||||||
|
<c:set var='authorsText' value='multi-author' />
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<span id="no_coauthorships">Currently there are no ${authorsText} papers for
|
||||||
|
<span id="no_coauthorships_person" class="author_name">this author</span> in the VIVO database.</span>
|
||||||
|
</c:otherwise>
|
||||||
|
</c:choose>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c:if test='${numOfCoAuthorShips > 0 || numOfAuthors > 0}'>
|
||||||
|
|
||||||
|
<div id="bodyPannel">
|
||||||
|
|
||||||
|
|
||||||
|
<div id="visPanel" style="float: left; width: 600px;">
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
renderCoAuthorshipVisualization();
|
||||||
|
//-->
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="dataPanel">
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<div id="profileImage"></div>
|
||||||
|
|
||||||
|
<div class="bold"><strong><span id="authorName" class="neutral_author_name"> </span></strong></div>
|
||||||
|
|
||||||
|
<div class="italicize"><span id="profileMoniker" class="author_moniker"></span></div>
|
||||||
|
<div><a href="#" id="profileUrl">VIVO profile</a> | <a href="#" id="coAuthorshipVisUrl">Co-author network</a></div>
|
||||||
|
<br />
|
||||||
|
<div class="works"><span class="numbers" style="width: 40px;" id="works"></span> <span class="title">Works</span></div>
|
||||||
|
<div class="works"><span class="numbers" style="width: 40px;" id="coAuthors"></span> <span>Co-author(s)</span></div>
|
||||||
|
|
||||||
|
<div class="works" id="fPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="firstPublication"></span> <span>First Publication</span></div>
|
||||||
|
<div class="works" id="lPub" style="visibility:hidden"><span class="numbers" style="width:40px;" id="lastPublication"></span> <span>Last Publication</span></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<c:if test='${numOfAuthors > 0}'>
|
||||||
|
|
||||||
|
<div class="vis_stats">
|
||||||
|
|
||||||
|
<h2 class="sub_headings">Tables</h2>
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
<p id="publications_table_container" class="datatable">
|
||||||
|
${egoPubSparkline.table}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c:if test='${numOfCoAuthorShips > 0}'>
|
||||||
|
|
||||||
|
<div class="vis-tables">
|
||||||
|
<p id="coauth_table_container" class="datatable"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
<c:if test='${numOfCoAuthorShips > 0}'>
|
||||||
|
$("#coauth_table_container").empty().html('<img id="loadingData" with="auto" src="${loadingImageLink}" />');
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
processProfileInformation("ego_label",
|
||||||
|
"ego_moniker",
|
||||||
|
"ego_profile_image",
|
||||||
|
jQuery.parseJSON(getWellFormedURLs("${requestScope.egoURIParam}", "profile_info")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ($('#profileMoniker').text().length > 30) {
|
||||||
|
//$('#profileMoniker').text($('#profileMoniker').text().substr(0, 30) + "...");
|
||||||
|
console.log("what");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
<c:if test='${numOfCoAuthorShips <= 0}'>
|
||||||
|
|
||||||
|
if ($('#ego_label').text().length > 0) {
|
||||||
|
setProfileName('no_coauthorships_person', $('#ego_label').text());
|
||||||
|
}
|
||||||
|
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<%@ 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="egoCoAuthorshipDataFeederURL" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="coauthorship" />
|
||||||
|
<c:param name="render_mode" value="data" />
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||||
|
<c:param name="labelField" value="name" />
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="egoCoAuthorsListDataFileURL" value="/admin/visQuery">
|
||||||
|
<c:param name="vis" value="person_level" />
|
||||||
|
<c:param name="render_mode" value="data" />
|
||||||
|
<c:param name="vis_mode" value="coauthors" />
|
||||||
|
<c:param name="uri" value="${requestScope.egoURIParam}" />
|
||||||
|
</c:url>
|
||||||
|
|
||||||
|
<c:url var="swfLink" value="/${themeDir}site_icons/visualization/coauthorship/CoAuthor.swf" />
|
||||||
|
|
||||||
|
<c:url var="jquery" value="/js/jquery.js"/>
|
||||||
|
<c:url var="adobeFlashDetector" value="/js/visualization/coauthorship/AC_OETags.js" />
|
||||||
|
<c:url var="googleVisualizationAPI" value="http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D"/>
|
||||||
|
<c:url var="coAuthorShipJavaScript" value="/js/visualization/personlevel/person_level.js" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${adobeFlashDetector}"></script>
|
||||||
|
<script type="text/javascript" src="${jquery}"></script>
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
||||||
|
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
<!--
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Globals
|
||||||
|
// Major version of Flash required
|
||||||
|
var requiredMajorVersion = 10;
|
||||||
|
// Minor version of Flash required
|
||||||
|
var requiredMinorVersion = 0;
|
||||||
|
// Minor version of Flash required
|
||||||
|
var requiredRevision = 0;
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
var swfLink = "${swfLink}";
|
||||||
|
var egoCoAuthorshipDataFeederURL = "${egoCoAuthorshipDataFeederURL}";
|
||||||
|
var egoCoAuthorsListDataFileURL = "${egoCoAuthorsListDataFileURL}";
|
||||||
|
var contextPath = "${contextPath}";
|
||||||
|
|
||||||
|
// -->
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="${coAuthorShipJavaScript}"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<c:url var="coAuthorStyle" value="/${themeDir}css/visualization/personlevel/coauthor_style.css" />
|
||||||
|
<c:url var="pageStyle" value="/${themeDir}css/visualization/personlevel/page.css" />
|
||||||
|
|
||||||
|
<link href="${coAuthorStyle}" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="${pageStyle}" rel="stylesheet" type="text/css" />
|
15
webapp/web/templates/visualization/publication_count.jsp
Normal file
15
webapp/web/templates/visualization/publication_count.jsp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<%@ page import="edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.SparklineVOContainer" %>
|
||||||
|
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
|
||||||
|
|
||||||
|
<c:set var='sparkline' value='${requestScope.sparklineVO}'/>
|
||||||
|
|
||||||
|
<div class="staticPageBackground">
|
||||||
|
|
||||||
|
|
||||||
|
<div id="pub_count_vis_container">
|
||||||
|
${sparkline.sparklineContent}
|
||||||
|
</div>
|
||||||
|
${sparkline.sparklineContext}
|
||||||
|
</div>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
|
||||||
|
|
||||||
|
<div class="staticPageBackground">
|
||||||
|
|
||||||
|
${requestScope.error}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
24
webapp/web/templates/visualization/visualization_scripts.jsp
Normal file
24
webapp/web/templates/visualization/visualization_scripts.jsp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
|
||||||
|
|
||||||
|
<% /***********************************************
|
||||||
|
This file is used to inject <link> and <script> elements
|
||||||
|
into the head element of the generated source of a VITRO
|
||||||
|
page that is being displayed by the entity controller.
|
||||||
|
|
||||||
|
In other words, anything like domain.com/entity?...
|
||||||
|
will have the lines specified here added in the <head>
|
||||||
|
of the page.
|
||||||
|
|
||||||
|
This is a great way to specify JavaScript or CSS files
|
||||||
|
at the entity display level as opposed to globally.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/entity.css"/>" media="screen"/>
|
||||||
|
<script type="text/javascript" src="/js/jquery.js"></script>
|
||||||
|
****************************************************/ %>
|
||||||
|
|
||||||
|
<c:url var="jquery" value="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"/>
|
||||||
|
<c:url var="googleVisualizationAPI" value="http://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22areachart%22%2C%22imagesparkline%22%5D%7D%5D%7D"/>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${jquery}"></script>
|
||||||
|
<script type="text/javascript" src="${googleVisualizationAPI}"></script>
|
|
@ -223,6 +223,18 @@ table#head{
|
||||||
|
|
||||||
#header img{
|
#header img{
|
||||||
margin:0;
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#research_instance {
|
||||||
|
background-color:red;
|
||||||
|
color:white;
|
||||||
|
font-size:1.25em;
|
||||||
|
font-weight:bold;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#research_instance a {
|
||||||
|
color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************** header search form *********************************/
|
/************** header search form *********************************/
|
||||||
|
|
Loading…
Add table
Reference in a new issue