Remove 'legacy' directory (#139)

Partial resolution to: https://jira.lyrasis.org/browse/VIVO-1753

Co-authored-by: Andrew Woods <awoods@duraspace.org>
This commit is contained in:
Andrew Woods 2020-03-24 14:46:53 -04:00 committed by GitHub
parent a16815dc61
commit 8b08a01559
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
89 changed files with 0 additions and 12534 deletions

View file

@ -1,247 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
@charset "UTF-8";
/* CSS Document */
/* Tell the browser to render HTML 5 elements as block */
header,
toc,
hgroup,
section,
nav,
article,
aside,
footer{
display: block;
}
time{
font-weight: normal;
}
html,
body{
margin: 0;
padding: 0;
height: 100%; /* needed for container min-height */
font-family: 'Arimo', "Lucida Sans Unicode","Lucida Grande", Geneva, helvetica, sans-serif;
font-size: 1em;
height: auto !important; /* real browsers */
height: 100%; /* IE6: treaded as min-height*/;
min-height: 100%; /* real browsers */
margin: 0 auto;
}
body{
background: #fff url(../images/header-background.gif) center 0 repeat-x;
}
/* h1,h2,h3,h4,h5,h6 ------> */
h1 {
padding: 8px 0 6px 0;
margin: 0;
font-size: 1.5em;
}
h2 {
padding: 8px 0 6px 0;
margin: 0;
font-size: 1.4em;
color: #2485ae;
}
h2 a{
color: #2485ae;
}
h2 a:link, h2 a:visited{
text-decoration: underline;
}
h2 a:hover, h2 a:active{
text-decoration: none;
}
h3{
padding: 8px 0 6px 0;
margin: 0;
font-size: 1.2em;
color: #2485ae;
}
h4{
padding: 4px 0 4px 0;
margin: 0;
font-size: 1.1em;
color: #000000;
}
h5{
padding: 3px 0 2px 0;
margin: 0;
font-size: 1em;
color: #2485ae;
}
a {
text-decoration: underline;
color: #2485ae;
}
a:visited {
text-decoration: underline;
color: #5e6363;
}
code, pre {
font-size: 1.1em;
}
blockquote {
padding: 5px;
font-size: .9em;
background-color: #EEEEEE;
}
/* HEADER ------> */
#branding {
position: relative;
width: 970px;
height: 114px;
margin: 0 auto;
}
/* BRANDING ------> */
h1.vitro-logo {
position: absolute;
width: 386px;
height: 59px;
top: 28px;
left: 0;
background: url(../images/VITRO-logo.png) 0 0 no-repeat;
}
h1.vitro-logo a {
display: block;
width: 386px;
height: 59px;
}
/* WRAPPER CONTENT------> */
#wrapper-content {
clear: both;
width: 930px;
margin: 0 auto;
background: #fff;
min-height: 550px;
padding: 20px;
}
/* TOC -------> */
ol {
margin: 0 0 10px 10px;
}
/* TABLE --------> */
table {
margin: 10px auto;
border-width: 1px;
border-spacing: 2px;
border-style: outset;
border-color: gray;
border-collapse: collapse;
}
th {
border-width: 1px;
padding: 4px;
border-style: inset;
border-color: white;
background: #2485ae;
color: #FFFFFF;
}
td {
border-width: 1px;
padding: 4px 4px 4px 6px;
border-style: inset;
border-color: #EEEEEE;
-moz-border-radius: 0px 0px 0px 0px;
}
tr {
background: #EEEEEE;
}
tr.odd_row {
background: #FFFFFF;
border-bottom: 1px solid #999999;
font-weight: bold;
}
/* FOOTER------> */
div#footer {
clear: both;
width: 970px;
height: 88px;
margin: 0 auto;
font-size: 0.7em;
color: #4e5051;
background-color: #fff;
}
div#footer p.copyright {
float: left;
padding-top: 50px;
padding-left: 30px;
width: 500px;
}
ul#footer-nav {
float: right;
list-style: none;
width: 300px;
height: 20px;
margin: 0;
padding: 0;
padding-top: 50px;
padding-right: 20px;
}
ul#footer-nav li {
float: left;
display: block;
padding-left: 10px;
padding-right: 10px;
border-right: 1px solid #c9c8c8;
}
ul#footer-nav li:last-child {
border-right: none
}
#footer-nav a {
color: #4e5051
}
#footer-nav a:hover {
color: #09C;
text-decoration: none;
}
a.terms {
color: #09C;
text-decoration: none;
}
a.terms:hover {
color: #4e5051;
text-decoration: none;
}
/* GENERAL STYLE------> */
p{
margin-bottom: 1.3em;
}
/* MISCELLANEOUS ------> */
.blue{
color: #2485ae;
}
.grey{
color: #5e6363;
}
.green{
color: #b2d15a;
}
.displace {
position: absolute;
left: -9999px;
}
ol.roman1 {
list-style-type: upper-roman;
}
ol.roman2 {
list-style-type: lower-roman;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

File diff suppressed because it is too large Load diff

View file

@ -1,25 +0,0 @@
Copyright (c) ${year}, 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.

View file

@ -1,171 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!-- ======================================================================
Build script for the ORNG Shindig webapp.
This can be used on its own, or invoked from the "orng" target of the main build file.
====================================================================== -->
<project name="ORNG-shindig" default="describe">
<!-- =================================
target: describe
================================= -->
<target name="describe" description="--> Describe the targets (this is the default).">
<echo>
all - Runs "clean", then "deploy".
clean - Delete all artifacts so the next build will be from scratch.
deploy - Configure the application and deploy directly into the Tomcat webapps directory.
</echo>
</target>
<!-- =================================
target: all
================================= -->
<target name="all" depends="clean, deploy" description="--> Run 'clean', then 'deploy'" />
<!-- - - - - - - - - - - - - - - - - -
target: properties
- - - - - - - - - - - - - - - - - -->
<target name="properties">
<property name="build.properties.file" location="../webapp/config/build.properties" />
<fail message="You must create a &quot;${build.properties.file}&quot; file.">
<condition>
<not>
<available file="${build.properties.file}" />
</not>
</condition>
</fail>
<property file="${build.properties.file}" />
<fail unless="tomcat.home" message="${build.properties.file} must contain a value for tomcat.home" />
<fail unless="vitro.home" message="${build.properties.file} must contain a value for vitro.home" />
<fail unless="webapp.name" message="${build.properties.file} must contain a value for webapp.name" />
<property name="runtime.properties.file" location="${vitro.home}/runtime.properties" />
<fail message="The runtime properties file &quot;${runtime.properties.file}&quot; does not exist.">
<condition>
<not>
<available file="${runtime.properties.file}" />
</not>
</condition>
</fail>
<property file="${runtime.properties.file}" />
<fail unless="VitroConnection.DataSource.url" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.password" />
<fail unless="VitroConnection.DataSource.driver" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.driver" />
<fail unless="OpenSocial.shindigURL" message="${runtime.properties.file} must contain a value for OpenSocial.shindigURL" />
<fail unless="OpenSocial.tokenService" message="${runtime.properties.file} must contain a value for OpenSocial.tokenService" />
<fail unless="OpenSocial.tokenKeyFile" message="${runtime.properties.file} must contain a value for OpenSocial.tokenKeyFile" />
<fail message="The Vitro home directory &quot;${vitro.home}&quot; does not exist.">
<condition>
<not>
<available file="${vitro.home}" />
</not>
</condition>
</fail>
<fail message="The Vitro home directory &quot;${vitro.home}&quot; is not writable.">
<condition>
<not>
<isfileselected file="${vitro.home}">
<writable />
</isfileselected>
</not>
</condition>
</fail>
<fail message="The Shindig token key file &quot;${OpenSocial.tokenKeyFile}&quot; does not exist.">
<condition>
<not>
<available file="${OpenSocial.tokenKeyFile}" />
</not>
</condition>
</fail>
<!-- build directories -->
<property name="build.dir" location="./build" />
<property name="build.shindig.dir" location="${build.dir}/shindig" />
<!-- deploy directories -->
<property name="shindig.home.dir" location="${vitro.home}/shindig" />
<property name="shindig.config.dir" location="${shindig.home.dir}/conf" />
<property name="tomcat.webapps.dir" location="${tomcat.home}/webapps" />
<!-- the Shindig WAR -->
<property name="shindig.war.original.file" location="./shindigorng.war" />
<property name="shindig.war.deployed.file" location="${tomcat.webapps.dir}/shindigorng.war" />
<property name="shindig.war.deployed.dir" location="${tomcat.webapps.dir}/shindigorng" />
<!-- Shindig properties file -->
<property name="shindig.properties.template.file" location="${basedir}/shindigorng.properties.template" />
<property name="shindig.properties.modified.file" location="${build.shindig.dir}/shindigorng.properties" />
<property name="shindig.properties.deployed.file" location="${shindig.config.dir}/shindigorng.properties" />
<!-- sample-gadgets webapp -->
<property name="sample.webapp.original.dir" location="./sample-gadgets" />
<property name="sample.webapp.deployed.dir" location="${tomcat.webapps.dir}/sample-gadgets" />
</target>
<!-- =================================
target: clean
================================= -->
<target name="clean" depends="properties" description="--> Delete all artifacts">
<delete includeemptydirs="true" failonerror="false">
<fileset dir="${build.shindig.dir}" />
<fileset file="${shindig.war.deployed.file}" />
<fileset dir="${shindig.war.deployed.dir}" />
<fileset dir="${sample.webapp.deployed.dir}" />
</delete>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepare
- - - - - - - - - - - - - - - - - -->
<target name="prepare" depends="properties">
<mkdir dir="${build.dir}" />
<mkdir dir="${build.shindig.dir}" />
<mkdir dir="${shindig.home.dir}" />
<mkdir dir="${shindig.config.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: modifyPropertiesFile
- - - - - - - - - - - - - - - - - -->
<target name="modifyPropertiesFile" depends="properties, prepare">
<copy file="${shindig.properties.template.file}" toFile="${shindig.properties.modified.file}">
<filterset>
<filter token="TOKEN_KEY_FILE" value="${OpenSocial.tokenKeyFile}" />
<filter token="DATA_SOURCE_URL" value="${VitroConnection.DataSource.url}" />
<filter token="DATA_SOURCE_USERNAME" value="${VitroConnection.DataSource.username}" />
<filter token="DATA_SOURCE_PASSWORD" value="${VitroConnection.DataSource.password}" />
<filter token="DATA_SOURCE_DRIVER" value="${VitroConnection.DataSource.driver}" />
<filter token="WEBAPP_NAME" value="${webapp.name}" />
</filterset>
</copy>
</target>
<!-- =================================
target: deploy
================================= -->
<target name="deploy" depends="modifyPropertiesFile" description="--> Deploy the application directly into the Tomcat webapps directory.">
<copy file="${shindig.properties.modified.file}" tofile="${shindig.properties.deployed.file}" />
<copy file="${shindig.war.original.file}" tofile="${shindig.war.deployed.file}" overwrite="true" />
<copy todir="${sample.webapp.deployed.dir}" overwrite="true" >
<fileset dir = "${sample.webapp.original.dir}" />
</copy>
</target>
</project>

View file

@ -1,295 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Websites"
description="Websites">
<Require feature="opensocial-0.9" />
<Require feature="views" />
<Require feature="dynamic-height" />
<Require feature="pubsub" />
<Require feature="osapi" />
</ModulePrefs>
<!-- ==================== START COMBINED VIEWS ==================== -->
<Content type="html" view="default, home, profile">
<![CDATA[<!--HTML-->
<!DOCTYPE html>
<!-- #includes -->
<link rel="stylesheet" href="css/gadget.css" type="text/css" media="screen, projection" >
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<script type="text/javascript" src="js/os.js" ></script>
<style>
.links_title { font-family:Verdana, Arial; font-size: 14px; }
.links_body { font-family:Arial; font-size: 12px; }
.links_credit { font-family:Arial; font-size:10px; }
.links_save_button { height:20px; font-size:11px; }
a, a:visited { color: #0088CC; text-decoration: none; }
a:hover { color: #005580; text-decoration: underline; }
</style>
<script type="text/javascript">
var g_max_links = 5;
var g_oLinks = []; // declare it like this to make json work
// ========================================
function sort_by (field, reverse, primer) {
reverse = (reverse) ? -1 : 1;
return function(a,b) {
a = a[field];
b = b[field];
if (typeof(primer) != 'undefined') {
a = primer(a);
b = primer(b);
}
if (a<b) return reverse * -1;
if (a>b) return reverse * 1;
return 0;
}
}
// ========================================
// ========================================
function deleteArrayItem (array_index) {
g_oLinks.splice(array_index,1);
// write links data to gadget database
osapi.appdata.update({'userId': '@viewer', 'appId': '@app', 'data': {'links' : gadgets.json.stringify(g_oLinks)} }).execute(function(result) {
if (result.error) {
alert("Error " + result.error.code + " writing application data: " + result.error.message + ". Your edited link list was not saved.");
}
});
// show links w/o deleted item even if data write fails - array already spliced
displayData();
}
// ========================================
// ========================================
function readData(callback) {
osapi.appdata.get({'userId': '@owner', 'appId':'@app', 'fields' : ['links']} ).execute(function(result){
// get incoming link data (in json string format)
var viewer = os.osapi.getViewerFromResult(result);
// convert to json object format
g_oLinks = gadgets.json.parse(viewer.links) || [];
// execute the callback;
callback();
}); /* end osapi.appdata.get */
}
// ========================================
// ========================================
function displayData() {
// if links data exists
if (g_oLinks) {
// sort object by link name, case-insensitive, A-Z
g_oLinks.sort(sort_by('link_name', false, function(a){return a.toUpperCase()}));
if (document.getElementById("edit_links_table")){
// EDIT MODE - build table to hold retrieved app data
var links_table_data = "<table cellspacing='10' cellpadding='0' border='0'><tr>";
var favicon_path_array;
for (i in g_oLinks) {
cell_name = g_oLinks[i].link_name;
cell_url = g_oLinks[i].link_url;
cell_url2 = g_oLinks[i].link_url;
favicon_path_array = cell_url.split("//");
cell_url2 = favicon_path_array[1];
favicon_path_array = cell_url2.split("/");
cell_url2 = favicon_path_array[0];
cell_favicon="<img height='16' width=16' src='http://www.google.com/s2/favicons?domain=" + cell_url2 + "' />";
// build and add table row
links_table_data = links_table_data
+ "<tr>" + "<td>" + cell_favicon + "</td>"
+ "<td>" + "<a href='" + cell_url + "' target='_blank'>" + cell_name + "</a></td>"
+ "<td>" + cell_url + "</td>"
+ "<td><input type='button' class='links_save_button' value='Delete' onClick='deleteArrayItem("
+ i + ")'" + "></td>" + "</tr>";
}
// close the table
links_table_data = links_table_data + "</tr></table>";
// put appdata table markup in designated div
// and set height based on which view view this is
document.getElementById("edit_links_table").innerHTML=links_table_data;
gadgets.window.adjustHeight(250 + ((g_oLinks.length - 1) * 28 * 2) + 10 );
}
if(document.getElementById("view_links_table")){
// VIEW MODE - build table to hold retrieved app data
links_table_data = "<table cellspacing='10' cellpadding='0' border='0'><tr>";
for (i in g_oLinks) {
cell_name = g_oLinks[i].link_name;
cell_url = g_oLinks[i].link_url;
cell_url2 = g_oLinks[i].link_url;
favicon_path_array = cell_url.split("//");
cell_url2 = favicon_path_array[1];
favicon_path_array = cell_url2.split("/");
cell_url2 = favicon_path_array[0];
cell_favicon="<img height='16' width=16' src='http://www.google.com/s2/favicons?domain=" + cell_url2 + "' />";
// build and add table row
links_table_data = links_table_data
+ "<tr>" + "<td>" + cell_favicon + "</td>"
+ "<td onClick=\"gadgetEventTrack('go_to_website', cell_name)\">" + "<a href='" + cell_url + "' target='_blank'>" + cell_name + "</a></td>" + "</tr>";
}
// close the table
links_table_data = links_table_data + "</tr></table>";
// put appdata table markup in designated div
document.getElementById("view_links_table").innerHTML=links_table_data;
if (g_oLinks.length > 0) {
gadgets.window.adjustHeight( 12 + ((g_oLinks.length - 1) * 30) + 34 );
}
else {
gadgets.pubsub.publish("hide");
}
}
} /* end if link data exists */
}
// ========================================
// ========================================
function saveData() {
// get link name and url from form
var new_link_name=document.getElementById("linkname").value;
var new_link_url=document.getElementById("linkurl").value;
if (g_oLinks.length < g_max_links || !g_oLinks) {
// check for empty input boxes
if(new_link_name=="" || new_link_url==""){
alert("Please provide both a Link Name and a URL");
return;
}
// prepend http header if missing
if(new_link_url.indexOf("://") == -1){new_link_url = "http://" + new_link_url;}
var newLinkNdx = g_oLinks.length;
g_oLinks[newLinkNdx] = {};
g_oLinks[newLinkNdx].link_name = new_link_name;
g_oLinks[newLinkNdx].link_url = new_link_url;
// write links data to gadget database
osapi.appdata.update({'userId': '@viewer', 'appId': '@app', 'data': {'links' : gadgets.json.stringify(g_oLinks)} }).execute(function(result) {
if (result.error) {
alert("Error " + result.error.code + " writing application data: " + result.error.message);
} else {
// refresh after update, clear input fields - don't need to reset g_oLinks as displayData does this
displayData();
document.getElementById("linkname").value = "";
document.getElementById("linkurl").value = "http://";
alert("Your links information is saved. Don't forget to use the Hide / Show links to make this section visible or hidden on your profile page.");
}
});
} else {
alert("You already have the maximum number of links.");
}
}
// ==============================================================
function gadgetEventTrack(action, label, value) {
var message = {'action' : action};
if (label) {message.label = label;}
if (value) {message.value = value;}
gadgets.pubsub.publish("analytics", message);
}
// ==============================================================
</script>
]]></Content>
<!-- ==================== END COMBINED VIEWS ==================== -->
<!-- ==================== START HOME/EDIT VIEW ==================== -->
<Content type="html" view="home" preferred_height="300" preferred_width="700">
<![CDATA[<!--HTML-->
<h3 style="padding-left:10px; padding-top: 0px;">Manage Links to Other Websites</h3>
<div style="padding:5px 0px 0px 25px;">
Add up to five websites to your profile.
Enter the website name, as you want it to appear on your profile, and its URL.
Some samples include a link to your lab web site, your research program or your research blog.<br /><br />
</div>
<!-- display the new link input fields -->
<div class='question' style="padding:0px 0px 5px 12px;">
<table cellpadding="0" cellspacing="0">
<tr>
<td class="links_body" valign="top"><b>Website Name</b><br />
e.g. My Lab Site<br />
<input id="linkname" type="linkname" name="linkname" style="width:280px; margin-top:4px;"><br />
(60 characters max)
</td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td class="links_body" valign="top"><b>Website URL</b> (not displayed in profile)<br />
e.g. mylabsite.ucsf.edu<br />
<input id="linkurl" type="linkurl" name="linkurl" style="width:250px; margin-top:4px;" value="http://">
</td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td><br /><br /><input type="button" style="margin-bottom: 8px;" value="Save" onClick="saveData();"></td>
</tr>
</table>
</div>
<h4 style="padding-left:10px; padding-top: 0px;">Your Current Websites:</h4>
<div id="edit_links_table" style="padding:0px 0px 10px 25px;"></div>
<script type="text/javascript">
gadgets.util.registerOnLoadHandler(function() {
readData(displayData)
});
</script>
]]></Content>
<!-- ==================== END HOME/EDIT VIEW ==================== -->
<!-- ==================== START PROFILE VIEW ==================== -->
<Content type="html" view="profile" preferred_height="100" preferred_width="670">
<![CDATA[<!--HTML-->
<div id="view_links_table" style="padding:0px 0px 10px 20px;"></div>
<script type="text/javascript">
gadgets.util.registerOnLoadHandler(function() {
readData(displayData)
});
</script>
]]></Content>
<!-- ==================== END PROFILE VIEW ==================== -->
</Module>

View file

@ -1,478 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Faculty Mentoring"
description="Faculty Mentoring details">
<Require feature="opensocial-0.9" />
<Require feature="views" />
<Require feature="dynamic-height" />
<Require feature="pubsub" />
<Require feature="osapi" />
</ModulePrefs>
<!-- ==================== START COMBINED VIEWS ==================== -->
<Content type="html" view="default, home, profile"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<!-- #includes -->
<link rel="stylesheet" href="css/gadget.css" type="text/css" media="screen, projection" >
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<script type="text/javascript" src="js/os.js" ></script>
<style>
.mentor_title {
font-family: Verdana, Arial;
font-size: 14px;
}
.mentor_body {
font-family: Arial;
font-size: 11px;
}
.mentor_credit {
font-family: Arial;
font-size: 10px;
}
.mentor_list {
font-family: Arial;
font-size: 11px;
}
.mentor_message {
font-family: Arial;
font-size: 12px;
font-weight: normal;
}
a, a:visited { color: #0088CC; text-decoration: none; }
a:hover { color: #005580; text-decoration: underline; }
</style>
<script type="text/javascript">
var g_chars_allowed=2000;
var g_textarea_content="";
function limit_chars(){
num_chars = document.getElementById("facultyNarrative").value.length;
if (num_chars > g_chars_allowed) {
alert("Your narrative exceeds the maximum number of characters.");
document.getElementById("facultyNarrative").value = g_textarea_content;
}
else {
g_textarea_content = document.getElementById("facultyNarrative").value;
}
}
// ==============================================================
function gadgetEventTrack(action, label, value) {
var message = {'action' : action};
if (label) {message.label = label;}
if (value) {message.value = value;}
gadgets.pubsub.publish("analytics", message);
}
// ==============================================================
function displayMentorAppData() {
var fields = ["careerMentor", "coMentor", "leadResearch", "projectMentor",
"contactEmail", "contactPhone", "contactAssistant",
"assistantName", "assistantEmail", "assistantPhone",
"narrative", "lastUpdate"];
osapi.appdata.get( {'userId': '@owner', 'appId':'@app', 'fields': fields } ).execute(function(result) {
if (result.error) {
alert("Error " + result.error.code + " reading application data: " + result.error.message);
} else {
// get incoming mentor data
var viewer = os.osapi.getViewerFromResult(result);
if (viewer.careerMentor == "T" && document.getElementById("edit_career_mentor") )
document.getElementById("edit_career_mentor").checked = true;
if (viewer.coMentor == "T" && document.getElementById("edit_co_mentor") )
document.getElementById("edit_co_mentor").checked = true;
if (viewer.leadResearch == "T" && document.getElementById("edit_lead_research") )
document.getElementById("edit_lead_research").checked = true;
if (viewer.projectMentor == "T" && document.getElementById("edit_project_mentor") )
document.getElementById("edit_project_mentor").checked = true;
if (viewer.contactEmail == "T" && document.getElementById("edit_email"))
document.getElementById("edit_email").checked = true;
if (viewer.contactPhone == "T" && document.getElementById("edit_phone"))
document.getElementById("edit_phone").checked = true;
if (viewer.contactAssistant == "T" && document.getElementById("edit_assistant"))
document.getElementById("edit_assistant").checked = true;
if (viewer.assistantName && document.getElementById("edit_assistant_name") )
document.getElementById("edit_assistant_name").value = viewer.assistantName;
if (viewer.assistantEmail && document.getElementById("edit_assistant_email") )
document.getElementById("edit_assistant_email").value = viewer.assistantEmail;
if (viewer.assistantPhone && document.getElementById("edit_assistant_phone") )
document.getElementById("edit_assistant_phone").value = viewer.assistantPhone;
if (viewer.narrative)
document.getElementById("facultyNarrative").value = viewer.narrative;
if (viewer.lastUpdate)
document.getElementById("last_updated").innerHTML = viewer.lastUpdate;
// VIEW MODE - build table to hold retrieved app data
var view_window_height=80;
var mentor_as = "hidden";
var mentor_contact = "hidden";
if (viewer.careerMentor == "T" && document.getElementById("mentor_as_career_mentor") && document.getElementById("mentor_as") ) {
document.getElementById("mentor_as").style.display = "block";
document.getElementById("mentor_as_career_mentor").style.display = "block";
view_window_height += 20;
mentor_as = "visible";
}
if (viewer.coMentor == "T" && document.getElementById("mentor_as_co_mentor") && document.getElementById("mentor_as") ) {
document.getElementById("mentor_as").style.display = "block";
document.getElementById("mentor_as_co_mentor").style.display = "block";
view_window_height += 20;
mentor_as = "visible";
}
if (viewer.leadResearch == "T" && document.getElementById("mentor_as_lead_research") && document.getElementById("mentor_as") ) {
document.getElementById("mentor_as").style.display = "block";
document.getElementById("mentor_as_lead_research").style.display = "block";
view_window_height += 20;
mentor_as = "visible";
}
if (viewer.projectMentor == "T" && document.getElementById("mentor_as_project_mentor") && document.getElementById("mentor_as") ) {
document.getElementById("mentor_as").style.display = "block";
document.getElementById("mentor_as_project_mentor").style.display = "block";
view_window_height += 20;
mentor_as = "visible";
}
if (viewer.contactEmail == "T" && document.getElementById("mentor_contact_email") && document.getElementById("mentor_contact") ) {
document.getElementById("mentor_contact").style.display = "block";
document.getElementById("mentor_contact_email").style.display = "block";
view_window_height += 20;
mentor_contact = "visible";
}
if (viewer.contactPhone == "T" && document.getElementById("mentor_contact_phone") && document.getElementById("mentor_contact") ) {
document.getElementById("mentor_contact").style.display = "block";
document.getElementById("mentor_contact_phone").style.display = "block";
view_window_height += 20;
mentor_contact = "visible";
}
if (viewer.contactAssistant == "T" && document.getElementById("mentor_contact_assistant") && document.getElementById("mentor_contact") ) {
document.getElementById("mentor_contact").style.display = "block";
document.getElementById("mentor_contact_assistant").style.display = "block";
document.getElementById("mentor_assistant").style.display = "block";
view_window_height += 20;
mentor_contact = "visible";
}
if (viewer.assistantName && document.getElementById("mentor_assistant") && document.getElementById("mentor_assistant_name") ) {
document.getElementById("mentor_assistant_name").style.display = "block";
document.getElementById("mentor_assistant_name").innerHTML += viewer.assistantName;
view_window_height += 20;
}
if (viewer.assistantEmail && document.getElementById("mentor_assistant") && document.getElementById("mentor_assistant_email") ) {
document.getElementById("mentor_assistant_email").style.display = "block";
document.getElementById("mentor_assistant_email").innerHTML += viewer.assistantEmail;
view_window_height += 20;
}
if (viewer.assistantPhone && document.getElementById("mentor_assistant") && document.getElementById("mentor_assistant_phone") ) {
document.getElementById("mentor_assistant_phone").style.display = "block";
document.getElementById("mentor_assistant_phone").innerHTML += viewer.assistantPhone;
view_window_height += 20;
}
if (viewer.narrative) {
document.getElementById("facultyNarrative").style.display = "block";
var p_chars = viewer.narrative;
// count the characters and calculate number of rows
p_num_chars = p_chars.length;
document.getElementById("facultyNarrative").innerHTML = p_chars;
p_lines = Math.round(p_num_chars / 100);
if (p_lines < 1) {p_lines = 1}
view_window_height += (p_lines * 15);
// note works in FF but not IE:
// view_window_height += document.getElementById('facultyNarrative').offsetHeight;
}
if (viewer.lastUpdated)
document.getElementById("last_updated").innerHTML = viewer.lastUpdated;
if (mentor_as == "visible") {view_window_height += 20};
if (mentor_contact == "visible") {view_window_height += 20};
// adjust the window height - only do this here if in profile VIEW (not in EDIT)
if (document.getElementById("mentor_as")) {
gadgets.window.adjustHeight(view_window_height);
}
} /* end else */
}); /*osapi.appdata.get*/
}
function saveMentorAppData() {
var mentor_today = new Date();
var weekday=new Array(7);
weekday[0]="Sunday";
weekday[1]="Monday";
weekday[2]="Tuesday";
weekday[3]="Wednesday";
weekday[4]="Thursday";
weekday[5]="Friday";
weekday[6]="Saturday";
var month=new Array(12);
month[0]="January";
month[1]="February";
month[2]="March";
month[3]="April";
month[4]="May";
month[5]="June";
month[6]="July";
month[7]="August";
month[8]="September";
month[9]="October";
month[10]="November";
month[11]="December";
var mentor_day = weekday[mentor_today.getDay()]
var mentor_month = month[mentor_today.getMonth()]
var mentor_date = mentor_today.getDate();
var mentor_year = mentor_today.getFullYear();
var current_date = mentor_day + " " + mentor_month + " " + mentor_date + ", " + mentor_year;
// pack the data into an Object (md for mentor data)
// with property names that match the values in the "fields" array
// used by osapi.appdate.get in displayMentorAppData
var md = {};
md.careerMentor = document.getElementById("edit_career_mentor").checked ? "T" : "F";
md.coMentor = document.getElementById("edit_co_mentor").checked ? "T" : "F";
md.leadResearch = document.getElementById("edit_lead_research").checked ? "T" : "F";
md.projectMentor = document.getElementById("edit_project_mentor").checked ? "T" : "F";
md.contactEmail = document.getElementById("edit_email").checked ? "T" : "F";
md.contactPhone = document.getElementById("edit_phone").checked ? "T" : "F";
md.contactAssistant = document.getElementById("edit_assistant").checked ? "T" : "F";
md.assistantName = document.getElementById("edit_assistant_name").value;
md.assistantEmail = document.getElementById("edit_assistant_email").value;
md.assistantPhone = document.getElementById("edit_assistant_phone").value;
md.narrative = document.getElementById("facultyNarrative").value;
md.lastUpdate = current_date;
osapi.appdata.update({'userId': '@viewer', 'appId':'@app', 'data':md }).execute(function(result) {
if (result.error) {
alert("Error " + result.error.code + " writing application data: " + result.error.message);
}
});
}
</script>
]]></Content>
<!-- ==================== END COMBINED VIEWS ==================== -->
<!-- ==================== START HOME/EDIT VIEW ==================== -->
<Content type="html" view="default, home" preferred_width="700"><![CDATA[<!--HTML-->
<h4 style="padding-left:12px;">Add Faculty Mentoring to Your Profile</h4>
<div id='AddEdit' style="padding:15px 0px 0px 12px;">
Add details about your availability to mentor UCSF faculty.
Learn about the <a href="http://academicaffairs.ucsf.edu/ccfl/faculty_mentoring_program.php" target="_blank" title="Go to the UCSF Faculty Mentoring Website">Faculty Mentoring Program</a>
and the <a href="http://ctsi.ucsf.edu/training/mdp-announcement" target="_blank" title="Go to the CTSI MDP Web page">CTSI&nbsp;Mentor&nbsp;Development&nbsp;Program</a>
<br /><br />
</div>
<div>
<div style="float:left;">
<span class="mentor_message">&nbsp;&nbsp;&nbsp;
Be sure to <b>SAVE</b> your work below.</span>
</div>
<div class="updated" style="float:right; display:block; text-align:left; padding-right:10px; font-size: 10px;">
Last Updated: <span id="last_updated" style="font-size: 10px;"></span>
</div>
</div>
<div class='question' style="padding: 0px; width:500px;">
<br>
<h4>Available to Mentor Faculty as:</h4> <span>(check all that apply)</span> &nbsp;&nbsp;&mdash;&nbsp;&nbsp; <a href="http://ctsi.ucsf.edu/training/mdp-seminar1-definitions" target="_blank" title="Go to the Mentor Role Definitions Web page">Review Mentor Role Definitions</a>
<table cellspacing="0" cellpadding="15">
<tr>
<td valign="middle" width="220" class="mentor_list">
<input id="edit_career_mentor" type="checkbox">Career Mentor</td>
<td valign="middle" class="mentor_list">
<input id="edit_co_mentor" type="checkbox">Co-Mentor</td>
</tr>
<tr>
<td valign="middle" class="mentor_list">
<input id="edit_lead_research" type="checkbox">Lead Research / Scholarly Mentor&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td valign="middle" class="mentor_list">
<input id="edit_project_mentor" type="checkbox">Project Mentor</td>
</tr>
</table>
</div>
<div class='question'>
<h4>My Contact Preference:</h4>
<table cellspacing="0" cellpadding="15">
<tr>
<td valign="middle" width="220" class="mentor_list">
<input id="edit_email" type="checkbox">Email</td>
<td valign="middle" class="mentor_list">
<input id="edit_phone" type="checkbox">Phone</td>
</tr>
<tr>
<td valign="middle" class="mentor_list">
<input id="edit_assistant" type="checkbox">Assistant</td>
<td></td>
</tr>
</table>
</div>
<div class='question' style="padding:0px 0px 0px 10px;">
<span class="mentor_list"><b>Assistant Details</b></span><br>
<fieldset class='details roundbox'>
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<label class='textlabel'>Name</label>
<input id="edit_assistant_name" type="text" style="width:420px;">
</td>
</tr>
</table>
<br>
<table cellpadding="0" cellspacing="0">
<tr>
<td><label class='textlabel'>Email</label>
<input id="edit_assistant_email"></td>
<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td><label class='textlabel'>Phone</label>
<input id="edit_assistant_phone"></td>
</tr>
</table>
</fieldset>
</div>
<div class='question'>
<h4>Mentoring Narrative:&nbsp;<img src="images/hovertiptarget.png" border="0" onClick="document.getElementById('sample').style.display='block';">
<span class="mentor_message">&nbsp;&nbsp;Be sure to <b>SAVE</b> your work below.</span></h4>
<div id="sample" style="display:none; border:1px solid #383838; padding:10px 10px 10px 10px; margin:10px; height:160px;">
<div style="padding-bottom: 5px;">
<button style="float:right;" onClick="document.getElementById('sample').style.display='none';">Close</button><br>
<center><b>Sample Mentor Narratives</b> (cut and paste to create your own)</center><br>
</div>
<div style="height:110px; padding: 0px 0px 0 5px;overflow:auto;">
EXAMPLE 1:<br />
Dr. Brown is willing to mentor faculty, fellows, residents and students interested in an academic research career. Most often her mentees have had training in clinical research methods or will obtain training through the CTSI CTST. For students, it is expected they will have dedicated time for research. Through email or meeting, if there is a “match” for research interest, time, and training, further discussions as to project, goals, and access to resources (space, databases, and statistical support) will be discussed to provide a productive experience.
<br><br>
EXAMPLE 2:<br />
I am highly qualified to participate as a lead mentor or co-mentor at UCSF. My program of research is focused on health outcomes associated with disturbed sleep in various populations of healthy women and women with chronic illnesses like HIV/AIDS and cancer. I have completed cross-sectional studies, longitudinal studies, and most recently, randomized clinical trials to improve sleep. I have mentored doctoral students and postdoctoral fellows studying various patient populations, from the very young to very old. During my tenure at UCSF, I have directly supervised over 30 doctoral students, mentored 14 postdoctoral trainees, and served as a lead mentor for 6 pre-tenured faculty. I have been the Director for a T32 Nurse Research Training Grant since 1996, and I have been honored with being voted mentor of the year by doctoral students on two occasions. I play a significant role in the clinical and translational (CTSI) research mentoring and career development programs at UCSF. I am the seminar leader for the first session in the CTSI Mentor Development program on “Rewards and Challenges of Mentoring” and I have co-mentored two KL2 scholars. I have published over 50 peer-reviewed research articles with trainees as first-author, and serve as a consultant on two external K awards as well as three external R01 awards with former mentees. Finally, I have served on many different NIH study section review panels, and I served as the Chair of an NIH study section (2008-2010), which allows me to be particularly effective in mentoring early career principal investigators who are writing their first NIH applications.
<br><br>
I can provide mentees a cubicle space with my research team, tangible resources such as access to large datasets for secondary analysis as needed, and intangible resources such as attending our formal research team meetings and our informal spontaneous group discussions as well as networking at national sleep research conferences.
</div>
</div>
<fieldset>
<textarea id="facultyNarrative" rows='9' cols='72' class='roundbox' style="margin-left:12px;" name="facultyNarrative" onKeyDown="limit_chars()" onKeyUp="limit_chars()" onMouseout="limit_chars()"></textarea>
<span style="margin-left:12px;white-space:nowrap">(2000 characters max)</span>
</fieldset>
</div>
<div>
<center>
<input type="button" onClick="saveMentorAppData();" value="Save">
&nbsp;&nbsp;&nbsp;
<input type="button" onClick="displayMentorAppData()" value="Cancel">
</center>
</div>
<script type="text/javascript" >
// retrieve last-saved data and map it to the fields in the markup
displayMentorAppData();
gadgets.window.adjustHeight(700);
</script>
]]></Content>
<!-- ==================== END HOME/EDIT VIEW ==================== -->
<!-- ==================== START PROFILE VIEW ==================== -->
<Content type="html" view="default, profile" preferred_width="670"><![CDATA[<!--HTML-->
<div class="updated" style="display:block; text-align:left; padding: 5px 10px 10px 0; font-size: 10px;">
Last Updated: <span id="last_updated" style="font-size: 10px;"></span>
</div>
<br>
<div>
<p id="facultyNarrative" style="margin-left:20px; margin-right:20px; font-family:Arial; font-size:12px; display:none;"></p>
</div>
<div id="mentor_as" style="display:none; margin-left:20px;">
<span class='detailtitle'>Available to Mentor as: </span> (<a href="http://ctsi.ucsf.edu/training/mdp-seminar1-definitions" target="_blank" title="Go to the Mentor Role Definitions Web page" onClick="gadgetEventTrack('view_mentor_roles', 'http://ctsi.ucsf.edu/training/mdp-seminar1-definitions'); return true">Review Mentor Role Definitions</a>):
<span id="mentor_as_career_mentor" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Career Mentor</span>
<span id="mentor_as_co_mentor" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Co-Mentor</span>
<span id="mentor_as_lead_research" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Lead Research / Scholarly Mentor</span>
<span id="mentor_as_project_mentor" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Project Mentor</span>
</div>
<div id="mentor_contact" style="padding:10px 0 0 0; display:none; margin-left: 20px;">
<span class='detailtitle'>Contact for Mentoring:</span>
<ul style="width:400px;">
<li id="mentor_contact_email" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Email (see above)</li>
<li id="mentor_contact_phone" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Phone (see above)</li>
<li id="mentor_contact_assistant" style="display:none; padding-botom:3px;"><span style="font-size:18px;">&nbsp;&nbsp;&nbsp;<b>&middot;</b>&nbsp;</span>Assistant</li>
</ul>
</div>
<div id="mentor_assistant" style="padding:5px 0 0 0; display:none; margin-left: 55px;">
<div id="mentor_assistant_name" style="display:none; height:20px;">Name:&nbsp;</div>
<div id="mentor_assistant_email" style="display:none; height:20px;">Email:&nbsp;</div>
<div id="mentor_assistant_phone" style="display:none; height:20px;">Phone:&nbsp;</div>
</div>
<div style="padding:10px 0px 0px 20px;">
Learn about the <a href="http://academicaffairs.ucsf.edu/ccfl/faculty_mentoring_program.php" target="_blank" title="Go to the UCSF Faculty Mentoring Website" onClick="gadgetEventTrack('go_to_program', 'http://academicaffairs.ucsf.edu/ccfl/faculty_mentoring_program.php'); return true">Faculty Mentoring Program</a>
and the <a href="http://ctsi.ucsf.edu/training/mdp-announcement" target="_blank" title="Go to the CTSI | MDP Web page" onClick="gadgetEventTrack('go_to_development', 'http://ctsi.ucsf.edu/training/mdp-announcement'); return true">CTSI Mentor Development Program</a>
<br /><br />
</div>
<script type="text/javascript">
displayMentorAppData();
</script>
]]></Content>
<!-- ==================== END PROFILE VIEW ==================== -->
</Module>

View file

@ -1,624 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Create a Group" author="Eric Meeks">
<Require feature="opensocial-0.9" />
<Require feature="pubsub" />
<Require feature="views" />
<Require feature="osapi" />
<Require feature="rdf" />
</ModulePrefs>
<Content type="html" view="canvas, small"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<!-- #includes -->
<link rel="stylesheet" href="css/gadget.css" type="text/css" media="screen, projection" >
<script type="text/javascript" src="js/os.js" ></script>
<script type="text/javascript" src="js/jquery-1.4.4.js"></script>
<script type="text/javascript" src="js/environment.js"></script>
<style>
.tool_title {font-family:Arial,Helvetica; font-size:14px;}
.tool_title_orange {font-weight:bold; font-family:Arial,Helvetica; font-size:14px; color:#CA7C29;margin-top:-1px;}
.tool_body {font-family:Arial; font-size:12px;}
.tool_credit {font-family:Arial; font-size:10px;}
.tool_table_cell {font-family:Arial,Helvetica; font-size:12px; padding:0 20px 0 0;}
.tool_table_cell_small {font-family:Arial,Helvetica;font-size:11px;}
.tool_table_cell_small span a {font-size:11px;}
.tool_table_cell_small span {font-size:11px;display:inline-block;margin-right: -15px; }
.tool_toggle_button {font-size: 13px;padding:0 5px;}
a, a:visited { color: #0088CC; text-decoration: none; }
a:hover { color: #005580; text-decoration: underline; }
</style>
<script type="text/javascript">
// ==============================================================
function gadgetEventTrack(action, label, value) {
var message = {'action' : action};
if (label) {message.label = label;}
if (value) {message.value = value;}
gadgets.pubsub.publish("analytics", message);
}
// ==============================================================
function showHelp() {
var pop = window.open('Create a Group Help','','top=200,left=200,width=450,height=340,scrollbars=0,status=0,menubar=0,location=0,resizable=0');
pop.document.title = "Create a Group Help";
pop.document.write("<html><head></head><body><div style='margin:10px; font-family:Arial; font-size:12px;'>");
pop.document.write("Create a list of profiles and start a UCSF Chatter group or email list from here. "
+ "Here's how:<br><ol>"
+ "<li>Click the 'Create Now!' button</li>"
+ "<li>Start compiling a list of profiles for your group. "
+ "You can add one profile at a time, add a set of search results, "
+ "or add a set of co-authors.</li>"
+ "<li>Review your list and create your group</li>"
+ "<li>Name your group and add a description</li></ol>"
+ "<strong>Tips:</strong><br><br>"
+ "You are automatically added to the UCSF Chatter group if you create it. "
+ "You don't need to add yourself to the list of group members. "
+ "This works best if your group is 25 people or less. "
+ "If you want to add or remove members after the group is created, "
+ "go to UCSF Chatter directly.<br><br>"
+ "To learn more about UCSF Chatter, go to "
+ "<a href='http://it.ucsf.edu/services/chatter' target='_blank'>"
+ "http://it.ucsf.edu/services/chatter</a>");
pop.document.write("<br><br><center>"
+ "<input type = 'button' value = 'Close' onclick = 'window.close();'>"
+ "</center>");
pop.document.write("</body></html>");
}
// ==============================================================
function getNewProfilesStats(sender, message) {
var stats = gadgets.json.parse(message);
// display the action item table and update it
$("#actions").show();
if (message === 0) {
document.getElementById("add_profiles").innerHTML = "No Profiles found";
}
else {
document.getElementById("add_profiles").innerHTML = "<a style='font-size:11px;' href='javascript:addNewProfiles();'>Add " + message + " to list</a>";
}
}
function addNewProfiles() {
document.getElementById("add_profiles").innerHTML = "Adding profiles...";
document.getElementById("list_profiles").innerHTML = "Merging into list...";
readIdsFromDB(function(existingIds) {
gadgets.pubsub.subscribe("JSONPersonIds", getNewIdsCallback(existingIds));
});
}
function getNewIdsCallback(existingIds) {
return function(sender, message) {
// extract the array of incoming person IDs
var newIds = gadgets.json.parse(message).personIds;
var addedListSize = getListSize(newIds);
var priorListSize = getListSize(existingIds);
// merge the incoming and existing person ID arrays
// existing array already populated
for (var baseURI in newIds) {
if (!existingIds.hasOwnProperty(baseURI)) {
existingIds[baseURI] = [];
}
existingIds[baseURI] = dedupeArray(existingIds[baseURI].concat(newIds[baseURI]));
}
var newListSize = getListSize(existingIds);
showCurrentListSize(newListSize);
if (newListSize > priorListSize) {
saveData(existingIds, function() {
document.getElementById("add_profiles").innerHTML = ((newListSize - priorListSize) === 1 ? "1 new Profile added" : "" + (newListSize - priorListSize) + " new Profiles added");
showCurrentListSize(newListSize);
});
}
else {
document.getElementById("add_profiles").innerHTML = (addedListSize == 1 ? "Profile already in list" : "Profiles already in list");
}
};
}
// ==============================================================
function getListSize(ids) {
var cnt = 0;
for (var baseURI in ids) {
cnt += ids[baseURI].length;
}
return cnt;
}
// ==============================================================
function showCurrentListSize(count) {
if (count > 0) {
document.getElementById("list_profiles").innerHTML = "<a href='javascript:gadgets.views.requestNavigateTo(\"canvas\");'>" + count + " Profiles in list</a>";
}
else {
document.getElementById("list_profiles").innerHTML = "List is currently empty";
}
}
function showToolVersion(canvasMode) {
// fetch the extended state
osapi.appdata.get({'userId':'@viewer', 'appId':'@app', 'fields':['extended']} )
.execute(function(result) {
if (os.osapi.getViewerFromResult(result).extended == "True") {
if (canvasMode) {
document.getElementById("extended_functions").style.display = "inline-block";
document.getElementById("extended_functions").style.padding = "0 0 0 20px";
document.getElementById("canvas_help").innerHTML =
'Create a UCSF Chatter group or email list that includes the people below. '
+ 'To manage your UCSF Chatter group after you create it, such as adding or '
+ 'removing members, go to UCSF Chatter directly.' ;
}
}
else {
// this is what people who have limited functionality (only chatter group) see
if (canvasMode) {
document.getElementById("basic_functions").style.display = "inline-block";
document.getElementById("basic_functions").style.padding = "0 0 0 20px";
document.getElementById("canvas_help").innerHTML =
'Create a UCSF Chatter group that includes the people below. '
+ 'To manage your group after you create it, such as adding or '
+ 'removing members, go to UCSF Chatter directly.' ;
}
}
// if we are not in canvas mode, show the On/Off state correctly
if (!canvasMode) {
readCountFromDB( function(count) {
showCurrentListSize(count);
});
gadgets.pubsub.subscribe("PersonResultCount", getNewProfilesStats);
}
});
}
// ==============================================================
function toURIList(existingIds) {
var uriList = [];
for (var baseURI in existingIds) {
for (var i = 0; i < existingIds[baseURI].length; i++) {
uriList.push(baseURI + existingIds[baseURI][i]);
}
}
return uriList;
}
// first argument is an map of data,
// second argument is the callback function to execute after updating the data
function saveData(ids, callback) {
osapi.appdata.update({'userId': '@viewer', 'appId':'@app', 'data': {'count' : '' + getListSize(ids), 'ids' : gadgets.json.stringify(ids)}}).execute(callback);
}
// ==============================================================
function readCountFromDB(callback) {
osapi.appdata.get({'userId':'@viewer', 'appId':'@app', 'fields':'count'}).execute(function(result) {
// a map of {baseURI1 : ["string", "string"], baseURI2 : ["string", "string"]}
var count = os.osapi.getViewerFromResult(result).count || 0;
callback(count);
});
}
function readIdsFromDB(callback) {
osapi.appdata.get({'userId':'@viewer', 'appId':'@app', 'fields':'ids'}).execute(function(result) {
// a map of {baseURI1 : ["string", "string"], baseURI2 : ["string", "string"]}
var existingIds = os.osapi.getViewerFromResult(result).ids || "{}";
callback(gadgets.json.parse(existingIds));
});
}
// ==============================================================
function deleteList() {
osapi.appdata['delete']({'userId':'@viewer', 'appId':'@app', 'fields': ['ids', 'count']} )
.execute(function(result){
if (result.error) {
alert("Error " + result.error.code + " deleting application data: " + result.error.message);
} else {
document.getElementById("canvas_email_list_textarea").value = "";
document.getElementById("canvas_full_list_textarea").value = "";
document.getElementById("canvas_profile_list").innerHTML = "";
document.getElementById("number_selected").innerHTML = "Select Profiles";
}
}); /* end osapi.appdata.delete */
}
// ==============================================================
function dedupeArray(arrHasDupes) {
var deduped = [];
$.each(arrHasDupes, function(i, el){
if($.inArray(el, deduped) === -1) deduped.push(el);
});
return deduped;
}
// ==============================================================
function displayProfileList(existingIds) {
var uris = toURIList(existingIds);
// put these as individual fields in an ontology.js file
// pass in as options to getRdf call
var fullName = 'http://profiles.catalyst.harvard.edu/ontology/prns#fullName';
var preferredTitle = 'http://vivoweb.org/ontology/core#preferredTitle';
var email = 'http://vivoweb.org/ontology/core#email';
var strTable="<table cellspacing='0' cellpadding='0' width='640'><tr>";
// build the table header row
strTable += "<td align='left' valign='top' class='tool_table_cell'>" + "<u><b>Name</b></u></td>";
strTable += "<td align='left' valign='top' class='tool_table_cell'>" + "<u><b>Title</b></u></td>";
strTable += "<td align='left' valign='top' class='tool_table_cell'>" + "<u><b>Email&nbsp;Address</b></u></td>";
strTable += "</tr>";
for (i in uris) {
//strTable += "<tr id='" + uris[i] + "'><div id='displayPerson_" + i + "'></div></tr>";
strTable += "<tr id='" + uris[i] + "'></tr>";
}
strTable += "</table>";
// dispay the empty table in canvas view
document.getElementById("canvas_profile_list").innerHTML = strTable;
document.getElementById("number_selected").innerHTML = "Your list includes (" + uris.length + ")" + " selected profiles";
// initialize the export divs
document.getElementById("canvas_email_list_textarea").value = "";
document.getElementById("canvas_full_list_textarea").value = "";
// load in groups of ten
var batchSize = 10;
var batchCount = Math.floor(uris.length/batchSize) + (uris.length % batchSize == 0 ? 0 : 1);
for (i = 0; i < uris.length; i += batchSize) {
var ids = '';
for (j = 0; j < batchSize && i+j < uris.length; j++) {
ids += (j > 0 ? ',' : '') + uris[i + j];
}
osapi.rdf.getRDF(ids).execute(function(data) {
var people = data.list;
if(!people) {
people = [data];
}
for (var j = 0; j < people.length; j++) {
var base = people[j].base;
people[j] = jsonldHelper.getItem(people[j]);
// put in div now so people can see progress
var table_row = "<td align='left' valign='top' class='tool_table_cell'>" + people[j][fullName] + "</td>";
table_row += "<td align='left' valign='top' class='tool_table_cell'>" + people[j][preferredTitle] + "</td>";
table_row += "<td align='left' valign='top' class='tool_table_cell email'>" + (people[j][email] ? people[j][email] : "") + "</td>";
document.getElementById(base + people[j]['@id']).innerHTML = table_row;
}
// see if we are done and if so turn off progress bar and
// add to export lists
if (--batchCount == 0) {
var full_list = "";
var email_list = "";
$("#canvas_profile_list tr").each(function(index, tr){
if(!$(tr).attr("id")) {
return true;
}
var row = "";
$("td", tr).each(function(fld_index, td){
var txt = $(td).text();
row += txt + ";";
if(fld_index == 2 && txt != "") {
email_list += txt + "\n";
}
});
full_list += row + "\n";
});
document.getElementById("canvas_full_list_textarea").value = full_list;
document.getElementById("canvas_email_list_textarea").value = email_list;
document.getElementById("progress").style.display="none";
}
});
}
} /* end displayProfileList */
// ==============================================================
function copyEmailDivToClipboard() {
$("#canvas_email_list").show();
$("#canvas_email_list_text").show();
$("#canvas_full_list").hide();
$("#canvas_full_list_text").hide();
$("#canvas_profile_list").hide();
}
// ==============================================================
function copyFullDivToClipboard() {
$("#canvas_full_list").show();
$("#canvas_full_list_text").show();
$("#canvas_email_list").hide();
$("#canvas_email_list_text").hide();
$("#canvas_profile_list").hide();
}
// ==============================================================
var root = (typeof ENV_LOCAL_URL === 'undefined')? "": ENV_LOCAL_URL;
var chatterProxyURL = root + "/chatter/ChatterProxyService.svc";
function getNodeIdFromURI(uri) {
if (typeof uri === 'string') {
var c = uri.split('/');
return c[c.length-1];
}
else {
var retval = [];
for ( i = 0; i < uri.length; i++) {
retval[i] = getNodeIdFromURI(uri[i]);
}
return retval;
}
}
function createGroup(name, description, ownerId, users) {
document.getElementById("progress").style.display="block";
var params = {
"name": name,
"description": description,
"ownerId": ownerId,
"users": users};
sendRequest(false, false, chatterProxyURL + "/group/new", params, function(data) {
document.getElementById("progress").style.display="none";
if(data.Success) {
showMessage("<strong>Success! Your UCSF Chatter group '" + name + "' has been created.</strong><br> "
+ "<a target='_blank' href='" + data.URL + "'>Go to UCSF Chatter to start working with your group.</a>");
$("input#goup_name").val("");
}
else {
showMessage("Cannot create a group. " + data.ErrorMessage, true);
}
},
function(obj) {
showMessage("Server error " + obj.rc + " : " + obj.errors, true);
});
}
// ==============================================================
function sendRequest(cache, signed, url, post_params, success, error) {
var params = {};
if (signed) {
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
}
params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(post_params);
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
if(cache == false) {
params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 0;
}
gadgets.io.makeRequest(url, function(obj) {
if(obj.data != null) {
success(obj.data);
}
else if(obj.errors != null) {
if(error) {
error(obj);
}
}
}
, params);
}
// ==============================================================
function showMessage(msg, isError) {
$("div.message").html(msg);
if(isError == true) {
$("div.message").removeClass("info");
$("div.message").addClass("error");
}
else {
$("div.message").removeClass("error");
$("div.message").addClass("info");
}
$("div.message").removeClass("hidden");
}
// ==============================================================
function getUserList() {
var items = [];
$("div#canvas_profile_list tr").each( function(index, elem) {
var id = $(elem).attr("id");
if(id != null && id != "") {
items.push(getNodeIdFromURI(id));
}
});
return items.join(',');
}
// ==============================================================
</script>]]></Content>
<Content type="html" view="small" preferred_height="75" preferred_width="190"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<table id="button_and_help" cellspacing="6" cellpadding="5" style="display:block;">
<tr>
<td class="tool_table_cell_small" style="width:145px">Add profiles to your list</td>
<td><img src="images/hovertiptarget.png" border="0" onClick="gadgetEventTrack('help');showHelp()"></td>
</tr>
</table>
<table id="actions" style="display:none;clear:right;" cellspacing="2" cellpadding="0">
<tr>
<td class="tool_table_cell_small">&nbsp;1.&nbsp;</td>
<td class="tool_table_cell_small"><span id="add_profiles" onClick="gadgetEventTrack('add_profiles')"></span></td>
</tr>
<tr>
<td class="tool_table_cell_small" valign="top" style="padding-top:4px">&nbsp;2.&nbsp;</td>
<td class="tool_table_cell_small" valign="top" style="padding-top:4px"><span id="list_profiles" onClick="gadgetEventTrack('list_profiles')">Loading...</span></td>
</tr>
</table>
<script type="text/javascript">
function init() {
showToolVersion(false);
}
gadgets.util.registerOnLoadHandler(init);
</script>]]></Content>
<Content type="html" view="canvas" preferred_height="600" preferred_width="700"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<style type="text/css">
div#create_group {
margin-left: 20px;
margin-top:10px;
margin-bottom:10px;
padding-top:10px;
padding-bottom:10px;
padding-left:10px;
padding-right:10px;
border:solid gray 1px;
width:470px;
border-radius: 0;
}
input#close {
margin-left:10px;
}
div.message {
margin-bottom:10px;
}
div.info {
color:green;
}
div.error {
color:red;
}
.hidden {
display:none;
}
a, a:visited { color: #0088CC; text-decoration: none; }
a:hover { color: #005580; text-decoration: underline; }
p { width: 640px; }
</style>
<!-- top menu links -->
<div style="width:640px;">
<p id="number_selected" class="tool_title_orange" style="margin-left:20px;margin-top:20px\9;">
Selected Profiles<p>
<p id="canvas_help" style="padding-left:20px"></p>
<p class="tool_body" style="margin-left:20px; margin-bottom:10px;">
<div id="extended_functions" style="display:none;">
<a href="" id="create_group">Create UCSF Chatter Group</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="javascript:gadgetEventTrack('export_email');copyEmailDivToClipboard();">Export email addresses only</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="javascript:gadgetEventTrack('export_all_data');copyFullDivToClipboard();">Export all data</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="" id="compose-email">Compose email to list</a><p>
</div>
<div id="basic_functions" style="display:none;">
<a href="" id="create_group">Create UCSF Chatter Group</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|
</div>
<a href="javascript:gadgetEventTrack('delete_list');deleteList();" style="margin-left:20px;">Delete list</a>
</p>
<p id="progress" style="margin-left:20px;">
<br><br>
<img src="images/waiting.gif">
<br><br>
<b>This may take a minute or two, based on the size of your selected Profiles list.</b></p>
</div>
<div id="create_group" class="hidden">
<div class="message hidden"><strong>Success! Your UCSF Chatter group has been created.</strong><br>
Go to UCSF Chatter to start working with your group.</div>
<table><tr>
<td nowrap valign="top">UCSF Chatter Group Name:</td>
<td><input id="group_name" type="text" style="width:218px"></input><br><br></td></tr><tr>
<td nowrap valign="top" align="right">Group Description:</td>
<td><textarea id="group_description" rows="4" cols="25"></textarea><br><br></td></tr><tr><td>&nbsp;</td>
<td><input id="create" type="button" value="Create"></input>
<input id="close" type="button" value="Cancel/Close"></input></td></tr></table>
</div>
<div id="canvas_email_list" style="display:none; background:#FFF; width:670px; height:50px; margin-left:20px;">
Copy and paste the email addresses below into an Excel spreadsheet or email client "To" field.
<input type="button" style="height:22px; font-size:10; margin-left:40px; margin-top: 6px;" value="Close" onClick="document.getElementById('canvas_email_list').style.display='none';document.getElementById('canvas_email_list_text').style.display='none';document.getElementById('canvas_profile_list').style.display='block';"></button>
</div>
<!-- holds the email address list to be copied to the clipboard -->
<div id="canvas_email_list_text" style="display:none; width:658px; height:450px; color:#000; margin:0px 5px 0px 5px;">
<textarea id="canvas_email_list_textarea" rows="27" cols="78" style="border:1px solid #000; margin: 0px 8px 0px 8px;">
</textarea>
</div>
<div id="canvas_full_list" style="display:none; background:#FFF; width:640px; height:50px; margin-left: 20px;">
Copy and paste the profile data below into an Excel spreadsheet or external text editor.
<input type="button" style="height:22px; font-size:10; margin-left:40px; margin-top: 6px;" value="Close" onClick="document.getElementById('canvas_full_list').style.display='none';document.getElementById('canvas_full_list_text').style.display='none';document.getElementById('canvas_profile_list').style.display='block';"></button>
</div>
<!-- holds the full profile list to be copied to the clipboard -->
<div id="canvas_full_list_text" style="display:none; width:640px; height:450px; color:#000; margin:0px 5px 0px 5px;">
<textarea id="canvas_full_list_textarea" rows="27" cols="78" style="border:1px solid #000; margin: 0px 8px 0px 8px;">
</textarea>
</div>
<!-- holds the visible profile details list -->
<div id="canvas_profile_list" style="display:none; margin-left:20px; height:463px; height:443px\9; width: 660px; overflow:auto;"></div>
<script type="text/javascript">
function init() {
// update UI
showToolVersion(true);
readIdsFromDB(displayProfileList);
document.getElementById("canvas_profile_list").style.display="block";
$("a#create_group").click(function(event){
event.preventDefault();
$("div.message").addClass("hidden");
$("div#create_group").removeClass("hidden");
});
$("input#close").click(function(event){
$("div#create_group").addClass("hidden");
});
$("input#create").click(function(event){
$("div.message").addClass("hidden");
var name = $("div#create_group input#group_name").val();
var description = $("div#create_group #group_description").val();
if(name == null || name == '') {
showMessage("Please enter a group name.", true);
}
else {
osapi.people.getViewer({ fields: ['id'] }).execute(function(result) {
var users = getUserList();
createGroup(name, description, getNodeIdFromURI(result.id), users);
});
}
});
$("#compose-email").click(function(event){
var emails = [];
var emailElem = $("td.email");
if(emailElem.size() > 50) {
if(!confirm("Only the first 50 email addresses can be used. If your list has more, please use the Export function and paste them into email. Do you want to proceed?")) {
event.preventDefault();
return false;
}
}
emailElem.each(function(index, elem) {
var email = $.trim($(elem).text());
if(email != '') {
emails.push(email);
}
if(emails.length >= 50) {
return false;
}
});
if(emails.length > 0) {
$(this).attr("href", "mailto:" + emails.join(';'));
}
});
}
gadgets.util.registerOnLoadHandler(init);
</script>]]></Content>
</Module>

View file

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Hello RDF!" height="800" width="700" scrolling="true">
<Require feature="opensocial-0.8" />
<Require feature="rdf"/>
<Require feature="dynamic-height"/>
</ModulePrefs>
<Content type="html">
<![CDATA[<!--HTML-->
<!DOCTYPE html>
<script type="text/javascript" src="js/jquery-1.4.4.js"></script>
<script type="text/javascript" src="js/prettyprint.js" ></script>
<script type="text/javascript">
// use pretty print!
function loadPeople() {
osapi.people.getViewer().execute(function(result) {
onLoadPeopleOsapi(result, 'viewer');
});
// load RDF version, Alexei, please follow this pattern
osapi.rdf.getViewer().execute(function(result) {
var person = jsonldHelper.getItem(result);
onLoadPeopleRdf(person, 'viewer_rdf');
});
osapi.people.getOwner().execute(function(result) {
onLoadPeopleOsapi(result, 'owner');
document.getElementById('rdfurl').value = result.id;
});
// load RDF version, Alexei, please follow this pattern
var options = {};
options.output = 'full';
osapi.rdf.getOwner(options).execute(function(result) {
var person = jsonldHelper.getItem(result);
onLoadPeopleRdf(person, 'owner_rdf');
});
osapi.rdf.getOwner().execute(function(result) {
var foo = result;
var person = jsonldHelper.getItem(result);
});
}
function onLoadPeopleOsapi(person, divId) {
html = new Array();
html.push('<ul>');
html.push('<li>You are looking at ' + person.displayName + '</li>');
html.push('<li>Their URI is ' + person.profileUrl + '</li>');
html.push('</ul>');
document.getElementById(divId).innerHTML = html.join('');
}
function onLoadPeopleRdf(person, divId) {
html = new Array();
html.push('<ul>');
html.push('<li>You are looking at ' + person.label + '</li>');
html.push('<li>Their URI is ' + (person.uri || person._about) + '</li>');
html.push('<li>Their email is ' + person.primaryEmail + '</li>');
html.push('</ul>');
var ppTable = prettyPrint(person);
$('#' + divId).html(ppTable);
gadgets.window.adjustHeight();
}
var priorurl = [];
var ndx = 0;
priorurl[ndx++] = "http://vivo.ufl.edu/individual/n25562";
priorurl[ndx++] = "http://connects.catalyst.harvard.edu/profiles/profile/person/32213/viewas/rdf";
function submitform() {
var rdfurl = document.getElementById('rdfurl');
if (ndx == 0 || priorurl[ndx] != rdfurl.value) {
priorurl[ndx++] = rdfurl.value;
}
document.getElementById('rdf').innerHTML = '...fetching content...';
osapi.rdf.getRDF(rdfurl.value).execute(function(result) {
onLoadPeopleRdf(result, 'rdf');
});
}
function goback() {
if (ndx > 0 && priorurl[ndx - 1] == document.getElementById('rdfurl').value) {
ndx--;
}
if (ndx > 0) {
ndx--
}
document.getElementById('rdfurl').value = priorurl[ndx];
}
gadgets.util.registerOnLoadHandler(loadPeople);
</script>
<div id='main'>
<h4>Viewer</h4>
<div id='viewer'></div>
<div id='viewer_rdf'></div>
<h4>Owner</h4>
<div id='owner'></div>
<div id='owner_rdf'></div>
<form>
RDF: <input type="text" id="rdfurl" name="rdfurl" size="80">
<p>
<div id="query"></div>
<p>
<a href="javascript: submitform()">Submit</a>&nbsp;<a href="javascript: goback()">Back</a>
</form>
<div id='rdf'></div>
</div> ]]>
</Content>
</Module>

View file

@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Google site search: full text search results XX" width="600">
<Require feature="pubsub" />
<Require feature="dynamic-height" />
</ModulePrefs>
<Content type="html"><![CDATA[<!--HTML-->
<!-- #includes -->
<!DOCTYPE html>
<style>
.gadget_text {
font-family: Verdana, Arial;
font-size: 11px;
}
.gadgets-gadget-chrome {
margin-left: 8px;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<pre><div id="content" class="gadget_text"></div></pre>
<script>
function parseXml(xml) {
if (jQuery.browser.msie) {
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(xml);
xml = xmlDoc;
}
return xml;
}
function handleResponse(obj) {
var ids = [];
var theXML = obj.text;
// IE hack
theXML = parseXml(theXML);
// JB hack
$("#content").append( "Additional search results for " + gadgets.util.getUrlParameters()['keyword'] )
gadgets.window.adjustHeight();
};
function makeRequest(url, postdata) {
var params = {};
postdata = gadgets.io.encodeValues(postdata);
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
gadgets.io.makeRequest(url + "?" + postdata, handleResponse, params);
};
var data = {
start : "0",
num : "30",
q: gadgets.util.getUrlParameters()['keyword'],
// q: "cat",
client : "google-csbe",
output : "xml_no_dtd",
cx : "016654132415451954564:o_v7w23054u"
};
makeRequest("http://www.google.com/search", data);
</script>
]]>
</Content>
</Module>

View file

@ -1,182 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
title="Featured Presentations"
author="Nels Johnson"
author_email="njohnson@downrecs.com"
description="Featured Presentations">
<Require feature="opensocial-0.9" />
<Require feature="pubsub" />
<Require feature="views" />
<Require feature="flash" />
<!-- Require feature="dynamic-height" / -->
<Require feature="osapi" />
</ModulePrefs>
<Content type="html" view="default, home, profile" preferred_height="470" preferred_width="670"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<base target="_blank"/>
<!-- TODO: Fix height for OSDE. Should be removed -->
<!--script type="text/javascript">
gadgets.window.adjustHeight(700);
</script-->
<!-- #includes -->
<link rel="stylesheet" href="css/gadget.css" type="text/css" media="screen, projection">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<script type="text/javascript" src="js/os.js" ></script>
<!-- Styles -->
<style type="text/css">
.slideshare_title { font-family: Arial, helvetica; font-size: 14px;}
.slideshare_body { font-family: Arial, helvetica; font-size: 11px;}
.slideshare_credit { font-family: Arial, helvetica; font-size: 10px;}
.ss-link{ margin:10px 0px 10px 0px; }
a, a:visited { color: #0088CC; text-decoration: none; }
a:hover { color: #005580; text-decoration: underline; }
</style>
<script type="text/javascript">
function gotoSlideshare() {
var action = 'go_to_slideshare';
var href = $('div.ss-link a').attr('href');
gadgets.pubsub.subscribe("analytics", function(sender, message){
if(message.action = action) {
window.top.location.href = href;
}
});
gadgetEventTrack(action, href);
}
function gadgetEventTrack(action, label, value) {
var message = {'action' : action};
if (label) {message.label = label;}
if (value) {message.value = value;}
gadgets.pubsub.publish("analytics", message);
}
// ========================================
function getUserNameAndPreview(userId){
osapi.appdata.get({'userId': userId, 'groupId': '@self', 'appId':'@app', 'fields': ['username']})
.execute(function(response){
var viewer = os.osapi.getViewerFromResult(response);
var username = viewer.username;
$('input[name=username]').val(username);
if(username != null && username != "") { // only render flash if there's a username
preview(username);
}
});
}
// ========================================
// ========================================
function preview(username){
var url = "http://static.slidesharecdn.com/swf/multiwidget.swf";
$('#preview').html(
'<div style="width:577px;margin:auto;">' +
'<object style="margin:0px" width="600" height="428" ' +
' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' +
' codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0"' +
' id="slideshow"' +
'>' +
'<param name="movie" value="http://static.slidesharecdn.com/swf/multiwidget.swf"/>' +
'<param name="allowFullScreen" value="true"/>' +
'<param name="allowScriptAccess" value="always"/>' +
'<param name="flashVars" value="feedurl=user/'+ username + '&widgettitle=Slides%20by%20'+ username +'"/>' +
'<embed src="http://static.slidesharecdn.com/swf/multiwidget.swf" ' +
' name="slideshow" ' +
' flashVars="feedurl=user/'+ username + '&widgettitle=Slides%20by%20'+ username +'"' +
' type="application/x-shockwave-flash"' +
' pluginspage="http://www.adobe.com/go/getflashplayer"' +
' allowscriptaccess="always"' +
' allowfullscreen="true"' +
' width="600" ' +
' height="428">' +
'</embed>' +
'</object>' +
'<div class="ss-link">Having trouble seeing this? <a href="http://www.slideshare.net/'+ username + '" target="_top">View at SlideShare</a><div/>' +
'</div>'
);
$('div.ss-link a').click(function(event){
event.preventDefault();
gotoSlideshare();
}); //click
}
// ========================================
// ========================================
gadgets.util.registerOnLoadHandler(function(){
var viewName=gadgets.views.getCurrentView().getName();
if(viewName=='home'){
var innerDiv=$('#inner_home_settings').html();
$('#settings').html(innerDiv);
$('#secondHeader').show();
getUserNameAndPreview('@viewer');
$('span.save').click(function(){
var username = $('input[name=username]').val();
osapi.appdata.update({'userId': '@viewer', 'groupId': '@self', 'appId':'@app', 'data':{'username':username} })
.execute(function(response){
});
$('#preview').html('');
if(username != null && username != "") {
preview(username);
}
}); //click
}
else{
getUserNameAndPreview('@owner');
}
}); // registerOnLoadHandler
// ========================================
</script>
<div id="secondHeader" style="display:none; margin:0px 10px 0px 10px;">
<span class="slideshare_title"><b>SlideShare: A great way to share presentations</b></span>
</div>
<div id="settings" style="clear:both; margin:0px 10px 0px 10px;">
</div>
<br>
<div id="preview">
</div>
<br><br>
]]>
</Content>
<Content type="html" view="home" preferred_height="670" preferred_width="700"><![CDATA[<!--HTML-->
<div id="inner_home_settings" style="display:none;">
<p class="slideshare_body">
If you already have a SlideShare account and have uploaded presentations, simply follow these steps:<br>
</p>
<p class="slideshare_body" style="padding-left:20px;">
<ol>
<li class="slideshare_body">Enter your SlideShare Username below and click Save/Preview.
Any public presentations that you've uploaded to SlideShare will be shown in the preview below.</li>
<li class="slideshare_body">Make sure these presentations are the ones you want to share on your profile.</li>
<li class="slideshare_body">Click the "Show" link (above, upper right) to make the presentations publicly available within your profile.</li>
<li class="slideshare_body">To remove the presentations, delete your SlideShare Username and click Save/Preview.
Make sure to "Hide" your presentations from the public if you delete your SlideShare Username.</li>
</ol>
</p>
<div class="question">
<span class="slideshare_body">SlideShare Username:&nbsp;</span><input type="text" name="username" style="display:inline;width:20em;">
&nbsp;&nbsp;&nbsp;</span>
<span class="save slideshare_body" style="text-decoration:underline;cursor:pointer;color:#44F; display:inline;" title="Save this Username and preview the presentations.">Save/Preview</span>
<br><br>
<span class="slideshare_body">Don't have a SlideShare account yet?
Go to <a href="http://www.slideshare.net" target="_blank" style="font-size:12px;text-decoration:none; cursor:pointer;color:#44F;" title="Go to the SlideShare Web site">
SlideShare</a> now to create an account and upload presentations.</span>
</div>
</div>
]]>
</Content>
</Module>

View file

@ -1,133 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
title="Tweets"
author="Alexei Vassiliev"
author_email="alexnv@sbcglobal.com"
description="Twitter">
<Require feature="opensocial-0.9" />
<Require feature="pubsub" />
<Require feature="views" />
<Require feature="osapi" />
<Require feature="dynamic-height" />
</ModulePrefs>
<Content type="html" view="default, home, profile"><![CDATA[<!--HTML-->
<!DOCTYPE html>
<!-- #includes -->
<link rel="stylesheet" href="css/gadget.css" type="text/css" media="screen, projection">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<script type="text/javascript" src="js/jquery.blockUI.js"></script>
<script charset="utf-8" src="http://widgets.twimg.com/j/2/widget.js"></script>
<script type="text/javascript" src="js/os.js" ></script>
<script type="text/javascript">
var ucsf = ucsf || {};
ucsf.twitter = {};
ucsf.gadgetEventTrack=function(action, label, value) {
var message = {'action' : action};
if (label) {message.label = label;}
if (value) {message.value = value;}
gadgets.pubsub.publish("analytics", message);
};
ucsf.twitter.getUsername=function(callback) {
osapi.appdata.get({'userId': '@owner', 'groupId': '@self', 'appId':'@app', 'fields': ['twitter_username']})
.execute(function(response){
var viewer = os.osapi.getViewerFromResult(response);
var username = viewer.twitter_username;
if(username != null && username != '' && callback) {
callback(username);
}
});
}
ucsf.twitter.render=function(username) {
$("#twitter-wjs").remove();
$(".twitter-gadget .content").empty();
$(".twitter-gadget .content").append('<a width="520" height="300" class="twitter-timeline" href="https://twitter.com/'+username+'" data-screen-name="'+username+'" data-widget-id="320982656688996353">Tweets by @'+username+'</a>')
var fjs=document.getElementsByTagName("script")[0];
var p=/^http:/.test(document.location)?'http':'https';
js=document.createElement("script");
js.id="twitter-wjs";
js.src=p+"://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);
}
ucsf.twitter.preview=function(widget_id) {
if(widget_id) {
ucsf.twitter.render(widget_id);
}
}
</script>
]]></Content>
<Content type="html" view="profile" preferred_width="670"><![CDATA[<!--HTML-->
<script type="text/javascript">
ucsf.twitter.profilePageInit = function() {
gadgets.window.adjustHeight(300);
ucsf.twitter.getUsername(ucsf.twitter.preview);
}
gadgets.util.registerOnLoadHandler(ucsf.twitter.profilePageInit);
</script>
<!-- Styles -->
<style type="text/css">
.twitter-gadget .content {text-align: center;}
</style>
<div class="twitter-gadget">
<div class="content">
</div>
</div>
]]></Content>
<Content type="html" view="home" preferred_width="700"><![CDATA[<!--HTML-->
<script type="text/javascript">
$(document).ready(function () {
$(".twitter-gadget .save").click(function() {
$(".twitter-gadget").block({ message: "Saving..." });
osapi.appdata.update({'userId': '@owner', 'groupId': '@self', 'appId':'@app', 'data':{'twitter_username':$('.twitter-gadget input').val()} }).execute(function(response){
$(".twitter-gadget").unblock();
});
});
$(".twitter-gadget .preview").click(function() {
var username = $('.twitter-gadget input').val();
if(username != null && username != '') {
$('.twitter-gadget .content').show();
gadgets.window.adjustHeight(350);
ucsf.twitter.preview(username);
}
else {
$('.twitter-gadget .content').hide();
gadgets.window.adjustHeight(50);
}
});
});
ucsf.twitter.homePageInit = function() {
gadgets.window.adjustHeight(50);
ucsf.twitter.getUsername(function(username) {
$('.twitter-gadget input').val(username);
$('.twitter-gadget .content').show();
gadgets.window.adjustHeight(350);
ucsf.twitter.preview(username);
});
}
gadgets.util.registerOnLoadHandler(ucsf.twitter.homePageInit);
</script>
<!-- Styles -->
<style type="text/css">
.twitter-gadget {margin-top: 10px;}
.twitter-gadget input {width: 400px;}
.twitter-gadget .label {margin-right: 10px;font-weight: bold;}
.twitter-gadget .preview, .twitter-gadget .save {margin-left: 10px;color: #3B6394; cursor:pointer;}
.twitter-gadget .content {margin-top: 10px; margin-left: 20px;}
</style>
<div class="twitter-gadget">
<span class="label">Widget Id:</span><input type="text" name="keywords"></input><span class="preview">Preview</span><span class="save">Save</span>
<div class="content" style="display:none">
</div>
</div>
]]></Content>
</Module>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>
</web-app>

View file

@ -1,31 +0,0 @@
-- Add some gadgets to play with ------------------------
--
DELETE FROM `orng_apps`;
INSERT INTO `orng_apps` (`appid`, `name`, `url`, `PersonFilterID`, `enabled`, `channels`) VALUES
(100, 'Search Example', 'http://localhost:8080/sample-gadgets/SearchExample.xml', NULL, 1, NULL),
(101, 'Featured Presentations', 'http://localhost:8080/sample-gadgets/SlideShare.xml', NULL, 1, NULL),
(102, 'Faculty Mentor', 'http://localhost:8080/sample-gadgets/Mentor.xml', NULL, 0, NULL),
(103, 'Websites', 'http://localhost:8080/sample-gadgets/Links.xml', NULL, 1, NULL),
(104, 'Profile List', 'http://localhost:8080/sample-gadgets/ProfileListTool.xml', NULL, 1, 'JSONPersonIds'),
(106, 'RDF Test Gadget', 'http://localhost:8080/sample-gadgets/RDFTest.xml', NULL, 1, NULL),
(112, 'Twitter', 'http://localhost:8080/sample-gadgets/Twitter.xml', NULL, 1, NULL);
DELETE FROM `orng_app_views`;
INSERT INTO `orng_app_views` (`appid`, `viewer_req`, `owner_req`, `page`, `view`, `chromeId`, `opt_params`, `display_order`) VALUES
(100, NULL, NULL, 'search', NULL, 'gadgets-search', NULL, NULL),
(101, NULL, 'R', 'individual', 'profile', 'gadgets-view', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':290}', 4),
(101, NULL, NULL, 'individual-EDIT-MODE', 'home', 'gadgets-edit', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':700}', 4),
(102, NULL, 'R', 'individual', 'profile', 'gadgets-view', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':290}', 3),
(102, NULL, NULL, 'individual-EDIT-MODE', 'home', 'gadgets-edit', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':700}', 3),
(103, NULL, NULL, 'individual-EDIT-MODE', 'home', 'gadgets-edit', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':700}', NULL),
(103, NULL, 'R', 'individual', 'profile', 'gadgets-view', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':0, ''closed_width'':290}', 1),
(104, 'U', NULL, 'search', 'small', 'gadgets-tools', NULL, NULL),
(104, 'U', NULL, 'gadgetDetails', 'canvas', 'gadgets-detail', NULL, NULL),
(104, 'U', NULL, 'individual', 'small', 'gadgets-view', NULL, NULL),
(106, NULL, NULL, 'individual-EDIT-MODE', 'home', 'gadgets-edit', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':700}', NULL),
(112, NULL, 'R', 'individual', 'profile', 'gadgets-view', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':0, ''closed_width'':290}', 2),
(112, NULL, NULL, 'individual-EDIT-MODE', 'home', 'gadgets-edit', '{''gadget_class'':''ORNGToggleGadget'', ''start_closed'':1, ''closed_width'':700}', 2);

View file

@ -1,153 +0,0 @@
--
-- Table structure for table `orng_activity`
--
DROP TABLE IF EXISTS `orng_activity`;
CREATE TABLE `orng_activity` (
`activityId` int(11) NOT NULL AUTO_INCREMENT,
`userId` varchar(255) default NULL,
`appId` int(11) default NULL,
`createdDT` datetime default NULL,
`activity` text,
PRIMARY KEY (`activityId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `orng_appdata`
--
DROP TABLE IF EXISTS `orng_appdata`;
CREATE TABLE `orng_appdata` (
`userId` varchar(255) NOT NULL,
`appId` int(11) NOT NULL,
`keyname` varchar(255) NOT NULL,
`value` varchar(4000) default NULL,
`createdDT` datetime default NULL,
`updatedDT` datetime default NULL,
KEY `userId` (`userId`,`appId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `orng_apps`
--
DROP TABLE IF EXISTS `orng_apps`;
CREATE TABLE `orng_apps` (
`appid` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`PersonFilterID` int(11) default NULL,
`enabled` tinyint(1) NOT NULL default '1',
`channels` varchar(255) default NULL,
PRIMARY KEY (`appid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `orng_app_registry`
--
DROP TABLE IF EXISTS `orng_app_registry`;
CREATE TABLE `orng_app_registry` (
`appid` int(11) NOT NULL,
`personId` varchar(255) NOT NULL,
`createdDT` datetime NOT NULL,
PRIMARY KEY (`appid`, `personId` )
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `orng_app_views`
--
DROP TABLE IF EXISTS `orng_app_views`;
CREATE TABLE `orng_app_views` (
`appid` int(11) NOT NULL,
`viewer_req` char(1) default NULL,
`owner_req` char(1) default NULL,
`page` varchar(50) default NULL,
`view` varchar(50) default NULL,
`chromeId` varchar(50) default NULL,
`display_order` int(11) default NULL,
`opt_params` varchar(255) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `orng_messages`
--
DROP TABLE IF EXISTS `orng_messages`;
CREATE TABLE `orng_messages` (
`msgId` varchar(255) NOT NULL,
`senderId` varchar(255) default NULL,
`recipientId` varchar(255) default NULL,
`coll` varchar(255) default NULL,
`title` varchar(255) default NULL,
`body` varchar(4000) default NULL,
`createdDT` datetime default NULL,
PRIMARY KEY (`msgId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
DROP PROCEDURE IF EXISTS `orng_registerAppPerson`;
DROP PROCEDURE IF EXISTS `orng_upsertAppData`;
DROP PROCEDURE IF EXISTS `orng_deleteAppData`;
DELIMITER //
CREATE PROCEDURE orng_registerAppPerson (uid varchar(255), aid INT, v BOOL)
BEGIN
IF (v)
THEN
INSERT INTO orng_app_registry (appId, personId, createdDT) values (aid, uid, now());
ELSE
DELETE FROM orng_app_registry where appId = aid AND personId = uid;
END IF;
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE orng_upsertAppData(uid varchar(255), aid INT, kn varchar(255),v varchar(4000))
BEGIN
DECLARE cnt int;
SELECT count(*) FROM orng_appdata WHERE userId = uid AND appId = aid and keyname = kn INTO cnt;
IF (cnt > 0)
THEN
UPDATE orng_appdata set `value` = v, updatedDT = NOW() WHERE userId = uid AND appId = aid and keyname = kn;
ELSE
INSERT INTO orng_appdata (userId, appId, keyname, `value`) values (uid, aid, kn, v);
END IF;
-- if keyname is VISIBLE, do more
IF (kn = 'VISIBLE' AND v = 'Y')
THEN
CALL orng_registerAppPerson(uid, aid, 1);
ELSEIF (kn = 'VISIBLE' )
THEN
CALL orng_registerAppPerson(uid, aid, 0);
END IF;
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE orng_deleteAppData(uid varchar(255), aid INT, kn varchar(255))
BEGIN
DELETE FROM orng_appdata WHERE userId = uid AND appId = aid and keyname = kn;
-- if keyname is VISIBLE, do more
IF (kn = 'VISIBLE' )
THEN
CALL orng_registerAppPerson(uid, aid, 0);
END IF;
END //
DELIMITER ;

View file

@ -1,194 +0,0 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
##################################################################
#
# Note from UCSF. Compare this to the latest in shindig-common/conf/shindig.properties
# whenever you download a new version of shindig
#
##################################################################
# Location of feature manifests (comma separated)
shindig.features.default=res://features/features.txt
# Location of container configurations (comma separated)
# In shindigorng this is set automatically to either res://vivo-container.js or res://profiles-container.js based on your orng.system value below!
# Leave this commented out !!!!
#shindig.containers.default=res://containers/default/container.js
# A file containing blacklisted gadgets.
shindig.blacklist.file=
### Inbound OAuth support
# The URL base to use for full OAuth support (three-legged)
shindig.oauth.base-url=/oauth/
shindig.oauth.authorize-action=/WEB-INF/authorize.jsp
### Outbound OAuth support
shindig.signing.state-key=
shindig.signing.key-name=
shindig.signing.key-file=
shindig.signing.global-callback-url=http://localhost:8080/shindigorng/gadgets/oauthcallback
shindig.signing.enable-signed-callbacks=true
# Set to true if you want to allow the use of 3-legged OAuth tokens when viewer != owner.
# This setting is not recommeneded for pages that allow user-controlled javascript, since
# that javascript could be used to make unauthorized requests on behalf of the viewer of the page
shindig.signing.viewer-access-tokens-enabled=false
# If enabled here, configuration values can be found in container configuration files.
shindig.locked-domain.enabled=false
# TODO: This needs to be moved to container configuration.
# Note by Eric. This is set up to now exclude everything and include nothing
shindig.content-rewrite.only-allow-excludes=false
shindig.content-rewrite.include-urls=.*
shindig.content-rewrite.exclude-urls=
shindig.content-rewrite.include-tags=body,embed,img,input,link,script,style
shindig.content-rewrite.expires=86400
shindig.content-rewrite.proxy-url=/shindigorng/gadgets/proxy?container=default&url=
shindig.content-rewrite.concat-url=/shindigorng/gadgets/concat?container=default&
shindig.content-rewrite.enable-split-js-concat=false
#
# Default set of forced libs to allow for better caching
#
# NOTE: setting this causes the EndToEnd test to fail the opensocial-templates test
shindig.gadget-rewrite.default-forced-libs=core:rpc
shindig.gadget-rewrite.default-forced-libs=
#
# Allow supported JavaScript features required by a gadget to be externalized on demand
shindig.gadget-rewrite.externalize-feature-libs=true
# Configuration for image rewriter
shindig.image-rewrite.max-inmem-bytes = 1048576
shindig.image-rewrite.max-palette-size = 256
shindig.image-rewrite.allow-jpeg-conversion = true
shindig.image-rewrite.jpeg-compression = 0.75
shindig.image-rewrite.min-threshold-bytes = 200
# Configuration for the os:Flash tag
shindig.flash.min-version = 9.0.115
# Configuration for template rewriter
shindig.template-rewrite.extension-tag-namespace=http://ns.opensocial.org/2009/extensions
# These values provide default TTLs for HTTP responses that don't use caching headers.
shindig.cache.http.defaultTtl=3600000
shindig.cache.http.negativeCacheTtl=60000
# A default refresh interval for XML files, since there is no natural way for developers to
# specify this value, and most HTTP responses don't include good cache control headers.
shindig.cache.xml.refreshInterval=300000
# Add entries in the form shindig.cache.lru.<name>.capacity to specify capacities for different
# caches when using the LruCacheProvider.
# It is highly recommended that the EhCache implementation be used instead of the LRU cache.
shindig.cache.lru.default.capacity=1000
shindig.cache.lru.expressions.capacity=1000
shindig.cache.lru.gadgetSpecs.capacity=1000
shindig.cache.lru.messageBundles.capacity=1000
shindig.cache.lru.httpResponses.capacity=10000
# The location of the EhCache configuration file.
shindig.cache.ehcache.config=res://org/apache/shindig/common/cache/ehcache/ehcacheConfig.xml
# True to enable JMX integration with cache stats
shindig.cache.ehcache.jmx.enabled=true
# true to enable JMX stats.
shindig.cache.ehcache.jmx.stats=true
# true to skip expensive encoding detection.
# if true, will only attempt to validate utf-8. Assumes all other encodings are ISO-8859-1.
shindig.http.fast-encoding-detection=true
# Configuration for the HttpFetcher
# Connection timeout, in milliseconds, for requests.
shindig.http.client.connection-timeout-ms=5000
# Maximum size, in bytes, of the object we fetched, 0 == no limit
shindig.http.client.max-object-size-bytes=0
# Strict-mode parsing for proxy and concat URIs ensures that the authority/host and path
# for the URIs match precisely what is found in the container config for it. This is
# useful where statistics and traffic routing patterns, typically in large installations,
# key on hostname (and occasionally path). Enforcing this does come at the cost that
# mismatches break, which in turn mandates that URI generation always happen in consistent
# fashion, ie. by the class itself or tightly controlled code.
shindig.uri.proxy.use-strict-parsing=false
shindig.uri.concat.use-strict-parsing=false
# Host:port of the proxy to use while fetching urls. Leave blank if proxy is
# not to be used.
org.apache.shindig.gadgets.http.basicHttpFetcherProxy=
org.apache.shindig.serviceExpirationDurationMinutes=60
#
# Older versions of shindig used 'data' in the json-rpc response format
# The spec calls for using 'result' instead, however to avoid breakage we
# allow you to set it back to the old way here
#
# valid values are
# result - new form
# data - old broken form
# both - return both fields for full compatibility
#
shindig.json-rpc.result-field=result
# Remap "Internal server error"s received from the basicHttpFetcherProxy server to
# "Bad Gateway error"s, so that it is clear to the user that the proxy server is
# the one that threw the exception.
shindig.accelerate.remapInternalServerError=true
shindig.proxy.remapInternalServerError=true
#####################################################################################
#
# Open Research Networking Gadgets Items
#
#####################################################################################
# orng.RDFConverter should be elda. We also currently support babel but it is only being used for test and comparison purposes
# and babel will be phased out
orng.RDFConverter = elda
orng.tokenservice.port = 8777
orng.securityTokenKeyFile = @TOKEN_KEY_FILE@
#
# Note that orng.systemDomain can be commented out in a production environment.
# It is used to trigger system specific (VIVO or Profiles) means for URI to URL conversion.
# This is sometimes necessary when a "fake" domain is being used in a testing/development environment
#
# orng.system must be set to Profiles or VIVO
#orng.system = Profiles
#orng.dbDriver = com.microsoft.sqlserver.jdbc.SQLServerDriver
#orng.dbURL = jdbc:sqlserver://dev-sql-ctsi.ucsf.edu;instanceName=default;portNumber=1433;databaseName=profiles_100
#orng.dbUser = App_Profiles10
#orng.dbPassword = Password1234
#orng.systemDomain = http://localhost/profiles
orng.system = VIVO
orng.dbDriver = @DATA_SOURCE_DRIVER@
orng.dbURL = @DATA_SOURCE_URL@
orng.dbUser = @DATA_SOURCE_USERNAME@
orng.dbPassword = @DATA_SOURCE_PASSWORD@
orng.systemDomain = http://localhost:8080/vivo

Binary file not shown.

View file

@ -1,28 +0,0 @@
Vitro depends on solr. This directory provides a basic installation of solr to be used along side vitro.
solr-4.7.2.war is the exact war as provided by Solr.
additions-to-solr-war contains files that will be are merged into the war by the build script:
log4j.properties
jcl-over-slf4j-1.6.1.jar
jul-to-slf4j-1.6.1.jar
log4j-1.2.16.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
The Solr WAR file does not include logging JARs, assuming that they will be provided
by the supporting container: Tomcat or equivalent. But we want the WAR to be
self-contained, so we provide the JARs. We also want to reduce the amount of logging
messages, so we provide a log4j.properties.
jts-1.13.jar
Don't know.
template.context.xml is the basis for a Tomcat context fragment. The build script will
modify this so it provides a JNDI reference to the Solr home directory, and disables
persistence across Tomcat restarts.
Non-Tomcat containers will likely ignore this.
homeDirectoryTemplate is a modified version of the example home directory provided by Solr.
Don't know what those modifications are, but they certainly include our own version of
conf/schema.xml.

View file

@ -1,192 +0,0 @@
=begin
--------------------------------------------------------------------------------
This script will try to show that the JARs in a list are not needed for VIVO
(or Vitro).
Given a list of JARs, it will determine what packages the JAR contains, and will
search the source files of the project for references to those packages.
The list of JARs should be created by running the jarlist target of the build file.
That will use JarJar to create a list of JAR file that are not directly referenced
by the classes in the build. But what about JARs that are needed by a call using
reflection? Like Class.forName("this.that.theOther"). We know this is how the MySQL
driver is loaded (so we need mysql-connector-java-5.1.16-bin.jar). Are there any
others? This script will try to find them.
The jarlist target includes a list of JARs that we know are needed, such as the MySQL
connector. If this script finds any JARs that are needed, they should be added to that
list, and the target run again, in case they depend on other JARs in turn.
--------------------------------------------------------------------------------
One of the tricks that this script uses is to prune the list of packages to
search for. If a JAR contains both "this.that.other" and "this.that", then we
only need to search for "this.that", since it will reveal uses of "this.that.other"
as well.
--------------------------------------------------------------------------------
pass the name of the file that contains the JAR names
pass the root directory of the combined vitro/vivo distro
(appbase)
--------------------------------------------------------------------------------
Search all of the *.java, *.jsp, *.js, *.tld, *.xml files for mention of these package names
For each hit, print the file path, line number, the package name and the JAR name.
To search files:
find -X . -name \*.db -or -name \*pot | xargs grep 'org\.package\.name'
grep -H -n -f file_with_package_patterns
or can we do this all with grep on each string?
grep -r --include=*.jsp
grep -H -n -r --include=*.javaxd --include=*.jsp org\.package\.name .
and precede the output with a header that lists the package
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
=end
# Just say what we're doing.
#
def print_args
puts "Scanning for JAR usage."
puts "Base directory is #{@scan_base_directory}"
puts "JAR list is in #{@jar_names_file}"
puts
end
# Build a Hash of JAR names mapped to (reduced) arrays of package names.
#
def figure_package_names_from_jars
@packages_for_jars = {}
File.open(@jar_names_file) do |file|
file.each do |line|
jar_name = line.strip
@packages_for_jars[jar_name] = figure_package_names_for_jar(jar_name)
end
end
end
# Figure out the reduced set of package names for this JAR
#
def figure_package_names_for_jar(jar_name)
jar_path = "#{@scan_base_directory}/lib/#{jar_name}"
jar_contents = `jar -tf '#{jar_path}'`
packages = analyze_jar_contents(jar_contents)
reduced = reduce_package_names(packages)
end
# Ask the JAR what it contains. Keep only the names of populated packages.
# Ignore packages that are not at least 2 levels deep.
#
def analyze_jar_contents(jar_contents)
packages = []
jar_contents.lines do |line|
line.strip!
if line.end_with?('/')
elsif line.start_with?('META-INF')
elsif line.count('/') < 2
else
package = line[0...line.rindex('/')].tr('/', '.')
packages << package
end
end
packages.uniq.sort!
end
# Remove the names of any sub-packages. Searching for the parent package will be sufficient.
#
def reduce_package_names(packages)
reduced = []
packages.each do |candidate|
redundant = FALSE
reduced.each do |result|
redundant = TRUE if candidate.start_with?(result)
end
reduced << candidate unless redundant
end
reduced
end
# Show what packages we will search for, and for which JAR
#
def print_package_names_for_jars
puts "Packages for each jar"
@packages_for_jars.each do |jar_name, package_array|
puts " #{jar_name}"
package_array.each do |package_name|
puts " #{package_name}"
end
puts
end
end
#
#
def show_packages_in_source_files
@packages_for_jars.each do |jar_name, package_array|
show_packages_for_jar_in_source_files(jar_name, package_array)
end
end
#
#
def show_packages_for_jar_in_source_files(jar_name, package_array)
puts "------------------------------- #{jar_name} ------------------------------"
package_array.each do |package_name|
show_package_in_source_files(package_name)
end
end
#
#
def show_package_in_source_files(package_name)
puts "#{package_name}"
include_parms = build_include_parms(["*.java", "*.jsp", "*.xml", "*.tld", "*.js" ])
package_name_pattern = package_name.sub(/\./, "\\.")
system "grep -H -n -r #{include_parms} #{package_name_pattern} '#{@scan_base_directory}'"
puts
end
#
#
def build_include_parms(file_specs)
"--include=" + file_specs.join(" --include=")
end
#
#
# ------------------------------------------------------------------------------------
# Standalone calling.
#
# Do this if this program was called from the command line. That is, if the command
# expands to the path of this file.
# ------------------------------------------------------------------------------------
#
if File.expand_path($0) == File.expand_path(__FILE__)
if ARGV.length != 2
raise("usage is: ruby jarUsageScanner.rb <jar_names_file> <scan_base_directory>")
end
@jar_names_file, @scan_base_directory = ARGV
if !File.file?(@jar_names_file)
raise "File does not exist: '#{@jar_names_file}'."
end
if !File.directory?(@scan_base_directory)
raise "Directory does not exist: '#{@scan_base_directory}'."
end
print_args
figure_package_names_from_jars
print_package_names_for_jars
show_packages_in_source_files
end

View file

@ -1,93 +0,0 @@
/**
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class is created to work around a known bug in JarJar which did not get fixed in release 1.1.
* See the comments in edu.cornell.mannlib.vitro.utilities.jarlist.JarLister
*/
package com.tonicsystems.jarjar;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import com.tonicsystems.jarjar.asm.ClassReader;
import com.tonicsystems.jarjar.ext_util.ClassHeaderReader;
import com.tonicsystems.jarjar.ext_util.ClassPathEntry;
import com.tonicsystems.jarjar.ext_util.ClassPathIterator;
import com.tonicsystems.jarjar.ext_util.RuntimeIOException;
public class KlugedDepFind {
private File curDir = new File(System.getProperty("user.dir"));
public void setCurrentDirectory(File curDir) {
this.curDir = curDir;
}
public void run(String from, String to, DepHandler handler)
throws IOException {
try {
ClassHeaderReader header = new ClassHeaderReader();
Map<String, String> classes = new HashMap<String, String>();
ClassPathIterator cp = new ClassPathIterator(curDir, to, null);
try {
while (cp.hasNext()) {
ClassPathEntry entry = cp.next();
InputStream in = entry.openStream();
try {
header.read(in);
classes.put(header.getClassName(), entry.getSource());
} catch (Exception e) {
System.err.println("Error reading " + entry.getName()
+ ": " + e.getMessage());
} finally {
in.close();
}
}
} finally {
cp.close();
}
handler.handleStart();
cp = new ClassPathIterator(curDir, from, null);
try {
while (cp.hasNext()) {
ClassPathEntry entry = cp.next();
InputStream in = entry.openStream();
try {
new ClassReader(in).accept(new DepFindVisitor(classes,
entry.getSource(), handler),
ClassReader.SKIP_DEBUG
| ClassReader.EXPAND_FRAMES);
} catch (Exception e) {
System.err.println("Error reading " + entry.getName()
+ ": " + e.getMessage());
} finally {
in.close();
}
}
} finally {
cp.close();
}
handler.handleEnd();
} catch (RuntimeIOException e) {
throw (IOException) e.getCause();
}
}
}

View file

@ -1,435 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.containerneutral;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServlet;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Look at web.xml, and check for conditions that violate the Servlet 2.4 spec,
* but that might not be noticed because Tomcat doesn't complain.
*
* ------
*
* Values of the <dispatcher/> tag:
*
* The spec permits only these values: "FORWARD", "REQUEST", "INCLUDE", "ERROR",
* but Tomcat also allows the lower-case equivalents. GlassFish or WebLogic will
* barf on lower-case.
*
* Check to see that only the upper-case values are used.
*
* ------
*
* Existence of Servlet classes:
*
* The spec allows the container to either load all servlets at startup, or to
* load them when requested. Since Tomcat only loads servlet when requested, it
* doesn't notice or complain if web.xml cites a <servlet-class/> that doesn't
* exist, as long as it is never invoked. On the other hand, WebLogic loads all
* serlvets at startup, and will barf if the class is not found.
*
* Check each <servlet-class/> to insure that the class can be loaded and
* instantiated and assigned to HttpServlet.
*
* ------
*
* Embedded URIs in taglibs.
*
* I can't find this definitively in the JSP spec, but some containers complain
* if web.xml specifies a <taglib-uri/> that conflicts with the <uri/> embedded
* in the taglib itself. As far as I can see in the spec, the embedded <uri/>
* tag is not required or referenced unless we are using
* "Implicit Map Entries From TLDs", which in turn is only relevant for TLDs
* packaged in JAR files. So, I can't find support for this complaint, but it
* seems a reasonable one.
*
* Check each <taglib/> specified in web.xml. If the taglib has an embedded
* <uri/> tag, it should match the <taglib-uri/> from web.xml.
*
* ------
*
* Existence of Listener and Filter classes.
*
* As far as I can tell, there is no ambiguity here, and every container will
* complain if any of the <listener-class/> or <filter-class/> entries are
* unsuitable. I check them anyway, since the mechanism was already assembled
* for checking <servlet-class/> entries.
*
* Check each <listener-class/> to insure that the class can be loaded and
* instantiated and assigned to ServletContextListener.
*
* Check each <filter-class/> to insure that the class can be loaded and
* instantiated and assigned to Filter.
*
* ------
*
* A <servlet/> tag for every <servlet-mapping/> tag
*
* I can't find a mention of this in the spec, but Tomcat complains and refuses
* to load the app if there is a <servlet-mapping/> tag whose <servlet-name/> is
* not matched by a <servlet-name/> in a <servlet/> tag.
*
* Get sets of all <servlet-name/> tags that are specified in <servlet/> and
* <servlet-mapping/> tags. There should not be any names in the
* servlet-mappings that are not in the servlets.
*
* ---------------------------------------------------------------------
*
* Although this class is executed as a JUnit test, it doesn't have the usual
* structure for a unit test.
*
* In order to produce the most diagnostic information, the test does not abort
* on the first failure. Rather, failure messages are accumulated until all
* checks have been performed, and the test list all such messages on failure.
*
* ---------------------------------------------------------------------
*
* Since this is not executed as part of the standard Vitro unit tests, it also
* cannot use the standard logging mechanism. Log4J has not been initialized.
*
*/
public class CheckContainerNeutrality {
private static final String PROPERTY_WEBAPP_DIR = "CheckContainerNeutrality.webapp.dir";
private static DocumentBuilder docBuilder;
private static XPath xpath;
@BeforeClass
public static void createDocBuilder() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
factory.setNamespaceAware(true); // never forget this!
docBuilder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
}
@BeforeClass
public static void createXPath() {
xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new StupidNamespaceContext());
}
private File webappDir;
private File webXmlFile;
private Document webXmlDoc;
private List<String> messages;
@Before
public void setup() throws SAXException, IOException {
String webappDirPath = System.getProperty(PROPERTY_WEBAPP_DIR);
if (webappDirPath == null) {
fail("System property '" + PROPERTY_WEBAPP_DIR
+ "' was not provided.");
}
webappDir = new File(webappDirPath);
if (!webappDir.isDirectory()) {
fail("'" + webappDirPath + "' is not a directory");
}
webXmlFile = new File(webappDir, "WEB-INF/web.xml");
if (!webXmlFile.isFile()) {
fail("Can't find '" + webXmlFile.getAbsolutePath() + "'");
}
webXmlDoc = docBuilder.parse(webXmlFile);
messages = new ArrayList<String>();
}
// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
@Test
public void checkAll() throws IOException {
checkDispatcherValues();
checkServletClasses();
checkListenerClasses();
checkFilterClasses();
checkTaglibLocations();
checkServletNames();
if (!messages.isEmpty()) {
fail("Found these problems with '" + webXmlFile.getCanonicalPath()
+ "'\n " + StringUtils.join(messages, "\n "));
}
}
private void checkDispatcherValues() {
List<String> okValues = Arrays.asList(new String[] { "FORWARD",
"REQUEST", "INCLUDE", "ERROR" });
for (Node n : findNodes("//j2ee:dispatcher")) {
String text = n.getTextContent();
if (!okValues.contains(text)) {
messages.add("<dispatcher>" + text
+ "</dispatcher> is not valid. Acceptable values are "
+ okValues);
}
}
}
private void checkServletClasses() {
for (Node n : findNodes("//j2ee:servlet-class")) {
String text = n.getTextContent();
String problem = confirmClassNameIsValid(text, HttpServlet.class);
if (problem != null) {
messages.add("<servlet-class>" + text
+ "</servlet-class> is not valid: " + problem);
}
}
}
private void checkListenerClasses() {
for (Node n : findNodes("//j2ee:listener-class")) {
String text = n.getTextContent();
String problem = confirmClassNameIsValid(text,
ServletContextListener.class);
if (problem != null) {
messages.add("<listener-class>" + text
+ "</listener-class> is not valid: " + problem);
}
}
}
private void checkFilterClasses() {
for (Node n : findNodes("//j2ee:filter-class")) {
String text = n.getTextContent();
String problem = confirmClassNameIsValid(text, Filter.class);
if (problem != null) {
messages.add("<filter-class>" + text
+ "</filter-class> is not valid: " + problem);
}
}
}
private void checkTaglibLocations() {
for (Node n : findNodes("//j2ee:jsp-config/j2ee:taglib")) {
String taglibUri = findNode("j2ee:taglib-uri", n).getTextContent();
String taglibLocation = findNode("j2ee:taglib-location", n)
.getTextContent();
// System.out.println("taglibUri='" + taglibUri
// + "', taglibLocation='" + taglibLocation + "'");
String message = checkTaglibUri(taglibUri, taglibLocation);
if (message != null) {
messages.add(message);
}
}
}
private void checkServletNames() {
Set<String> servletNames = new HashSet<String>();
for (Node n : findNodes("//j2ee:servlet/j2ee:servlet-name")) {
servletNames.add(n.getTextContent());
}
Set<String> servletMappingNames = new HashSet<String>();
for (Node n : findNodes("//j2ee:servlet-mapping/j2ee:servlet-name")) {
servletMappingNames.add(n.getTextContent());
}
servletMappingNames.removeAll(servletNames);
for (String name : servletMappingNames) {
messages.add("There is a <servlet-mapping> tag for <servlet-name>"
+ name + "</servlet-name>, but there is "
+ "no matching <servlet> tag.");
}
}
private String checkTaglibUri(String taglibUri, String taglibLocation) {
File taglibFile = new File(webappDir, taglibLocation);
if (!taglibFile.isFile()) {
return "File '" + taglibLocation + "' can't be found ('"
+ taglibFile.getAbsolutePath() + "')";
}
Document taglibDoc;
try {
taglibDoc = docBuilder.parse(taglibFile);
} catch (SAXException e) {
return "Failed to parse the taglib file '" + taglibFile + "': " + e;
} catch (IOException e) {
return "Failed to parse the taglib file '" + taglibFile + "': " + e;
}
List<Node> uriNodes = findNodes("/j2ee:taglib/j2ee:uri",
taglibDoc.getDocumentElement());
// System.out.println("uriNodes: " + uriNodes);
if (uriNodes.isEmpty()) {
return null;
}
if (uriNodes.size() > 1) {
return "taglib '" + taglibLocation + "' contains "
+ uriNodes.size()
+ " <uri> nodes. Expecting no more than 1";
}
String embeddedUri = uriNodes.get(0).getTextContent();
if (taglibUri.equals(embeddedUri)) {
return null;
} else {
return "URI in taglib doesn't match the one in web.xml: taglib='"
+ taglibLocation + "', internal URI='"
+ uriNodes.get(0).getTextContent()
+ "', URI from web.xml='" + taglibUri + "'";
}
}
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
/**
* Search for an Xpath in web.xml, returning a handy list.
*/
private List<Node> findNodes(String pattern) {
return findNodes(pattern, webXmlDoc.getDocumentElement());
}
/**
* Search for an Xpath within a node of web.xml, returning a handy list.
*/
private List<Node> findNodes(String pattern, Node context) {
try {
XPathExpression xpe = xpath.compile(pattern);
NodeList nodes = (NodeList) xpe.evaluate(context,
XPathConstants.NODESET);
List<Node> list = new ArrayList<Node>();
for (int i = 0; i < nodes.getLength(); i++) {
list.add(nodes.item(i));
}
return list;
} catch (XPathExpressionException e) {
throw new RuntimeException(e);
}
}
/**
* Search for an Xpath within a node of web.xml, returning a single node or
* throwing an exception.
*/
private Node findNode(String pattern, Node context) {
List<Node> list = findNodes(pattern, context);
if (list.size() != 1) {
throw new RuntimeException("Expecting 1 node, but found "
+ list.size() + " nodes using '" + pattern + "'");
} else {
return list.get(0);
}
}
/**
* Check that the supplied className can be instantiated with a
* zero-argument constructor, and assigned to a variable of the target
* class.
*/
private String confirmClassNameIsValid(String className,
Class<?> targetClass) {
try {
Class<?> specifiedClass = Class.forName(className);
Object o = specifiedClass.newInstance();
if (!targetClass.isInstance(o)) {
return specifiedClass.getSimpleName()
+ " is not a subclass of "
+ targetClass.getSimpleName() + ".";
}
} catch (ClassNotFoundException e) {
return "The class does not exist.";
} catch (InstantiationException e) {
return "The class does not have a public constructor "
+ "that takes zero arguments.";
} catch (IllegalAccessException e) {
return "The class does not have a public constructor "
+ "that takes zero arguments.";
}
return null;
}
/**
* Dump the first 20 nodes of an XML context, excluding comments and blank
* text nodes.
*/
@SuppressWarnings("unused")
private int dumpXml(Node xmlNode, int... parms) {
int remaining = (parms.length == 0) ? 20 : parms[0];
int level = (parms.length < 2) ? 1 : parms[1];
Node n = xmlNode;
if (Node.COMMENT_NODE == n.getNodeType()) {
return 0;
}
if (Node.TEXT_NODE == n.getNodeType()) {
if (StringUtils.isBlank(n.getTextContent())) {
return 0;
}
}
int used = 1;
System.out.println(StringUtils.repeat("-->", level) + n);
NodeList nl = n.getChildNodes();
for (int i = 0; (i < nl.getLength() && remaining > used); i++) {
used += dumpXml(nl.item(i), remaining - used, level + 1);
}
return used;
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
private static class StupidNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("j2ee".equals(prefix)) {
return "http://java.sun.com/xml/ns/j2ee";
} else {
throw new UnsupportedOperationException();
}
}
@Override
public String getPrefix(String namespaceURI) {
throw new UnsupportedOperationException();
}
@Override
public Iterator<?> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
}

View file

@ -1,198 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.jarlist;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import com.tonicsystems.jarjar.AbstractDepHandler;
import com.tonicsystems.jarjar.DepHandler;
import com.tonicsystems.jarjar.KlugedDepFind;
/**
* This takes the place of the JarJar main routine, in doing a Find operation.
*
* One thing this lets us do is to call KlugedDepFind instead of DepFind.
* KlugedDepFind was created because JarJar had a known bug that wasn't fixed in
* the latest release. (see http://code.google.com/p/jarjar/issues/detail?id=6).
* I had to put KlugedDepFind into the com.tonicsystems.jarjar package so it
* wauld have access to DepFindVisitor, which is package-private.
*
* The other thing we can do is to provide a custom DepHandler which records the
* dependencies directly instead of writing them to a file which we would need
* to parse. Since we have the dependencies in a data structure, it's easy to
* walk the tree and find out what JARs are required, even through several
* layers of dependency.
*
* When calling this, pass 2 arguments. The first is the path to the JAR which
* contains the Vitro (or VIVO) classes. The second is the path to the directory
* that contains the JARs. (shouldn't end with a slash)
*
* There is a list of JARs which we know we need but which aren't shown by the
* analysis. For example, the MySQL driver is loaded dynamically by name, so an
* analysis of the class files in the JARs won't show that it is used. For now,
* these known dependencies are hard-coded, but it would be nice to read them
* from a data file instead.
*/
public class JarLister {
/**
* <pre>
*
* What I originally wanted to do was this:
*
* <target name="jarlist" depends="jar" description="Figure out what JARs are needed">
* <java classname="com.tonicsystems.jarjar.Main" fork="no" failonerror="true">
* <classpath refid="utility.run.classpath" />
* <arg value="find" />
* <arg value="jar" />
* <arg value="${build.dir}/${ant.project.name}.jar" />
* <arg value="${appbase.dir}/lib/*" />
* </java>
* </target>
*
* I ended up with this instead:
*
* <target name="jarlist" depends="jar" description="Figure out what JARs are needed">
* <java classname="edu.cornell.mannlib.vitro.utilities.jarlist.JarLister" fork="no" failonerror="true">
* <classpath refid="utility.run.classpath" />
* <arg value="${build.dir}/${ant.project.name}.jar" />
* <arg value="${appbase.dir}/lib" />
* <arg value="${appbase.dir}/config/jarlist/known_dependencies.txt" />
* </java>
* </target>
*
* </pre>
*/
private final String topJar;
private final String libDirectory;
private final List<String> knownDependencies;
private final Map<String, Set<String>> dependencyMap = new HashMap<String, Set<String>>();
private final Set<String> dependencySet = new TreeSet<String>();
public JarLister(String[] args) throws IOException {
topJar = args[0];
libDirectory = args[1];
knownDependencies = Collections
.unmodifiableList(readKnownDependencies(args[2]));
}
private List<String> readKnownDependencies(String knownDependenciesFilename)
throws IOException {
List<String> list = new ArrayList<String>();
BufferedReader r = new BufferedReader(new FileReader(
knownDependenciesFilename));
String line;
while (null != (line = r.readLine())) {
line = line.trim();
if (!(line.startsWith("#") || line.isEmpty())) {
list.add(line);
}
}
return list;
}
public void runDepFind() throws IOException {
DepHandler handler = new AbstractDepHandler(DepHandler.LEVEL_JAR) {
@Override
public void handle(String from, String to) {
addToMap(from, to);
}
};
String fullPath = topJar + ":" + libDirectory + "/*";
new KlugedDepFind().run(fullPath, fullPath, handler);
}
private void addToMap(String fromPath, String toPath) {
String fromName = new File(fromPath).getName();
String toName = new File(toPath).getName();
if (!dependencyMap.containsKey(fromName)) {
dependencyMap.put(fromName, new HashSet<String>());
}
dependencyMap.get(fromName).add(toName);
// System.out.println("Adding " + fromName + " ==> " + toName);
}
public void populateDependencySet() {
String topJarName = new File(topJar).getName();
addDependenciesFor(topJarName);
for (String known : knownDependencies) {
dependencySet.add(known);
addDependenciesFor(known);
}
}
private void addDependenciesFor(String name) {
if (!dependencyMap.containsKey(name)) {
return;
}
for (String depend : dependencyMap.get(name)) {
if (!dependencySet.contains(depend)) {
dependencySet.add(depend);
// System.out.println("Depend: " + depend);
addDependenciesFor(depend);
}
}
}
public void dumpDependencySet(PrintWriter w) {
w.println("--------------------");
w.println("Known required JARs");
w.println("--------------------");
for (String d : knownDependencies) {
w.println(" " + d);
}
w.println();
w.println("--------------------");
w.println("Dependent JARs");
w.println("--------------------");
for (String d : dependencySet) {
w.println(" " + d);
}
w.println();
File libDir = new File(libDirectory);
SortedSet<String> unused = new TreeSet<String>(Arrays.asList(libDir
.list()));
unused.removeAll(dependencySet);
w.println("--------------------");
w.println("Unused JARs");
w.println("--------------------");
for (String d : unused) {
w.println(" " + d);
}
w.println();
}
public static void main(String[] args) throws IOException {
JarLister jl = new JarLister(args);
jl.runDepFind();
jl.populateDependencySet();
PrintWriter output = new PrintWriter(System.out, true);
jl.dumpDependencySet(output);
output.close();
}
}

View file

@ -1,161 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.revisioninfo;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A harness that runs a system-level command.
*
* No provision is made for standard input.
*
* The standard output and standard error streams are asynchronously read, so
* the sub-process will not block on full buffers. Warning: if either of these
* streams contain more data than can fit into a String, then we will have a
* problem.
*/
public class ProcessRunner {
private int returnCode;
private String stdOut = "";
private String stdErr = "";
private File workingDirectory;
private final Map<String, String> environmentAdditions = new HashMap<String, String>();
/** Set the directory that the command will run in. */
public void setWorkingDirectory(File workingDirectory) {
this.workingDirectory = workingDirectory;
}
/** Add (or replace) any environment variable. */
public void setEnvironmentVariable(String key, String value) {
this.environmentAdditions.put(key, value);
}
/**
* Run the command.
*
* @param command
* a list containing the operating system program and its
* arguments. See
* {@link java.lang.ProcessBuilder#ProcessBuilder(List)}.
*/
public void run(List<String> command) throws ProcessException {
try {
ProcessBuilder builder = new ProcessBuilder(command);
if (workingDirectory != null) {
builder.directory(workingDirectory);
}
if (!environmentAdditions.isEmpty()) {
builder.environment().putAll(this.environmentAdditions);
}
Process process = builder.start();
StreamEater outputEater = new StreamEater(process.getInputStream());
StreamEater errorEater = new StreamEater(process.getErrorStream());
this.returnCode = process.waitFor();
outputEater.join();
this.stdOut = outputEater.getContents();
errorEater.join();
this.stdErr = errorEater.getContents();
} catch (IOException e) {
throw new ProcessException("Exception when handling sub-process:",
e);
} catch (InterruptedException e) {
throw new ProcessException("Exception when handling sub-process:",
e);
}
}
public int getReturnCode() {
return returnCode;
}
public String getStdErr() {
return stdErr;
}
public String getStdOut() {
return stdOut;
}
/**
* A thread that reads an InputStream until it reaches end of file, then
* closes the stream.
*/
private static class StreamEater extends Thread {
private final InputStream stream;
private final StringWriter contents = new StringWriter();
private final byte[] buffer = new byte[4096];
public StreamEater(InputStream stream) {
this.stream = stream;
this.start();
}
@Override
public void run() {
try {
int howMany = 0;
while (true) {
howMany = stream.read(buffer);
if (howMany > 0) {
contents.write(new String(buffer, 0, howMany));
} else if (howMany == 0) {
Thread.yield();
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getContents() {
return contents.toString();
}
}
/**
* Indicates a problem when dealing with a spawned sub-process.
*/
public static class ProcessException extends Exception {
public ProcessException() {
}
public ProcessException(String message) {
super(message);
}
public ProcessException(Throwable cause) {
super(cause);
}
public ProcessException(String message, Throwable cause) {
super(message, cause);
}
}
}

View file

@ -1,253 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.revisioninfo;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import edu.cornell.mannlib.vitro.utilities.revisioninfo.ProcessRunner.ProcessException;
/**
* Get release and revision information to display on screen. Put this
* information into a single line and append it to the specified file.
*
* Ask Git for the information. If Git is available, and if this is a working
* directory, then we can build the info from the responses we get from
* "git describe", "git symbolic-ref" and "git log".
*
* If that doesn't work, read the information from the "revisionInfo" file in
* the product directory. Presumably, that file was created when the source was
* exported from Git.
*
* If that doesn't work either, return something like this:
* "productName ~ unknown ~ unknown"
*/
public class RevisionInfoBuilder {
/**
* Indicates a problem with the command-line arguments.
*/
private static class UsageException extends Exception {
UsageException(String message) {
super(message);
}
}
/**
* An object that holds the revision information and a message about how we
* obtained it.
*/
private static class Results {
final String message;
final String infoLine;
Results(String message, String infoLine) {
this.message = message;
this.infoLine = infoLine;
}
@Override
public String toString() {
return message + ": " + infoLine;
}
}
private static final String GIT_DIRECTORY_NAME = ".git";
private static final String[] GIT_DESCRIBE_COMMAND = { "git", "describe" };
private static final String[] GIT_SREF_COMMAND = { "git", "symbolic-ref",
"HEAD" };
private static final String[] GIT_LOG_COMMAND = { "git", "log",
"--pretty=format:%h", "-1" };
private static final String INFO_LINE_DELIMITER = " ~ ";
private static final String REVISION_INFO_FILENAME = "revisionInfo";
private final String productName;
private final File productDirectory;
private final File resultFile;
private Results results;
public RevisionInfoBuilder(String[] args) throws UsageException {
if (args.length != 3) {
throw new UsageException(
"RevisionInfoBuilder requires 3 arguments, not "
+ args.length);
}
productName = args[0];
productDirectory = new File(args[1]);
resultFile = new File(args[2]);
if (!productDirectory.isDirectory()) {
throw new UsageException("Directory '"
+ productDirectory.getAbsolutePath() + "' does not exist.");
}
if (!resultFile.getParentFile().exists()) {
throw new UsageException("Result file '"
+ resultFile.getAbsolutePath()
+ "' does not exist, and we can't create it "
+ "because it's parent directory doesn't exist either.");
}
}
private void buildInfo() {
results = buildInfoFromGit();
if (results == null) {
results = buildInfoFromFile();
}
if (results == null) {
results = buildDummyInfo();
}
}
private Results buildInfoFromGit() {
if (!isThisAGitWorkspace()) {
System.out.println("Not a git workspace");
return null;
}
String release = assembleReleaseNameFromGit();
if (release == null) {
System.out.println("Couldn't get release name from Git");
}
String revision = obtainCommitIdFromGit();
if (revision == null) {
System.out.println("Couldn't get commit ID from Git");
}
if ((revision == null) && (release == null)) {
return null;
}
return new Results("Info from Git", buildLine(release, revision));
}
private boolean isThisAGitWorkspace() {
File gitDirectory = new File(productDirectory, GIT_DIRECTORY_NAME);
return gitDirectory.isDirectory();
}
private String assembleReleaseNameFromGit() {
String describeResponse = runSubProcess(GIT_DESCRIBE_COMMAND);
String srefResponse = runSubProcess(GIT_SREF_COMMAND);
return parseReleaseName(describeResponse, srefResponse);
}
private String obtainCommitIdFromGit() {
String logResponse = runSubProcess(GIT_LOG_COMMAND);
return parseLogResponse(logResponse);
}
private String parseReleaseName(String describeResponse, String srefResponse) {
if (describeResponse != null) {
return describeResponse.trim() + " tag";
} else if (srefResponse != null) {
return srefResponse.substring(srefResponse.lastIndexOf('/') + 1)
.trim() + " branch";
} else {
return null;
}
}
private String parseLogResponse(String logResponse) {
return logResponse;
}
private String runSubProcess(String[] cmdArray) {
List<String> command = Arrays.asList(cmdArray);
try {
ProcessRunner runner = new ProcessRunner();
runner.setWorkingDirectory(productDirectory);
runner.run(command);
int rc = runner.getReturnCode();
if (rc != 0) {
throw new ProcessRunner.ProcessException("Return code from "
+ command + " was " + rc);
}
String output = runner.getStdOut();
// System.err.println(command + " response was '" + output + "'");
return output;
} catch (ProcessException e) {
// System.out.println(e);
return null;
}
}
private Results buildInfoFromFile() {
try {
File revisionInfoFile = new File(productDirectory,
REVISION_INFO_FILENAME);
BufferedReader reader = new BufferedReader(new FileReader(
revisionInfoFile));
String release = reader.readLine();
if (release == null) {
throw new EOFException("No release line in file.");
}
String revision = reader.readLine();
if (revision == null) {
throw new EOFException("No revision line in file.");
}
return new Results("Info from file", buildLine(release, revision));
} catch (IOException e) {
System.out.println("No information from file: " + e);
return null;
}
}
private Results buildDummyInfo() {
String line = buildLine(null, null);
return new Results("Using dummy info", line);
}
private String buildLine(String release, String revision) {
if (release == null) {
release = "unknown";
}
if (revision == null) {
revision = "unknown";
}
return productName + INFO_LINE_DELIMITER + release.trim()
+ INFO_LINE_DELIMITER + revision.trim();
}
private void writeLine() throws IOException {
Writer writer = null;
writer = new FileWriter(resultFile, true);
writer.write(results.infoLine + "\n");
writer.close();
System.out.println(results);
}
public static void main(String[] args) {
try {
RevisionInfoBuilder builder = new RevisionInfoBuilder(args);
builder.buildInfo();
builder.writeLine();
} catch (UsageException e) {
System.err.println(e);
System.err.println("usage: RevisionInfoBuilder [product_name] "
+ "[product_directory] [output_file]");
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}

View file

@ -1,346 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testing;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.BRIEF;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.FULL;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.MORE;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel;
/**
* Listen to events as they come from the JUnit test runner. The events from the
* lifecycle methods are broken down into semantic chunks and executed. Three
* levels of output are available.
*
* On the surface, JUnit treats "failures" (failed assertions) the same as
* "errors" (unexpected exceptions). We're going to distinguish between them.
*
* @author jeb228
*/
public class VitroTestRunListener extends RunListener {
private final ReportLevel reportLevel;
private int classCount;
private int testsTotal;
private int errorsTotal;
private int failuresTotal;
private int ignoresTotal;
private long overallStartTime;
private Class<?> currentClass;
private int testsCurrentClass;
private int errorsCurrentClass;
private int failuresCurrentClass;
private int ignoresCurrentClass;
private long classStartTime;
private String currentTest;
private boolean testHadError;
private boolean testFailed;
private boolean testIgnored;
private long testStartTime;
public VitroTestRunListener(ReportLevel reportLevel) {
this.reportLevel = reportLevel;
}
/** Did any of the tests fail or have errors? */
public boolean didEverythingPass() {
return (failuresTotal == 0) && (errorsTotal == 0);
}
// -------------------------------------------------------------------------
// Life-cycle methods that will be called by the test runner.
// -------------------------------------------------------------------------
@Override
public void testRunStarted(Description description) throws Exception {
openTestRun();
reportTestRunStart();
}
@Override
public void testStarted(Description description) throws Exception {
if (currentClass != description.getTestClass()) {
if (currentClass != null) {
closeCurrentClass();
reportCurrentClass();
}
openCurrentClass(description);
reportCurrentClassStart();
}
openCurrentTest(description);
}
@Override
public void testAssumptionFailure(Failure failure) {
if (isError(failure)) {
testHadError = true;
reportError(failure);
} else {
testFailed = true;
reportFailure(failure);
}
}
@Override
public void testFailure(Failure failure) throws Exception {
if (isError(failure)) {
testHadError = true;
reportError(failure);
} else {
testFailed = true;
reportFailure(failure);
}
}
@Override
public void testFinished(Description description) throws Exception {
closeCurrentTest();
reportCurrentTest();
}
@Override
public void testIgnored(Description description) throws Exception {
testStarted(description);
testIgnored = true;
testFinished(description);
}
@Override
public void testRunFinished(Result result) throws Exception {
if (currentClass != null) {
closeCurrentClass();
reportCurrentClass();
}
closeTestRun();
reportTestRun();
System.out.println();
}
// -------------------------------------------------------------------------
// Handling the logical events.
// -------------------------------------------------------------------------
private void openTestRun() {
overallStartTime = System.currentTimeMillis();
}
private void closeTestRun() {
// Nothing to close.
}
private void reportTestRunStart() {
if (reportLevel == FULL) {
System.out
.println("Starting test run at " + time(overallStartTime));
System.out.println();
}
if (reportLevel == MORE) {
System.out
.println("Starting test run at " + time(overallStartTime));
System.out.println();
System.out.println("Tests Pass Error Fail Ignore Seconds");
}
}
private void reportTestRun() {
int successes = testsTotal - errorsTotal - failuresTotal - ignoresTotal;
if (reportLevel != BRIEF) {
System.out.println();
}
System.out.format(
"Tests Pass Error Fail Ignore Seconds TOTAL (%d classes)\n",
classCount);
System.out.format(" %4d %4d %4d %4d %4d %6s\n", testsTotal,
successes, errorsTotal, failuresTotal, ignoresTotal,
elapsed(overallStartTime));
if (reportLevel != BRIEF) {
System.out.println("Ending test run at "
+ time(System.currentTimeMillis()));
}
}
private void openCurrentClass(Description description) {
currentClass = description.getTestClass();
classStartTime = System.currentTimeMillis();
testsCurrentClass = 0;
errorsCurrentClass = 0;
failuresCurrentClass = 0;
ignoresCurrentClass = 0;
}
private void closeCurrentClass() {
classCount++;
testsTotal += testsCurrentClass;
errorsTotal += errorsCurrentClass;
failuresTotal += failuresCurrentClass;
ignoresTotal += ignoresCurrentClass;
}
private void reportCurrentClassStart() {
if (reportLevel == FULL) {
System.out.format("Tests Pass Error Fail Ignore Seconds %s\n",
currentClass.getName());
}
}
private void reportCurrentClass() {
int successes = testsCurrentClass - errorsCurrentClass
- failuresCurrentClass - ignoresCurrentClass;
if (reportLevel == MORE) {
System.out.format(" %4d %4d %4d %4d %4d %6s %s\n",
testsCurrentClass, successes, errorsCurrentClass,
failuresCurrentClass, ignoresCurrentClass,
elapsed(classStartTime), currentClass.getSimpleName());
}
if (reportLevel == FULL) {
System.out.println("-----------------------------------");
System.out.format(" %4d %4d %4d %4d %4d %6s\n",
testsCurrentClass, successes, errorsCurrentClass,
failuresCurrentClass, ignoresCurrentClass,
elapsed(classStartTime));
System.out.println();
}
}
private void openCurrentTest(Description description) {
currentTest = description.getMethodName();
testHadError = false;
testFailed = false;
testIgnored = false;
testStartTime = System.currentTimeMillis();
}
private void closeCurrentTest() {
if (testHadError) {
errorsCurrentClass++;
}
if (testFailed) {
failuresCurrentClass++;
}
if (testIgnored) {
ignoresCurrentClass++;
}
testsCurrentClass++;
}
private boolean isError(Failure failure) {
Throwable throwable = failure.getException();
return (throwable != null) && !(throwable instanceof AssertionError);
}
private void reportError(Failure error) {
Description description = error.getDescription();
String methodName = description.getMethodName();
String className = description.getTestClass().getName();
String message = error.getMessage();
System.out.format("EXCEPTION: test %s() in %s: %s\n",
methodName, className, message);
System.out.println(formatStackTrace(error.getException()));
}
private void reportFailure(Failure failure) {
Description description = failure.getDescription();
String methodName = description.getMethodName();
String className = description.getTestClass().getName();
String message = failure.getMessage();
System.out.format("TEST FAILED: test %s() in %s: %s\n", methodName,
className, message);
}
private void reportCurrentTest() {
if (reportLevel == FULL) {
char passFlag = (testIgnored | testFailed | testHadError) ? ' '
: '1';
char errorFlag = testHadError ? '1' : ' ';
char failFlag = testFailed ? '1' : ' ';
char ignoreFlag = testIgnored ? '1' : ' ';
System.out.format(
" %c %c %c %c %6s %s()\n",
passFlag, errorFlag, failFlag, ignoreFlag,
elapsed(testStartTime), currentTest);
}
}
// -------------------------------------------------------------------------
// Formatting methods.
// -------------------------------------------------------------------------
private final SimpleDateFormat formatter = new SimpleDateFormat(
"HH:mm:ss 'on' MMM dd, yyyy");
private String time(long time) {
return formatter.format(new Date(time));
}
/** Show elapsed time in 6 columns. */
private String elapsed(long start) {
long interval = System.currentTimeMillis() - start;
return String.format("%6.2f", ((float) interval) / 1000.0);
}
/**
* Trim the stack trace: don't show the line saying "23 more", and don't
* show the lines about org.junit or java.lang.reflect or sun.reflect.
*
* Once we hit some "client code", we won't trim any futher lines even if
* they belong to org.junit, or the others.
*
* If we have nested exceptions, the process repeats for each "Caused by"
* section.
*/
private String formatStackTrace(Throwable throwable) {
StringWriter w = new StringWriter();
throwable.printStackTrace(new PrintWriter(w));
String[] lineArray = w.toString().split("\\n");
List<String> lines = new ArrayList<String>(Arrays.asList(lineArray));
boolean removing = true;
for (int i = lines.size() - 1; i > 0; i--) {
String line = lines.get(i);
if (removing) {
if (line.matches("\\s*[\\.\\s\\d]+more\\s*")
|| line.contains("at "
+ VitroTestRunner.class.getName())
|| line.contains("at org.junit.")
|| line.contains("at java.lang.reflect.")
|| line.contains("at sun.reflect.")) {
lines.remove(line);
} else {
removing = false;
}
} else {
if (line.contains("Caused by: ")) {
removing = true;
}
}
}
StringBuilder result = new StringBuilder();
for (String line : lines) {
result.append(line).append('\n');
}
return result.toString().trim();
}
}

View file

@ -1,153 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testing;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.junit.runner.JUnitCore;
/**
* A Java application that will run the Vitro unit tests. It searches for unit
* tests in the supplied source directory (any file whose name is *Test.Java).
* It runs the tests with a variety of reporting detail, depending on the level
* selected. If the level selector is absent or unrecognized, the medium level
* is used.
*
* @author jeb228
*/
public class VitroTestRunner {
public enum ReportLevel {
/** Report only the one-line summary. */
BRIEF,
/** Report times and statistics for each test class. */
MORE,
/** Report times and statistics for each test method. */
FULL
}
private final List<Class<?>> classes;
private final VitroTestRunListener listener;
/**
* Locate the test classes. Initialize the test listener.
*/
public VitroTestRunner(File sourceRootDir, ReportLevel reportLevel) {
List<String> classNames = getListOfTestClassNames(sourceRootDir);
this.classes = getTestClasses(classNames);
this.listener = new VitroTestRunListener(reportLevel);
}
/**
* Start a recursive search through the source directory.
*/
private List<String> getListOfTestClassNames(File sourceRootDir) {
SortedSet<String> names = new TreeSet<String>();
searchForTestClasses(names, "", sourceRootDir);
return new ArrayList<String>(names);
}
/**
* Recursively search the directory for files in the form "*Test.java".
* Ignore any files or directories whose names start with a "."
*/
private void searchForTestClasses(SortedSet<String> names, String prefix,
File directory) {
for (File file : directory.listFiles()) {
String filename = file.getName();
if (filename.startsWith(".")) {
// ignore .svn, etc.
} else if (file.isDirectory()) {
searchForTestClasses(names, prefix + filename + ".", file);
} else if (filename.endsWith("Test.java")) {
String classname = filename.substring(0, filename.length() - 5);
names.add(prefix + classname);
}
}
}
/**
* Instantiate a class for each test class name.
*/
private List<Class<?>> getTestClasses(List<String> classNames) {
List<Class<?>> classes = new ArrayList<Class<?>>();
for (String classname : classNames) {
try {
classes.add(Class.forName(classname));
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Can't load test class: "
+ classname, e);
}
}
return classes;
}
/**
* We've located all of the test clases. Now run them.
*/
private void run() {
JUnitCore junitCore = new JUnitCore();
junitCore.addListener(this.listener);
junitCore.run(this.classes.toArray(new Class<?>[0]));
}
/**
* Did any of the tests fail?
*/
private boolean didEverythingPass() {
return this.listener.didEverythingPass();
}
/**
* <p>
* You must provide a path to the source directory of the test classes.
* </p>
* <p>
* You may also provide a reporting level of "BRIEF", "MORE", or "FULL". If
* no level is provided, or if it is not recognized, "BRIEF" is used.
* </p>
*/
public static void main(String[] args) {
if ((args.length < 1) || (args.length > 2)) {
usage("Wrong number of arguments: expecting 1 or 2, but found "
+ args.length + ".");
}
File sourceRootDir = new File(args[0]);
if (!sourceRootDir.exists()) {
usage(sourceRootDir + " does not exist.");
}
if (!sourceRootDir.isDirectory()) {
usage(sourceRootDir + " is not a directory.");
}
ReportLevel reportLevel = ReportLevel.MORE;
if (args.length == 2) {
for (ReportLevel level : ReportLevel.values()) {
if (level.toString().equalsIgnoreCase(args[1])) {
reportLevel = level;
}
}
}
VitroTestRunner runner = new VitroTestRunner(sourceRootDir, reportLevel);
runner.run();
if (!runner.didEverythingPass()) {
System.exit(1);
}
}
/**
* Tell them how it should have been done.
*/
private static void usage(String message) {
System.out.println(message);
System.out.println("usage: " + VitroTestRunner.class.getSimpleName()
+ " sourceRootDirectory [ BRIEF | MORE | FULL ]");
System.exit(1);
}
}

View file

@ -1,300 +0,0 @@
=begin
--------------------------------------------------------------------------------
Scan the source directory, checking for expected "magic license tags",
or
Copy the source directory, inserting licensing information into the files.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
=end
$: << File.dirname(File.expand_path(__FILE__))
require 'date'
require 'fileutils'
require 'pathname'
require 'property_file_reader'
require 'licenser_stats'
class Licenser
MAGIC_STRING = '$This file is distributed under the terms of the license in LICENSE$'
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
#
# Some paths in the properties file, if they are relative, should be relative to the
# properties file itself.
def relative_to_properties(properties, key)
path = properties[key]
base = File.dirname(properties['properties_file_path'])
return nil if path == nil
return File.expand_path(path) if Pathname.new(path).absolute?
return File.expand_path(File.join(base, path))
end
# Some paths in the properties file, if they are relative, should be relative to the
# source directory.
def relative_to_source(properties, key)
path = properties[key]
base = @source_dir ? @source_dir : ''
return nil if path == nil
return path if Pathname.new(path).absolute?
return File.expand_path(File.join(base, path))
end
# Confirm that the parameters are reasonable.
#
def sanity_checks_on_parameters()
# Check that all necessary properties are here.
raise("Properties file must contain a value for 'source_dir'") if @source_dir == nil
raise("Properties file must contain a value for 'known_exceptions'") if @known_exceptions_file == nil
raise("Properties file must contain a value for 'skip_directories'") if @skip_directories_list == nil
raise("Properties file must contain a value for 'file_matchers'") if @file_match_list == nil
raise("Properties file must contain a value for 'report_level'") if @report_level_string == nil
if !File.exist?(@source_dir)
raise "Source directory does not exist: #{@source_dir}"
end
if !File.exist?(@known_exceptions_file)
raise "Known exceptions file does not exist: #{@known_exceptions_file}"
end
end
# The globs in the exceptions file are assumed to be
# relative to the source directory. Make them explicitly so.
#
# Ignore any blank lines or lines that start with a '#'
#
def prepare_exception_globs(exceptions_file, source_dir)
source_path = File.expand_path(source_dir)
globs = []
File.open(exceptions_file) do |file|
file.each do |line|
glob = line.strip
if (glob.length > 0) && (glob[0..0] != '#')
globs << "#{source_path}/#{glob}".gsub('//', '/')
end
end
end
return globs
end
# Recursively scan this directory, and copy if we are not scan-only.
#
def scan_dir(source_dir, target_dir)
@stats.enter_directory(source_dir)
Dir.foreach(File.join(@source_dir, source_dir)) do |filename|
source_path_relative = File.join(source_dir, filename)
source_path = File.join(@source_dir, source_path_relative)
target_path_relative = File.join(target_dir, filename)
target_path = File.join(@target_dir, target_path_relative)
# What kind of beast is this?
if filename == '.' || filename == '..'
is_skipped_directory = true
else
if File.directory?(source_path)
if (path_matches_skipped?(source_path_relative))
is_skipped_directory = true
else
is_directory = true
end
else
if filename_matches_pattern?(filename)
if path_matches_exception?(source_path_relative)
is_exception = true
else
is_match = true
end
else
is_ignored = true
end
end
end
if is_skipped_directory
# do nothing
elsif is_directory
scan_dir(source_path_relative, target_path_relative)
elsif is_match
@stats.record_scan_matching(filename)
scan_file(source_path, filename)
elsif is_exception
@stats.record_known_exception(filename)
else # not a match
@stats.record_scan_non_matching(filename)
end
end
end
# Is this directory one of the skipped?
#
def path_matches_skipped?(relative_path)
@skip_directories.each do |glob|
return true if File.fnmatch(glob, relative_path)
end
return false
end
# Does this file path match any of the exceptions?
#
def path_matches_exception?(relative_path)
path = File.expand_path(File.join(@source_dir, relative_path))
@known_exceptions.each do |pattern|
return true if File.fnmatch(pattern, path)
end
return false
end
# Does this filename match any of the patterns?
#
def filename_matches_pattern?(filename)
@file_matchers.each do |pattern|
return true if File.fnmatch(pattern, filename)
end
return false
end
# This file should contain a license tag.
#
def scan_file(source_path, filename)
found = 0
File.open(source_path) do |source_file|
source_file.each do |line|
if line.include?(MAGIC_STRING)
found += 1
end
end
end
if found == 0
@stats.record_no_tag(filename, source_path)
elsif found == 1
@stats.record_tag(filename)
else
raise("File contains #{found} license lines: #{source_path}")
end
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
# Setup and get ready to process.
#
# * properties is a map of keys to values, probably parsed from a properties file.
#
def initialize(properties)
@file_match_list = properties['file_matchers']
@skip_directories_list = properties['skip_directories']
@report_level_string = properties['report_level']
# These properties contain paths, and if they are relative paths, they
# should be relative to the properties file itself.
@source_dir = relative_to_properties(properties, 'source_dir')
@target_dir = relative_to_properties(properties, 'target_dir')
# These properties contain paths, and if they are relative paths, they
# should be relative to the source_directory.
@license_file = relative_to_source(properties, 'license_file')
@known_exceptions_file = relative_to_source(properties, 'known_exceptions')
sanity_checks_on_parameters()
@full_report = @report_level_string === 'full'
@short_report = @report_level_string === 'short'
@file_matchers = @file_match_list.strip.split(/,\s*/)
@skip_directories = @skip_directories_list.strip.split(/,\s*/)
@known_exceptions = prepare_exception_globs(@known_exceptions_file, @source_dir)
@stats = LicenserStats.new(@source_dir, @file_matchers, @full_report)
end
# Start the recursive scanning (and copying).
def process()
scan_dir('.', '.')
end
# Report the summary statistics
def report(properties)
if (@short_report)
tags = 0
@stats.tagged_files.each {|line| tags += line[1] }
known = 0
@stats.known_exceptions.each {|line| known += line[1] }
missing = 0
@stats.missing_tags.each {|line| missing += line[1] }
puts "Licenser: scanned #{@stats.file_count} files in #{@stats.dir_count} directories."
printf(" Licensed files: %5d\n", tags)
printf(" Known exceptions: %5d\n", known)
printf(" Missing tags: %5d\n", missing)
else
puts "Licenser: run completed at #{DateTime.now.strftime("%H:%M:%S on %b %d, %Y")}"
puts " scanned #{@stats.file_count} files in #{@stats.dir_count} directories."
puts
puts 'Licensed files'
@stats.tagged_files.sort.each do |line|
printf("%5d %s\n", line[1], line[0])
end
puts
puts 'Known non-licensed files'
@stats.known_exceptions.sort.each do |line|
printf("%5d %s\n", line[1], line[0])
end
puts
puts 'Missing tags'
@stats.missing_tags.sort.each do |line|
printf("%5d %s\n", line[1], line[0])
end
puts
puts 'properties:'
properties.each do |key, value|
puts " #{key} = #{value}"
end
end
end
# Were we successful or not?
def success?
return @stats.missing_tags.empty?
end
end
#
#
# ------------------------------------------------------------------------------------
# Standalone calling.
#
# Do this if this program was called from the command line. That is, if the command
# expands to the path of this file.
# ------------------------------------------------------------------------------------
#
if File.expand_path($0) == File.expand_path(__FILE__)
if ARGV.length == 0
raise("No arguments - usage is: ruby licenser.rb <properties_file>")
end
if !File.file?(ARGV[0])
raise "File does not exist: '#{ARGV[0]}'."
end
properties = PropertyFileReader.read(ARGV[0])
l = Licenser.new(properties)
l.process
l.report(properties)
if l.success?
puts "Licenser was successful."
exit 0
else
puts "Licenser found problems."
exit 1
end
end

View file

@ -1,95 +0,0 @@
=begin
--------------------------------------------------------------------------------
Collect the statistics of a licenser run.
--------------------------------------------------------------------------------
=end
class LicenserStats
attr_reader :tagged_files
attr_reader :missing_tags
attr_reader :known_exceptions
attr_reader :file_count
attr_reader :dir_count
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
#
def which_match(filename)
@file_matchers.each do |matcher|
return matcher if File.fnmatch(matcher, filename)
end
raise("filename matches no matchers!: #{filename}")
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(root_dir, file_matchers, full)
@root_dir = "#{root_dir}/".gsub('//', '/')
@file_matchers = file_matchers
@full = full
# keep track of how many tags are found in all file types
@tagged_files = Hash.new()
file_matchers.each do |matcher|
@tagged_files[matcher] = 0
end
# keep track of missing tags, only in file types that have missing tags
@missing_tags = Hash.new(0)
# keep track of how many known non-licensed files we encounter, and what types.
@known_exceptions = Hash.new(0)
# keep track of how many files are copied
@file_count = 0
#keep track of how many directories are copied
@dir_count = 0
end
def enter_directory(path)
@dir_count += 1
puts "Entering directory: #{path}" if @full
end
def record_scan_non_matching(filename)
@file_count += 1
puts " Scan without mods: #{filename}" if @full
end
def record_copy_non_matching(filename)
@file_count += 1
puts " Copy without mods: #{filename}" if @full
end
def record_scan_matching(filename)
@file_count += 1
puts " Scan with mods: #{filename}" if @full
end
def record_copy_matching(filename)
@file_count += 1
puts " Copy with mods: #{filename}" if @full
end
def record_known_exception(filename)
@file_count += 1
puts " Known exception: #{filename}" if @full
@known_exceptions[which_match(filename)] += 1
end
def record_tag(filename)
puts " Found license tag into #{filename}" if @full
@tagged_files[which_match(filename)] += 1
end
def record_no_tag(filename, source_path)
puts "ERROR: Found no license tag in #{source_path.sub(@root_dir, '')}"
@missing_tags[which_match(filename)] += 1
end
end

View file

@ -1,39 +0,0 @@
=begin
--------------------------------------------------------------------------------
A utility class that reads a properties file and returns a hash containing the
properties.
--------------------------------------------------------------------------------
=end
class PropertyFileReader
# Read a properties file and return a hash.
#
# Parameters: the path to the properties file
#
# The hash includes the special property "properties_file_path", which holds
# the path to the properties file.
#
def self.read(file_path)
properties = {}
properties["properties_file_path"] = File.expand_path(file_path)
File.open(file_path) do |file|
file.each_line do |line|
line.strip!
if line.length == 0 || line[0] == ?# || line[0] == ?!
# ignore blank lines, and lines starting with '#' or '!'.
elsif line =~ /(.*?)\s*[=:]\s*(.*)/
# key and value are separated by '=' or ':' and optional whitespace.
properties[$1.strip] = $2
else
# No '=' or ':' means that the value is empty.
properties[line] = ''
end
end
end
return properties
end
end

View file

@ -1,134 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!-- ======================================================================
A tool to migrate RDB data into TDB.
====================================================================== -->
<project name="RDB-migration" default="describe">
<property name="working.dir" location=".work" />
<property name="src.dir" location="src" />
<property name="lib.dir" location="lib" />
<!-- =================================
target: describe
================================= -->
<target name="describe"
description="--> Describe the targets (this is the default).">
<echo>
all - Compiles and runs the RDB migration tool.
</echo>
</target>
<!-- =================================
target: all
================================= -->
<target name="all"
depends="clean, run"
description="Build from scratch and run the migration.">
</target>
<!-- - - - - - - - - - - - - - - - - -
target: clean
- - - - - - - - - - - - - - - - - -->
<target name="clean">
<delete dir="${working.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: setup
- - - - - - - - - - - - - - - - - -->
<target name="setup" depends="getBuildProperties, getRuntimeProperties">
<mkdir dir="${working.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: getBuildProperties
- - - - - - - - - - - - - - - - - -->
<target name="getBuildProperties">
<property name="vivo.distribution.dir" location="../.." />
<property name="build.properties.file"
location="${vivo.distribution.dir}/build.properties" />
<fail message="You must create a &quot;${build.properties.file}&quot; file.">
<condition>
<not>
<available file="${build.properties.file}" />
</not>
</condition>
</fail>
<property file="${build.properties.file}" />
<fail unless="vitro.core.dir"
message="${build.properties.file} must contain a value for vitro.core.dir" />
<fail unless="vitro.home"
message="${build.properties.file} must contain a value for vitro.home" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: getRuntimeProperties
- - - - - - - - - - - - - - - - - -->
<target name="getRuntimeProperties">
<property name="runtime.properties.file"
location="${vitro.home}/runtime.properties" />
<fail message="You must create a &quot;${runtime.properties.file}&quot; file.">
<condition>
<not>
<available file="${runtime.properties.file}" />
</not>
</condition>
</fail>
<property file="${runtime.properties.file}" />
<fail unless="VitroConnection.DataSource.url"
message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username"
message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password"
message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.password" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compile
- - - - - - - - - - - - - - - - - -->
<target name="compile" depends="setup">
<path id="main.compile.classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<javac srcdir="${src.dir}"
destdir="${working.dir}"
debug="true"
deprecation="true"
encoding="UTF8"
includeantruntime="false"
optimize="true"
source="1.7">
<classpath refid="main.compile.classpath" />
</javac>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: run
- - - - - - - - - - - - - - - - - -->
<target name="run" depends="compile">
<path id="migrate.run.classpath">
<pathelement location="${working.dir}" />
<path refid="main.compile.classpath" />
</path>
<java classname="edu.cornell.mannlib.vivo.utilities.rdbmigration.RdbMigrator"
fork="no"
failonerror="true">
<arg value="${vitro.home}" />
<arg value="${VitroConnection.DataSource.url}" />
<arg value="${VitroConnection.DataSource.username}" />
<arg value="${VitroConnection.DataSource.password}" />
<jvmarg value="-Xms512m"/>
<jvmarg value="-Xmx2048m"/>
<classpath refid="migrate.run.classpath" />
</java>
</target>
</project>

View file

@ -1,362 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vivo.utilities.rdbmigration;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.db.DBConnection;
import org.apache.jena.db.GraphRDB;
import org.apache.jena.graph.Node;
import org.apache.jena.query.Dataset;
import org.apache.jena.sparql.core.DatasetGraph;
import org.apache.jena.tdb.TDBFactory;
/**
* A free-standing application that walks the user through the process of
* copying VIVO configuration data from RDB to TDB.
*/
public class RdbMigrator {
private static final String DIRECTORY_TDB = "tdbModels";
private static final String TABLE_RDB = "jena_graph";
private static final String TABLE_MIGRATED = "vivo_rdb_migrated";
private static final List<String> EXPECTED_MODELS = Arrays
.asList(new String[] {
"http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata",
"http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel",
"http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadataTBOX",
"http://vitro.mannlib.cornell.edu/default/vitro-kb-userAccounts" });
private final String vivoHomeDir;
private final String jdbcUrl;
private final String username;
private final String password;
private File targetDir;
private boolean alreadyMigrated;
private List<String> modelsToCopy;
/**
* Confirm all of the parameters. Ask the user for approval. Do the
* migration.
*
* @throws UserDeclinedException
* If the user decides not to continue.
*/
public RdbMigrator(String vivoHomeDir, String jdbcUrl, String username,
String password) throws UserDeclinedException, IOException,
SQLException {
this.vivoHomeDir = vivoHomeDir;
this.jdbcUrl = jdbcUrl;
this.username = username;
this.password = password;
testDbConnection();
checkThatRdbExists();
confirmTargetDirectory();
if (doesTdbExist()) {
askContinueOverTdb();
}
if (isAlreadyMigrated()) {
askMigrateAgain();
}
getListOfRdbModels();
if (isUnexpectedModels()) {
askMigrateAllModels();
}
askApprovalForMigrationPlan();
migrate();
}
private void testDbConnection() {
try (Connection conn = getSqlConnection()) {
// Just open and close it.
} catch (SQLException e) {
quit("Can't log in to database: '" + jdbcUrl + "', '" + username
+ "', '" + password + "'\n" + e.getMessage());
}
}
private void checkThatRdbExists() throws SQLException {
try (Connection conn = getSqlConnection()) {
DatabaseMetaData md = conn.getMetaData();
try (ResultSet rs = md.getTables(null, null, TABLE_RDB, null);) {
if (!rs.next()) {
quit("The database at '" + jdbcUrl
+ "' contains no RDB tables.");
}
}
}
}
private void confirmTargetDirectory() {
File vivoHome = new File(vivoHomeDir);
if (!vivoHome.isDirectory()) {
quit("'" + vivoHome + "' is not a directory.");
}
if (!vivoHome.canWrite()) {
quit("Can't write to '" + vivoHome + "'.");
}
targetDir = new File(vivoHome, DIRECTORY_TDB);
}
private boolean doesTdbExist() {
if (!targetDir.exists()) {
return false;
}
if (!targetDir.isDirectory()) {
quit("'" + targetDir + "' is not a directory.");
}
if (!targetDir.canWrite()) {
quit("Can't write to '" + targetDir + "'.");
}
String[] filenames = targetDir.list();
if (filenames == null || filenames.length == 0) {
return false;
}
return true;
}
private void askContinueOverTdb() throws UserDeclinedException, IOException {
ask("A directory of TDB files exists at '" + targetDir + "'.\n"
+ " Migration will replace the existing triples.\n"
+ "Continue? (y/n)");
}
private boolean isAlreadyMigrated() throws SQLException {
try (Connection conn = getSqlConnection()) {
DatabaseMetaData md = conn.getMetaData();
try (ResultSet rs = md.getTables(null, null, TABLE_MIGRATED, null);) {
if (rs.next()) {
alreadyMigrated = true;
announceMigrationDate(conn);
return true;
} else {
return false;
}
}
}
}
private void announceMigrationDate(Connection conn) {
String migrationDate = "UNKNOWN DATE";
String query = String.format("SELECT date FROM %s LIMIT 1",
TABLE_MIGRATED);
try (Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery(query)) {
if (rs.next()) {
migrationDate = rs.getString("DATE");
}
} catch (SQLException e) {
// go with default answer.
}
System.out.println("It looks like this RDB data has already been "
+ "migrated to TDB, on " + migrationDate
+ "\n (found a table named '" + TABLE_MIGRATED + "')");
}
private void askMigrateAgain() throws UserDeclinedException, IOException {
ask("Migrate again? (y/n)");
}
private void getListOfRdbModels() throws SQLException {
try (Connection conn = getSqlConnection();
ClosingDBConnection rdb = new ClosingDBConnection(conn)) {
modelsToCopy = rdb.getAllModelNames().toList();
}
}
private boolean isUnexpectedModels() {
List<String> unexpectedModels = new ArrayList<>(modelsToCopy);
unexpectedModels.removeAll(EXPECTED_MODELS);
if (unexpectedModels.isEmpty()) {
return false;
}
System.out
.println("VIVO requires only these models from RDB:\n "
+ StringUtils.join(EXPECTED_MODELS, "\n ")
+ "\nYour RDB triple-store contains these additional models:\n "
+ StringUtils.join(unexpectedModels, "\n "));
return true;
}
private void askMigrateAllModels() throws IOException, UserDeclinedException {
System.out.println("Migrate all models, or only the required models?\n"
+ " Enter 'all' or 'only', or anything else to quit.");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
if (s != null) {
if (s.trim().toLowerCase().equals("all")) {
return;
} else if (s.trim().toLowerCase().equals("only")) {
modelsToCopy = EXPECTED_MODELS;
return;
}
}
throw new UserDeclinedException("Enter 'all' or 'only'.");
}
private void askApprovalForMigrationPlan() throws SQLException,
UserDeclinedException, IOException {
int modelCount = 0;
int tripleCount = 0;
try (Connection conn = getSqlConnection();
ClosingDBConnection rdb = new ClosingDBConnection(conn)) {
for (String modelName : modelsToCopy) {
modelCount++;
try (ClosingGraphRDB graph = new ClosingGraphRDB(rdb, modelName)) {
tripleCount += graph.size();
}
}
}
String warning = alreadyMigrated ? " Existing triples will be over-written.\n"
: "";
String question = String.format("Migrating %d triples in %d models "
+ "to TDB files in '%s'\n%sContinue? (y/n)", tripleCount,
modelCount, targetDir, warning);
ask(question);
}
private void quit(String message) {
throw new IllegalArgumentException(
"--------------------------------------------------------------\n"
+ message
+ "\n--------------------------------------------------------------");
}
private void ask(String string) throws UserDeclinedException, IOException {
System.out.println(string);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
if ((s == null) || (!s.trim().toLowerCase().equals("y"))) {
throw new UserDeclinedException("OK.");
}
}
private static class UserDeclinedException extends Exception {
public UserDeclinedException(String message) {
super(message);
}
}
public void migrate() throws SQLException {
copyData();
writeMigrationRecord();
}
private void copyData() throws SQLException {
try (Connection conn = getSqlConnection();
ClosingDBConnection rdb = new ClosingDBConnection(conn)) {
Dataset tdbDataset = TDBFactory.createDataset(targetDir
.getAbsolutePath());
copyGraphs(rdb, tdbDataset);
}
}
@SuppressWarnings("deprecation")
private void copyGraphs(ClosingDBConnection rdb, Dataset tdbDataset) {
DatasetGraph tdbDsGraph = tdbDataset.asDatasetGraph();
for (String modelName : modelsToCopy) {
try (ClosingGraphRDB graph = new ClosingGraphRDB(rdb, modelName)) {
tdbDsGraph.addGraph(Node.createURI(modelName), graph);
System.out
.println(String.format(" copied %4d triples from %s",
graph.size(), modelName));
}
}
}
private void writeMigrationRecord() throws SQLException {
String createTable = String.format("CREATE TABLE %s (date DATE)",
TABLE_MIGRATED);
String deleteOldDates = String.format("DELETE FROM %s", TABLE_MIGRATED);
String insertDate = String.format("INSERT INTO %s (date) VALUES (?)",
TABLE_MIGRATED);
try (Connection conn = getSqlConnection();
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(insertDate)) {
if (alreadyMigrated) {
stmt.executeUpdate(deleteOldDates);
} else {
stmt.executeUpdate(createTable);
}
pstmt.setDate(1, new Date(System.currentTimeMillis()));
pstmt.executeUpdate();
}
}
private Connection getSqlConnection() throws SQLException {
Properties connectionProps;
connectionProps = new Properties();
connectionProps.put("user", username);
connectionProps.put("password", password);
return DriverManager.getConnection(jdbcUrl, connectionProps);
}
private static class ClosingDBConnection extends DBConnection implements
AutoCloseable {
ClosingDBConnection(Connection sqlConnection) {
super(sqlConnection, "MySQL");
}
}
private static class ClosingGraphRDB extends GraphRDB implements
AutoCloseable {
ClosingGraphRDB(DBConnection rdb, String modelName) {
super(rdb, modelName, null,
GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING, false);
}
}
// ----------------------------------------------------------------------
// Main routine
// ----------------------------------------------------------------------
@SuppressWarnings("unused")
public static void main(String[] args) {
if (args.length != 4) {
System.out.println("Usage: RdbMigrator vivoHomeDir, jdbcUrl, "
+ "username, password");
}
try {
new RdbMigrator(args[0], args[1], args[2], args[3]);
} catch (IllegalArgumentException | UserDeclinedException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -1,19 +0,0 @@
A tool to convert triples from SDB to TDB.
Unlike the RDF-migration tool, this tool is not tied to the VIVO
properties files. Instead, you must provide:
* The URL for the SDB, including username and password parameters
* The directory path for the TDB.
The directory must exist.
The directory must be empty, unless the "force" optiopn is used.
Examples:
java -jar sdb2tdb.jar \
jdbc:mysql://localhost/vitrodb?user=vivoUser&password=vivoPass \
/usr/local/my/tdb
java -Xms512m -Xmx4096m -jar .work/sdb2tdb.jar \
'jdbc:mysql://localhost/weill17?user=vivoUser&password=vivoPass' \
/Users/jeb228/Testing/instances/weill-develop/vivo_home/contentTdb \
force

View file

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!-- ======================================================================
A tool to convert SDB data into TDB.
====================================================================== -->
<project name="SDB-to-TDB" default="describe">
<property name="working.dir" location=".work" />
<property name="src.dir" location="src" />
<property name="lib.dir" location="lib" />
<property name="classes.dir" location="${working.dir}/classes" />
<property name="jar.file" location="${working.dir}/sdb2tdb.jar" />
<!-- =================================
target: describe
================================= -->
<target name="describe"
description="--> Describe the targets (this is the default).">
<echo>
all - Compiles the tool ad packs it into a JAR
</echo>
</target>
<!-- =================================
target: all
================================= -->
<target name="all"
depends="clean, jar"
description="Build from scratch and run the migration.">
</target>
<!-- - - - - - - - - - - - - - - - - -
target: clean
- - - - - - - - - - - - - - - - - -->
<target name="clean">
<delete dir="${working.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepare
- - - - - - - - - - - - - - - - - -->
<target name="prepare">
<mkdir dir="${working.dir}" />
<mkdir dir="${classes.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compile
- - - - - - - - - - - - - - - - - -->
<target name="compile" depends="prepare">
<path id="main.compile.classpath">
<fileset dir="${lib.dir}" includes="*.jar" />
</path>
<javac srcdir="${src.dir}"
destdir="${classes.dir}"
debug="true"
deprecation="true"
encoding="UTF8"
includeantruntime="false"
optimize="true"
source="1.7">
<classpath refid="main.compile.classpath" />
</javac>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: jar
- - - - - - - - - - - - - - - - - -->
<target name="jar" depends="compile">
<jar destfile="${jar.file}">
<manifest>
<attribute name="Main-Class"
value="edu.cornell.mannlib.vitro.utilities.sdb2tdb.Sdb2Tdb" />
</manifest>
<fileset dir="${classes.dir}" />
<archives>
<zips>
<fileset dir="${lib.dir}" includes="**/*.jar" />
</zips>
</archives>
</jar>
</target>
</project>

View file

@ -1,291 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.sdb2tdb;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.sdb.SDB;
import org.apache.jena.sdb.SDBFactory;
import org.apache.jena.sdb.Store;
import org.apache.jena.sdb.StoreDesc;
import org.apache.jena.sdb.store.DatabaseType;
import org.apache.jena.sdb.store.LayoutType;
import org.apache.jena.tdb.TDBFactory;
/**
* Copy all of the data from an SDB triple-store to a TDB triple-store. See
* README.txt for more details.
*
* Examples of invoking it:
*
* <pre>
* java -jar sdb2tdb.jar \
* 'jdbc:mysql://localhost/vitrodb?user=vivoUser&password=vivoPass'\
* /usr/local/my/tdb
*
* java -Xms2048m -Xmx2048m -jar .work/sdb2tdb.jar \
* 'jdbc:mysql://localhost/weill17?user=vivoUser&password=vivoPass' \
* /Users/jeb228/Testing/instances/weill-develop/vivo_home/contentTdb \
* force
* </pre>
*
* Each graph is copied separately. Small graphs are simply loaded into memory
* and transferred. Large graphs are read to produce a streaming result set
* which is written to a temporary file. That file is then read into a TDB
* model.
*
* This has been tested with graphs up to 6 million triples without crashing.
*/
public class Sdb2Tdb {
private static final int LARGE_MODEL_THRESHOLD = 500_000;
private final String driverClassName;
private final String jdbcUrl;
private final String destination;
private final boolean force;
private Dataset sdbDataset;
private Dataset tdbDataset;
public Sdb2Tdb(List<String> hardArgs) throws UsageException {
List<String> args = new ArrayList<>(hardArgs);
if (!args.isEmpty() && args.indexOf("force") == (args.size() - 1)) {
this.force = true;
args.remove(args.size() - 1);
} else {
this.force = false;
}
if (args.size() == 3) {
this.driverClassName = args.remove(0);
} else if (args.size() == 2) {
this.driverClassName = "com.mysql.jdbc.Driver";
} else {
throw new UsageException("Wrong number of arguments: "
+ hardArgs.size());
}
this.jdbcUrl = args.get(0);
this.destination = args.get(1);
checkDriverClass();
checkJdbcUrl();
checkDestination();
}
private void checkDriverClass() throws UsageException {
try {
Class.forName(this.driverClassName).newInstance();
} catch (Exception e) {
throw new UsageException("Can't instantiate JDBC driver: "
+ this.driverClassName);
}
}
private void checkJdbcUrl() {
if ((!this.jdbcUrl.matches("\\buser\\b"))
|| (!this.jdbcUrl.matches("\\bpassword\\b"))) {
System.out.println("\nWARNING: The JDBC url probably should "
+ "contain values for user and password.\n");
}
}
private void checkDestination() throws UsageException {
File destDir = new File(this.destination);
if (!destDir.isDirectory()) {
throw new UsageException(
"The destination directory does not exist: '"
+ this.destination + "'");
}
if (!destDir.canWrite()) {
throw new UsageException("Cannot write to '" + this.destination
+ "'");
}
if (!(this.force || getDestinationFilenames().isEmpty())) {
throw new UsageException("The destination directory is not empty. "
+ "Choose another destination, or use the 'force' option");
}
}
private List<String> getDestinationFilenames() {
File destDir = new File(this.destination);
String[] filenames = destDir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return !(name.equals(".") || name.equals(".."));
}
});
return Arrays.asList(filenames);
}
private void translate() throws SQLException, IOException {
try {
sdbDataset = openSdbDataset();
tdbDataset = openTdbDataset();
copyGraphs();
} finally {
if (tdbDataset != null) {
tdbDataset.close();
}
if (sdbDataset != null) {
sdbDataset.close();
}
}
}
private Dataset openSdbDataset() throws SQLException {
Connection conn = DriverManager.getConnection(this.jdbcUrl);
Store store = SDBFactory.connectStore(conn, makeSdbStoreDesc());
SDB.getContext().set(SDB.jdbcStream, Boolean.TRUE);
SDB.getContext().set(SDB.jdbcFetchSize, Integer.MIN_VALUE);
return SDBFactory.connectDataset(store);
}
private StoreDesc makeSdbStoreDesc() {
return new StoreDesc(LayoutType.LayoutTripleNodesHash,
DatabaseType.MySQL);
}
private Dataset openTdbDataset() {
return TDBFactory.createDataset(new File(this.destination)
.getAbsolutePath());
}
private void copyGraphs() throws IOException {
for (Iterator<String> modelNames = sdbDataset.listNames(); modelNames
.hasNext();) {
String modelName = modelNames.next();
Model model = sdbDataset.getNamedModel(modelName);
if (model.size() < LARGE_MODEL_THRESHOLD) {
copySmallModel(modelName, model);
} else {
copyLargeModel(modelName, model);
}
}
}
private void copySmallModel(String modelName, Model model) {
System.out.println(String.format("Copying %6d triples: %s",
model.size(), modelName));
tdbDataset.addNamedModel(modelName, model);
}
private void copyLargeModel(String modelName, Model model)
throws IOException {
File tempFile = File.createTempFile("sdb-", ".n3");
System.out.println(String.format("Copying %6d triples: %s %s",
model.size(), modelName, tempFile.getAbsolutePath()));
model.close();
try (OutputStream os = new FileOutputStream(tempFile);
GraphToTriples trips = new GraphToTriples(this, modelName)) {
RDFDataMgr.writeTriples(os, trips);
}
System.out.println("Wrote it.");
try (InputStream is = new FileInputStream(tempFile)) {
tdbDataset.getNamedModel(modelName).read(is, null, "N-TRIPLE");
}
System.out.println("Read it.");
}
public static void main(String[] args) {
try {
Sdb2Tdb sdb2tdb = new Sdb2Tdb(Arrays.asList(args));
sdb2tdb.translate();
} catch (UsageException e) {
System.out.println();
System.out.println(e.getMessage());
System.out.println(e.getProperUsage());
System.out.println();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
private static class UsageException extends Exception {
public UsageException(String message) {
super(message);
}
public String getProperUsage() {
return "Usage is: java -jar sdb2tdb [driver_class] <jdbcUrl> <destination_directory> [force]";
}
}
private static class GraphToTriples implements Iterator<Triple>,
AutoCloseable {
private static final String QUERY_TEMPLATE = "" //
+ "SELECT ?s ?p ?o \n" //
+ "WHERE { \n" //
+ " GRAPH <%s> { \n" //
+ " ?s ?p ?o . \n" //
+ " } \n" //
+ "}";
private final QueryExecution qe;
private final ResultSet results;
GraphToTriples(Sdb2Tdb parent, String graphUri) {
String qStr = String.format(QUERY_TEMPLATE, graphUri);
Query q = QueryFactory.create(qStr);
qe = QueryExecutionFactory.create(q, parent.sdbDataset);
results = qe.execSelect();
}
@Override
public boolean hasNext() {
return results.hasNext();
}
@Override
public Triple next() {
QuerySolution solution = results.nextSolution();
Node s = solution.get("s").asNode();
Node p = solution.get("p").asNode();
Node o = solution.get("o").asNode();
return new Triple(s, p, o);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void close() {
qe.close();
}
}
}

View file

@ -1,9 +0,0 @@
log4j.appender.AllAppender=org.apache.log4j.ConsoleAppender
log4j.appender.AllAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.AllAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] %m%n
# log4j.appender.AllAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] %m%n
log4j.rootLogger=INFO, AllAppender
# Make all of the Solr classes quieter...
log4j.logger.org.apache.solr=WARN

View file

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!-- ======================================================================
Integration tests to be sure that the Solr configuration does what we
want.
====================================================================== -->
<project name="solr-tester" default="describe">
<property name="src.dir" location="src" />
<property name="vitro.libs.dir" location="../../webapp/lib" />
<property name="solr.home.template"
location="../../solr/homeDirectoryTemplate" />
<property name="solr.war.file" location="../../solr/solr-4.7.2.war" />
<property name="working.dir" location=".work" />
<property name="classes.dir" location="${working.dir}/classes" />
<property name="solr.working.dir" location="${working.dir}/solrHome" />
<property name="solr.libs.dir" location="${working.dir}/solrLibs" />
<path id="main.compile.classpath">
<fileset dir="${vitro.libs.dir}" includes="*.jar" />
<fileset dir="${solr.libs.dir}" includes="*.jar" />
</path>
<path id="test.run.classpath">
<pathelement location="${classes.dir}" />
<path refid="main.compile.classpath" />
</path>
<!-- =================================
target: describe
================================= -->
<target name="describe"
description="--> Describe the targets (this is the default).">
<echo>
all - Runs "clean", then "test".
clean - Delete all artifacts so the next build will be from scratch.
test - Set up the Solr configuration, compile, and run the JUnit tests.
</echo>
</target>
<!-- =================================
target: all
================================= -->
<target name="all"
depends="clean,test"
description="Build from scratch and run the tests.">
</target>
<!-- =================================
target: clean
================================= -->
<target name="clean"
description="Delete the Solr configuration and the compiled clases.">
<delete dir="${working.dir}" />
</target>
<!-- =================================
target: test
================================= -->
<target name="test" depends="compile" description="Run the tests.">
<java classname="org.junit.runner.JUnitCore"
fork="yes"
failonerror="true">
<arg value="edu.cornell.mannlib.vitro.utilities.solrtest.SolrConfigTester" />
<classpath refid="test.run.classpath" />
<sysproperty key="test.solr.home" value="${solr.working.dir}" />
</java>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: setup
- - - - - - - - - - - - - - - - - -->
<target name="setup">
<mkdir dir="${working.dir}" />
<mkdir dir="${solr.working.dir}" />
<sync todir="${solr.working.dir}" includeemptydirs="true">
<fileset dir="${solr.home.template}" />
</sync>
<mkdir dir="${solr.libs.dir}" />
<unwar src="${solr.war.file}" dest="${solr.libs.dir}">
<patternset includes="WEB-INF/lib/*" />
<mapper type="flatten" />
</unwar>
<mkdir dir="${classes.dir}" />
<copy file="log4j.properties" todir="${classes.dir}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compile
- - - - - - - - - - - - - - - - - -->
<target name="compile" depends="setup">
<javac srcdir="${src.dir}"
destdir="${classes.dir}"
debug="true"
deprecation="true"
encoding="UTF8"
includeantruntime="false"
optimize="true"
source="1.7">
<classpath refid="main.compile.classpath" />
</javac>
</target>
</project>

View file

@ -1,250 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.solrtest;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* TODO
*/
@RunWith(JUnit4.class)
public class SolrConfigTester {
private static CoreContainer container;
private static EmbeddedSolrServer server;
@Before
public void setup() throws Exception {
String solrHomeString = System.getProperty("test.solr.home");
container = new CoreContainer(solrHomeString);
try (LogLeveler l = new LogLeveler(SolrCore.class, Level.ERROR)) {
container.load();
}
server = new EmbeddedSolrServer(container, "collection1");
server.deleteByQuery("*:*");
server.commit();
}
@After
public void tearDown() throws Exception {
server.shutdown();
}
// ----------------------------------------------------------------------
// The tests
// ----------------------------------------------------------------------
@Test
public void serverResponds() throws Exception {
server.ping();
}
@Test(expected = SolrException.class)
public void docIdIsRequred() throws Exception {
try (LogLeveler l = new LogLeveler(SolrCore.class, Level.OFF)) {
addDocuments(inputDoc(null, field("nameRaw", "No ID")));
}
}
@Test
public void simpleName() throws Exception {
addDocuments(inputDoc("idSimple", field("nameRaw", "SimpleName")));
assertQueryResults("simple name", "SimpleName", "idSimple");
}
@Test
public void upperLowerName() throws Exception {
addDocuments(inputDoc("idUpperLower", field("nameRaw", "Lower, Upper")));
assertQueryResults("upper lower name", "Lower", "idUpperLower");
assertQueryResults("upper lower name", "lower", "idUpperLower");
assertQueryResults("upper lower name", "UPPER", "idUpperLower");
}
/**
* Why does it behave as if name is stemmed? Is that the behavior that we
* want?
*/
@Ignore
@Test
public void nameIsNotStemmed() throws Exception {
addDocuments(inputDoc("nameStemming",
field("nameRaw", "Swimming, Bills"),
field("nameLowercaseSingleValued", "Lower, Upper")));
assertQueryResults("name not stemmed", "Swimming", "nameStemming");
assertQueryResults("name not stemmed", "Bills", "nameStemming");
assertQueryResults("name not stemmed", "Swim");
assertQueryResults("name not stemmed", "Bill");
}
/**
* A name with an umlaut over an o is found exactly, or with the umlaut
* missing, upper case or lower case.
*/
@Test
public void nameWithUmlaut() throws Exception {
addDocuments(inputDoc("idUmlaut",
field("nameRaw", "P\u00F6ysen B\u00F6ysen")));
assertQueryResults("name with umlaut", "Boysen", "idUmlaut");
assertQueryResults("name with umlaut", "B\u00F6ysen", "idUmlaut");
assertQueryResults("name with umlaut", "BOYSEN", "idUmlaut");
assertQueryResults("name with umlaut", "B\u00D6YSEN", "idUmlaut");
}
/**
* ALLTEXT is searched, but to make the 3rd case work, we need
* ALLTEXTUNSTEMMED also. Why is that?
*/
@Test
public void allTextIsSearched() throws Exception {
addDocuments(inputDoc("allTextSearch", field("ALLTEXT", "Wonderful"),
field("ALLTEXTUNSTEMMED", "Wonderful")));
assertQueryResults("all text", "Wonderful", "allTextSearch");
assertQueryResults("all text", "wonderful", "allTextSearch");
assertQueryResults("all text", "WoNdErFuL", "allTextSearch");
}
@Test
public void allTextIsStemmed() throws Exception {
addDocuments(inputDoc("allTextStem", field("ALLTEXT", "Swimming"),
field("ALLTEXTUNSTEMMED", "Swimming")));
assertQueryResults("all text stem", "Swim", "allTextStem");
assertQueryResults("all text stem", "swim", "allTextStem");
}
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
public InputField field(String name, String... values) {
return new InputField(name, null, values);
}
public InputField field(String name, Float boost, String... values) {
return new InputField(name, boost, values);
}
public SolrInputDocument inputDoc(String docId, InputField... fields) {
SolrInputDocument doc = new SolrInputDocument();
if (docId != null) {
doc.addField("DocId", docId);
}
for (InputField f : fields) {
for (String value : f.values) {
if (f.boost == null) {
doc.addField(f.name, value);
} else {
doc.addField(f.name, value, f.boost);
}
}
}
return doc;
}
public void addDocuments(SolrInputDocument... documents)
throws SolrServerException, IOException {
for (SolrInputDocument doc : documents) {
server.add(doc);
}
server.commit();
}
private void assertQueryResults(String message, String query,
String... expectedDocIds) throws SolrServerException {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set("q", query);
QueryResponse qResp = server.query(params);
SolrDocumentList docList = qResp.getResults();
List<String> expected = Arrays.asList(expectedDocIds);
List<String> actual = new ArrayList<>();
for (int i = 0; i < docList.getNumFound(); i++) {
actual.add(String.valueOf(docList.get(i).getFirstValue("DocId")));
}
assertEquals(message + " : '" + query + "'", expected, actual);
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
public static class InputField {
final String name;
final Float boost;
final String[] values;
public InputField(String name, Float boost, String[] values) {
this.name = name;
this.boost = boost;
this.values = values;
}
}
public static class LogLeveler implements AutoCloseable {
private final Logger logger;
private final Level initialLevel;
public LogLeveler(Class<?> clazz, Level desiredLevel) {
this.logger = Logger.getLogger(clazz);
this.initialLevel = this.logger.getLevel();
this.logger.setLevel(desiredLevel);
}
@Override
public void close() {
this.logger.setLevel(this.initialLevel);
}
}
}
/**
* TODO
*
* <pre>
* // ** Let's index a document into our embedded server
*
* SolrInputDocument newDoc = new SolrInputDocument();
* newDoc.addField(&quot;title&quot;, &quot;Test Document 1&quot;);
* newDoc.addField(&quot;id&quot;, &quot;doc-1&quot;);
* newDoc.addField(&quot;text&quot;, &quot;Hello world!&quot;);
* server.add(newDoc);
* server.commit();
*
* // ** And now let's query for it
*
* params.set(&quot;q&quot;, &quot;title:test&quot;);
* QueryResponse qResp = server.query(params);
*
* SolrDocumentList docList = qResp.getResults();
* System.out.println(&quot;Num docs: &quot; + docList.getNumFound());
* SolrDocument doc = docList.get(0);
* System.out.println(&quot;Title: &quot; + doc.getFirstValue(&quot;title&quot;).toString());
* </pre>
*/

View file

@ -1,26 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testrunner;
/**
* Indicates a problem with the attempt to run a command in a sub-process.
*/
public class CommandRunnerException extends Exception {
public CommandRunnerException() {
super();
}
public CommandRunnerException(String message) {
super(message);
}
public CommandRunnerException(Throwable cause) {
super(cause);
}
public CommandRunnerException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -1,26 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testrunner;
/**
* Indicates a problem so severe that we might as well stop now.
*/
public class FatalException extends RuntimeException {
public FatalException() {
super();
}
public FatalException(String message) {
super(message);
}
public FatalException(Throwable cause) {
super(cause);
}
public FatalException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -1,434 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testrunner;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener;
import edu.cornell.mannlib.vitro.utilities.testrunner.listener.LoggingListener;
import edu.cornell.mannlib.vitro.utilities.testrunner.listener.MulticastListener;
/**
* Holds the runtime parameters that are read from the properties file, perhaps
* with modifications from the GUI if we are running interactively.
*/
public class SeleniumRunnerParameters {
public static final String PROP_OUTPUT_DIRECTORY = "output_directory";
public static final String PROP_UPLOAD_DIRECTORY = "upload_directory";
public static final String PROP_SUITE_DIRECTORIES = "suite_parent_directories";
public static final String PROP_WEBSITE_URL = "website_url";
public static final String PROP_USER_EXTENSIONS_PATH = "user_extensions_path";
public static final String PROP_FIREFOX_PROFILE_PATH = "firefox_profile_template_path";
public static final String PROP_SUITE_TIMEOUT_LIMIT = "suite_timeout_limit";
public static final String PROP_SELENIUM_JAR_PATH = "selenium_jar_path";
public static final String PROP_IGNORED_TESTS = "ignored_tests_file";
public static final String PROP_SUMMARY_CSS = "summary_css_file";
public static final String LOGFILE_NAME = "log_file.txt";
private final String websiteUrl;
private final File userExtensionsFile;
private final File firefoxProfileDir;
private final int suiteTimeoutLimit;
private final File seleniumJarPath;
private final File uploadDirectory;
private final File outputDirectory;
private final File logFile;
private final Collection<File> suiteParentDirectories;
private final ModelCleanerProperties modelCleanerProperties;
private final IgnoredTests ignoredTests;
private boolean cleanModel = true;
private boolean cleanUploads = true;
// If we fail during the parameter parsing, we'll still write the log
// somewhere.
private Listener listener = new LoggingListener(System.out);
/**
* Read the required properties from the property file, and do some checks
* on them.
*/
public SeleniumRunnerParameters(String propertiesFilepath)
throws IOException {
Properties props = loadPropertiesFile(propertiesFilepath);
this.websiteUrl = getRequiredProperty(props, PROP_WEBSITE_URL);
this.userExtensionsFile = checkReadableFile(props,
PROP_USER_EXTENSIONS_PATH);
this.firefoxProfileDir = checkOptionalReadableDirectory(props,
PROP_FIREFOX_PROFILE_PATH);
this.suiteTimeoutLimit = getRequiredIntegerProperty(props,
PROP_SUITE_TIMEOUT_LIMIT);
this.seleniumJarPath = checkReadableFile(props, PROP_SELENIUM_JAR_PATH);
this.uploadDirectory = checkReadWriteDirectory(props,
PROP_UPLOAD_DIRECTORY);
this.outputDirectory = checkOutputDirectory(props);
this.logFile = new File(this.outputDirectory, LOGFILE_NAME);
this.listener = new MulticastListener();
addListener(new LoggingListener(this.logFile));
this.suiteParentDirectories = checkSuiteParentDirectories(props);
this.modelCleanerProperties = new ModelCleanerProperties(props);
// Get the list of ignored tests.
String ignoredFilesPath = getRequiredProperty(props, PROP_IGNORED_TESTS);
File ignoredFilesFile = new File(ignoredFilesPath);
FileHelper.checkReadableFile(ignoredFilesFile, "File '"
+ ignoredFilesPath + "'");
this.ignoredTests = new IgnoredTests(ignoredFilesFile);
}
/**
* Load the properties from the properties file.
*/
private Properties loadPropertiesFile(String propertiesFilepath)
throws FileNotFoundException, IOException {
File propsFile = new File(propertiesFilepath);
if (!propsFile.exists()) {
throw new FileNotFoundException("Property file does not exist: '"
+ propsFile + "'");
}
Reader propsReader = null;
try {
propsReader = new FileReader(propsFile);
Properties props = new Properties();
props.load(propsReader);
return props;
} finally {
if (propsReader != null) {
try {
propsReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* If there is a parameter for this key, it should point to a readable
* directory.
*/
private File checkOptionalReadableDirectory(Properties props, String key) {
String value = props.getProperty(key);
if (value == null) {
return null;
}
value = value.trim();
if (value.trim().length() == 0) {
return null;
}
File dir = new File(value);
if (!dir.exists()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' does not exist.");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' is not a directory.");
}
if (!dir.canRead()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' is not readable.");
}
return dir;
}
/**
* Check that there is a property for the required directory path, and that
* it points to a valid directory.
*/
private File checkReadWriteDirectory(Properties props, String key) {
String value = getRequiredProperty(props, key);
File dir = new File(value);
if (!dir.exists()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' does not exist. (" + dir.getAbsolutePath()
+ ")");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' is not a directory. (" + dir.getAbsolutePath()
+ ")");
}
if (!dir.canRead()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' is not readable. (" + dir.getAbsolutePath()
+ ")");
}
if (!dir.canWrite()) {
throw new IllegalArgumentException("Directory " + key + " '"
+ value + "' is not writeable. (" + dir.getAbsolutePath()
+ ")");
}
return dir;
}
private File checkReadableFile(Properties props, String key) {
String value = getRequiredProperty(props, key);
File file = new File(value);
if (!file.exists()) {
throw new IllegalArgumentException("File " + key + ": '" + value
+ "' does not exist. (" + file.getAbsolutePath() + ")");
}
if (!file.isFile()) {
throw new IllegalArgumentException("File " + key + ": '" + value
+ "' is not a file. (" + file.getAbsolutePath() + ")");
}
if (!file.canRead()) {
throw new IllegalArgumentException("File " + key + ": '" + value
+ "' is not readable. (" + file.getAbsolutePath() + ")");
}
return file;
}
/**
* Get the property for the output directory. If it does not exist, create
* it (the parent must exist). Ensure that it is writeable.
*/
private File checkOutputDirectory(Properties props) throws IOException {
String value = getRequiredProperty(props, PROP_OUTPUT_DIRECTORY);
File outputDirectory = new File(value);
File outputParent = outputDirectory.getParentFile();
if (!outputDirectory.exists()) {
if (!outputParent.exists()) {
throw new IllegalArgumentException(
"Output directory does not exist, nor does its parent. '"
+ outputDirectory + "' ("
+ outputDirectory.getAbsolutePath() + ")");
}
outputDirectory.mkdir();
if (!outputDirectory.exists()) {
throw new IOException("Failed to create output directory: '"
+ outputDirectory + "' ("
+ outputDirectory.getAbsolutePath() + ")");
}
}
if (!outputDirectory.isDirectory()) {
throw new IllegalArgumentException("Suite directory '"
+ outputDirectory.getPath() + "' is not a directory. ("
+ outputDirectory.getAbsolutePath() + ")");
}
if (!outputDirectory.canRead()) {
throw new IllegalArgumentException("Suite directory '"
+ outputDirectory.getPath() + "' is not readable. ("
+ outputDirectory.getAbsolutePath() + ")");
}
if (!outputDirectory.canWrite()) {
throw new IllegalArgumentException("Suite directory '"
+ outputDirectory.getPath() + "' is not writeable. ("
+ outputDirectory.getAbsolutePath() + ")");
}
return outputDirectory;
}
/**
* Get the property for the suite directories and ensure that each one is
* indeed a readable directory.
*/
private Collection<File> checkSuiteParentDirectories(Properties props) {
String value = getRequiredProperty(props, PROP_SUITE_DIRECTORIES);
List<File> dirs = new ArrayList<File>();
String[] paths = value.split("[:;]");
for (String path : paths) {
File dir = new File(path.trim());
if (!dir.exists()) {
throw new IllegalArgumentException("Suite directory '"
+ dir.getPath() + "' does not exist. ("
+ dir.getAbsolutePath() + ")");
}
if (!dir.isDirectory()) {
throw new IllegalArgumentException("Suite directory '"
+ dir.getPath() + "' is not a directory. ("
+ dir.getAbsolutePath() + ")");
}
if (!dir.canRead()) {
throw new IllegalArgumentException("Suite directory '"
+ dir.getPath() + "' is not readable. ("
+ dir.getAbsolutePath() + ")");
}
dirs.add(dir);
}
return dirs;
}
/**
* Get the value for this property. If there isn't one, or if it's empty,
* complain.
*/
private String getRequiredProperty(Properties props, String key) {
String value = props.getProperty(key);
if ((value == null) || (value.trim().length() == 0)) {
throw new IllegalArgumentException(
"Property file must provide a value for '" + key + "'");
}
return value;
}
/**
* This required property must be a valid integer.
*/
private int getRequiredIntegerProperty(Properties props, String key) {
String value = getRequiredProperty(props, key);
try {
return Integer.parseInt(value.trim());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Property value for '" + key
+ "' is not a valid integer: " + value);
}
}
public String getWebsiteUrl() {
return websiteUrl;
}
public File getUserExtensionsFile() {
return userExtensionsFile;
}
public boolean hasFirefoxProfileDir() {
return firefoxProfileDir != null;
}
public File getFirefoxProfileDir() {
return firefoxProfileDir;
}
public int getSuiteTimeoutLimit() {
return suiteTimeoutLimit;
}
public File getSeleniumJarPath() {
return seleniumJarPath;
}
public void addListener(Listener l) {
if (listener instanceof MulticastListener) {
((MulticastListener) listener).addListener(l);
} else {
throw new IllegalStateException("Listener is not a multi-cast -- "
+ "can't add new listeners.");
}
}
public Listener getListener() {
return listener;
}
public void setListener(Listener logger) {
this.listener = logger;
}
public File getUploadDirectory() {
return uploadDirectory;
}
public File getOutputDirectory() {
return outputDirectory;
}
public File getLogFile() {
return logFile;
}
public Collection<File> getSuiteParentDirectories() {
return suiteParentDirectories;
}
public ModelCleanerProperties getModelCleanerProperties() {
return modelCleanerProperties;
}
public IgnoredTests getIgnoredTests() {
return ignoredTests;
}
public boolean isCleanModel() {
return cleanModel;
}
public void setCleanModel(boolean cleanModel) {
this.cleanModel = cleanModel;
}
public boolean isCleanUploads() {
return cleanUploads;
}
public void setCleanUploads(boolean cleanUploads) {
this.cleanUploads = cleanUploads;
}
public String toString() {
return "Parameters:" + "\n websiteUrl: " + websiteUrl
+ "\n userExtensionsFile: " + userExtensionsFile
+ "\n firefoxProfileDir: " + firefoxProfileDir
+ "\n suiteTimeoutLimit: " + suiteTimeoutLimit
+ "\n seleniumJarPath: " + seleniumJarPath
+ "\n uploadDirectory: " + uploadDirectory
+ "\n outputDirectory: " + outputDirectory
+ "\n suiteParentDirectories: " + suiteParentDirectories
+ "\n modelCleanerProperties: " + modelCleanerProperties
+ "\n" + ignoredTests + "\n cleanModel: " + cleanModel
+ "\n cleanUploads: " + cleanUploads;
}
/**
* Look inside this parent directory and find any suite directories. You can
* recognize a suite directory because it contains a file named Suite.html.
*/
public Collection<File> findSuiteDirs(File parentDir) {
return Arrays.asList(parentDir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
if (!pathname.isDirectory()) {
return false;
}
if (pathname.getName().charAt(0) == '.') {
return false;
}
File suiteFile = new File(pathname, "Suite.html");
if (suiteFile.exists()) {
return true;
} else {
listener.subProcessErrout("Warning: suite file '"
+ suiteFile.getPath() + "' does not exist.\n");
return false;
}
}
}));
}
}

View file

@ -1,294 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testrunner.datamodel;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests;
import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo;
import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats;
import edu.cornell.mannlib.vitro.utilities.testrunner.Status;
import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData;
import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener;
import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput;
import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults;
/**
* Collect all that we know about suites, tests, and their current status.
*/
public class DataModel {
/* base data */
private Collection<SuiteContents> suiteContents = Collections.emptyList();
private Collection<File> selectedSuites = Collections.emptyList();
private Collection<SuiteResults> suiteResults = Collections.emptyList();
private OutputDataListener.Info dataListenerInfo = OutputDataListener.Info.EMPTY_INFO;
private IgnoredTests ignoredTestList = IgnoredTests.EMPTY_LIST;
private LogStats logStats = LogStats.EMPTY_LOG_STATS; // TODO
/* derived data */
private Status runStatus = Status.PENDING;
private final SortedMap<String, SuiteData> suiteDataMap = new TreeMap<String, SuiteData>();
private final EnumMap<Status, List<SuiteData>> suiteMapByStatus = new EnumMap<Status, List<SuiteData>>(
Status.class);
private final List<TestData> allTests = new ArrayList<TestData>();
private final EnumMap<Status, List<TestData>> testMapByStatus = new EnumMap<Status, List<TestData>>(
Status.class);
// ----------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------
public DataModel() {
calculate();
}
// ----------------------------------------------------------------------
// Update the base data.
// ----------------------------------------------------------------------
public void setSuiteContents(Collection<SuiteContents> suiteContents) {
this.suiteContents = new ArrayList<SuiteContents>(suiteContents);
calculate();
}
public void setSelectedSuites(Collection<File> selectedSuites) {
this.selectedSuites = new ArrayList<File>(selectedSuites);
calculate();
}
public Collection<File> getSelectedSuites() {
return new ArrayList<File>(selectedSuites);
}
public void setSuiteResults(Collection<SuiteResults> suiteResults) {
this.suiteResults = new ArrayList<SuiteResults>(suiteResults);
calculate();
}
public void captureDataListener(OutputDataListener dataListener) {
this.dataListenerInfo = dataListener.getInfo();
calculate();
}
public void setIgnoredTestList(IgnoredTests ignoredTestList) {
this.ignoredTestList = ignoredTestList;
calculate();
}
public void setLogStats(LogStats logStats) { // TODO
this.logStats = logStats;
calculate();
}
// ----------------------------------------------------------------------
// Keep the derived data current.
// ----------------------------------------------------------------------
/**
* Data in the model has been updated. Refresh all derived data.
*/
private void calculate() {
// Clear all derived data.
runStatus = Status.OK;
suiteDataMap.clear();
suiteMapByStatus.clear();
for (Status s : Status.values()) {
suiteMapByStatus.put(s, new ArrayList<SuiteData>());
}
allTests.clear();
testMapByStatus.clear();
for (Status s : Status.values()) {
testMapByStatus.put(s, new ArrayList<TestData>());
}
/*
* Populate the Suite map with all Suites.
*/
Map<String, SuiteResults> resultsMap = new HashMap<String, SuiteResults>();
for (SuiteResults result : suiteResults) {
resultsMap.put(result.getName(), result);
}
Map<String, SuiteContents> contentsMap = new HashMap<String, SuiteContents>();
for (SuiteContents contents : suiteContents) {
contentsMap.put(contents.getName(), contents);
}
for (SuiteContents contents : suiteContents) {
String name = contents.getName();
SuiteResults result = resultsMap.get(name);
boolean ignored = ignoredTestList.isIgnored(name);
ProcessOutput failureMessages = dataListenerInfo
.getFailureMessages().get(name);
suiteDataMap.put(name, new SuiteData(name, ignored, contents,
result, failureMessages));
}
/*
* Map the Suites by status.
*/
for (SuiteData s : suiteDataMap.values()) {
getSuites(s.getStatus()).add(s);
}
/**
* Populate the Test map with all Tests, and map by status.
*/
for (SuiteData s : suiteDataMap.values()) {
for (TestData t : s.getTestMap().values()) {
allTests.add(t);
getTests(t.getStatus()).add(t);
}
}
if (logStats.hasErrors() || !getSuites(Status.ERROR).isEmpty()) {
runStatus = Status.ERROR;
} else if (!getSuites(Status.PENDING).isEmpty()) {
runStatus = Status.PENDING;
} else {
runStatus = Status.OK;
}
}
// ----------------------------------------------------------------------
// Access the derived data.
// ----------------------------------------------------------------------
public Status getRunStatus() {
return runStatus;
}
public long getStartTime() {
return dataListenerInfo.getStartTime();
}
public long getEndTime() {
return dataListenerInfo.getEndTime();
}
public long getElapsedTime() {
return dataListenerInfo.getElapsedTime();
}
public boolean isAnyPasses() {
return !getTests(Status.OK).isEmpty();
}
public boolean isAnyFailures() {
return !getTests(Status.ERROR).isEmpty();
}
public boolean isAnyIgnores() {
return !getTests(Status.IGNORED).isEmpty();
}
public boolean isAnyPending() {
return !getTests(Status.PENDING).isEmpty();
}
public int getTotalSuiteCount() {
return suiteDataMap.size();
}
public int getPassingSuiteCount() {
return getSuites(Status.OK).size();
}
public int getFailingSuiteCount() {
return getSuites(Status.ERROR).size();
}
public int getIgnoredSuiteCount() {
return getSuites(Status.IGNORED).size();
}
public int getPendingSuiteCount() {
return getSuites(Status.PENDING).size();
}
public Collection<SuiteData> getAllSuites() {
return suiteDataMap.values();
}
public Map<String, SuiteData> getSuitesWithFailureMessages() {
Map<String, SuiteData> map = new TreeMap<String, SuiteData>();
for (SuiteData s : suiteDataMap.values()) {
if (s.getFailureMessages() != null) {
map.put(s.getName(), s);
}
}
return map;
}
public int getTotalTestCount() {
return allTests.size();
}
public int getPassingTestCount() {
return getTests(Status.OK).size();
}
public int getFailingTestCount() {
return getTests(Status.ERROR).size();
}
public int getIgnoredTestCount() {
return getTests(Status.IGNORED).size();
}
public int getPendingTestCount() {
return getTests(Status.PENDING).size();
}
public Collection<TestData> getAllTests() {
return Collections.unmodifiableCollection(allTests);
}
public Collection<TestData> getFailingTests() {
return Collections.unmodifiableCollection(getTests(Status.ERROR));
}
public Collection<TestData> getIgnoredTests() {
return Collections.unmodifiableCollection(getTests(Status.IGNORED));
}
public Collection<IgnoredTestInfo> getIgnoredTestInfo() {
return ignoredTestList.getList();
}
public String getReasonForIgnoring(String suiteName, String testName) {
return ignoredTestList.getReasonForIgnoring(suiteName, testName);
}
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
/**
* Get the list of suites that have this status.
*/
private List<SuiteData> getSuites(Status st) {
return suiteMapByStatus.get(st);
}
/**
* Get the list of tests that have this status.
*/
private List<TestData> getTests(Status st) {
return testMapByStatus.get(st);
}
}

View file

@ -1,375 +0,0 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.utilities.testrunner.output;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper;
import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo;
import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats;
import edu.cornell.mannlib.vitro.utilities.testrunner.SeleniumRunnerParameters;
import edu.cornell.mannlib.vitro.utilities.testrunner.Status;
import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.DataModel;
import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData;
import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData;
import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput;
/**
* Creates the summary HTML file.
*/
public class OutputSummaryFormatter {
public static final String SUMMARY_HTML_FILENAME = "summary.html";
public static final String SUMMARY_CSS_FILENAME = "summary.css";
private final SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
private final SeleniumRunnerParameters parms;
private LogStats logStats;
private DataModel dataModel;
public OutputSummaryFormatter(SeleniumRunnerParameters parms) {
this.parms = parms;
}
/**
* Create a summary HTML file from the info contained in this log file and
* these suite outputs.
*/
public void format(LogStats logStats, DataModel dataModel) {
this.logStats = logStats;
this.dataModel = dataModel;
PrintWriter writer = null;
try {
copyCssFile();
File outputFile = new File(parms.getOutputDirectory(),
SUMMARY_HTML_FILENAME);
writer = new PrintWriter(outputFile);
writeHeader(writer);
writeStatsSection(writer);
writeErrorMessagesSection(writer);
writeCondensedTable(writer);
writeIgnoreSection(writer);
writeSuiteErrorMessagesSection(writer);
writeFooter(writer);
} catch (IOException e) {
// There is no appeal for any problems here. Just report them.
e.printStackTrace();
} finally {
if (writer != null) {
writer.close();
}
}
}
/**
* Copy the CSS file into the output directory.
*/
private void copyCssFile() {
InputStream cssStream = this.getClass().getResourceAsStream(
SUMMARY_CSS_FILENAME);
if (cssStream == null) {
System.out.println("Couldn't find the CSS file: '"
+ SUMMARY_CSS_FILENAME + "'");
} else {
File cssTarget = new File(parms.getOutputDirectory(),
SUMMARY_CSS_FILENAME);
try {
FileHelper.copy(cssStream, cssTarget);
cssStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void writeHeader(PrintWriter w) {
Status runStatus = dataModel.getRunStatus();
String statusString = (runStatus == Status.PENDING) ? "IN PROGRESS"
: runStatus.toString();
String startString = formatDateTime(dataModel.getStartTime());
w.println("<html>");
w.println("<head>");
w.println(" <title>Summary of Acceptance Tests " + startString
+ "</title>");
w.println(" <link rel=\"stylesheet\" type=\"text/css\" "
+ "href=\"summary.css\">");
w.println("</head>");
w.println("<body>");
w.println();
w.println(" <div class=\"heading\">");
w.println(" Acceptance test results: " + startString);
w.println(" <div class=\"" + runStatus.getHtmlClass()
+ " one-word\">" + statusString + "</div>");
w.println(" </div>");
}
private void writeStatsSection(PrintWriter w) {
String passClass = dataModel.isAnyPasses() ? Status.OK.getHtmlClass()
: "";
String failClass = dataModel.isAnyFailures() ? Status.ERROR
.getHtmlClass() : "";
String ignoreClass = dataModel.isAnyIgnores() ? Status.IGNORED
.getHtmlClass() : "";
String start = formatDateTime(dataModel.getStartTime());
String end = formatDateTime(dataModel.getEndTime());
String elapsed = formatElapsedTime(dataModel.getElapsedTime());
w.println(" <div class=\"section\">Summary</div>");
w.println();
w.println(" <table class=\"summary\" cellspacing=\"0\">");
w.println(" <tr>");
w.println(" <td>");
w.println(" <table cellspacing=\"0\">");
w.println(" <tr><td>Start time:</td><td>" + start
+ "</td></tr>");
w.println(" <tr><td>End time:</td><td>" + end + "</td></tr>");
w.println(" <tr><td>Elapsed time</td><td>" + elapsed
+ "</td></tr>");
w.println(" </table>");
w.println(" </td>");
w.println(" <td>");
w.println(" <table class=\"tallys\" cellspacing=\"0\">");
w.println(" <tr><th>&nbsp;</th><th>Suites</th><th>Tests</th>");
w.println(" <tr class=\"" + passClass
+ "\"><td>Passed</td><td>" + dataModel.getPassingSuiteCount()
+ "</td><td>" + dataModel.getPassingTestCount() + "</td>");
w.println(" <tr class=\"" + failClass
+ "\"><td>Failed</td><td>" + dataModel.getFailingSuiteCount()
+ "</td><td>" + dataModel.getFailingTestCount() + "</td>");
w.println(" <tr class=\"" + ignoreClass
+ "\"><td>Ignored</td><td>" + dataModel.getIgnoredSuiteCount()
+ "</td><td>" + dataModel.getIgnoredTestCount() + "</td>");
if (dataModel.isAnyPending()) {
w.println(" <tr class=\"" + Status.PENDING.getHtmlClass()
+ "\"><td>Pending</td><td>"
+ dataModel.getPendingSuiteCount() + "</td><td>"
+ dataModel.getPendingTestCount() + "</td>");
}
w.println(" <tr><td class=\"total\">Total</td><td>"
+ dataModel.getTotalSuiteCount() + "</td><td>"
+ dataModel.getTotalTestCount() + "</td>");
w.println(" </table>");
w.println(" </td>");
w.println(" </tr>");
w.println(" </table>");
w.println();
}
private void writeErrorMessagesSection(PrintWriter w) {
String errorClass = Status.ERROR.getHtmlClass();
w.println(" <div class=section>Errors and warnings</div>");
w.println();
w.println(" <table cellspacing=\"0\">");
if ((!logStats.hasErrors()) && (!logStats.hasWarnings())) {
w.println(" <tr><td colspan=\"2\">No errors or warnings</td></tr>");
} else {
for (String e : logStats.getErrors()) {
w.println(" <tr class=\"" + errorClass
+ "\"><td>ERROR</td><td>" + e + "</td></tr>");
}
}
w.println(" </table>");
w.println();
}
private void writeCondensedTable(PrintWriter w) {
w.println(" <div class=section>Condensed List</div>");
w.println();
w.println(" <table class=\"condensed\" cellspacing=\"0\">");
for (SuiteData s : dataModel.getAllSuites()) {
String sReason = "";
if (s.getStatus() == Status.IGNORED) {
sReason = dataModel.getReasonForIgnoring(s.getName(), "*");
} else if (s.getFailureMessages() != null) {
sReason = s.getFailureMessages().getErrout();
} else if (s.getStatus() == Status.PENDING) {
sReason = Status.PENDING.toString();
}
w.println(" <tr>");
w.println(" <td class=\"" + s.getStatus().getHtmlClass()
+ "\">");
w.println(" <div class=\"suite\">" + outputLink(s)
+ "</div>");
if (!sReason.isEmpty()) {
// The entire class is either failed or pending or ignored.
w.println(" <div class=\"reason\">" + sReason + "</div>");
} else {
// Show the individual tests.
for (TestData t : s.getTestMap().values()) {
String tClass = t.getStatus().getHtmlClass();
String tReason = dataModel.getReasonForIgnoring(
s.getName(), t.getTestName());
w.println(" <div class=\"test " + tClass + "\">");
w.println(" " + outputLink(t));
if (!tReason.isEmpty()) {
w.println(" <div class=\"tReason\">" + tReason
+ "</div>");
}
w.println(" </div>");
}
}
w.println(" </td>");
w.println(" </tr>");
}
w.println(" </table>");
w.println();
}
private void writeSuiteErrorMessagesSection(PrintWriter w) {
Map<String, SuiteData> failedSuiteMap = dataModel
.getSuitesWithFailureMessages();
if (failedSuiteMap.isEmpty()) {
return;
}
w.println(" <div class=section>All tests</div>");
w.println();
for (SuiteData s : failedSuiteMap.values()) {
ProcessOutput output = s.getFailureMessages();
w.println(" <a name=\"" + SuiteData.failureMessageAnchor(s)
+ "\">");
w.println(" <table cellspacing=\"0\">");
w.println(" <tr><th>Standard Output</th></tr>\n");
w.println(" <tr><td><pre>" + output.getStdout()
+ "</pre></td></tr>\n");
w.println(" </table>");
w.println("<br/>&nbsp;<br/>");
w.println(" <table cellspacing=\"0\">");
w.println(" <tr><th>Error Output</th></tr>\n");
w.println(" <tr><td><pre>" + output.getErrout()
+ "</pre></td></tr>\n");
w.println(" </table>");
w.println("<br/>&nbsp;<br/>");
w.println();
}
}
private void writeIgnoreSection(PrintWriter w) {
String warnClass = Status.IGNORED.getHtmlClass();
Collection<IgnoredTestInfo> ignoredTests = dataModel
.getIgnoredTestInfo();
w.println(" <div class=section>Ignored</div>");
w.println();
w.println(" <table class=\"ignored\" cellspacing=\"0\">");
w.println(" <tr><th>Suite name</th><th>Test name</th>"
+ "<th>Reason for ignoring</th></tr>\n");
if (ignoredTests.isEmpty()) {
w.println(" <tr><td colspan=\"3\">No tests ignored.</td>"
+ "</tr>");
} else {
for (IgnoredTestInfo info : ignoredTests) {
String suiteName = info.suiteName;
String testName = info.testName;
String reason = dataModel.getReasonForIgnoring(suiteName,
testName);
w.println(" <tr class=\"" + warnClass + "\">");
w.println(" <td>" + suiteName + "</td>");
w.println(" <td>" + testName + "</td>");
w.println(" <td>" + reason + "</td>");
w.println(" </tr>");
}
}
w.println(" </table>");
w.println();
}
private void writeFooter(PrintWriter w) {
w.println(" <div class=section>Log</div>");
w.println(" <pre class=\"log\">");
Reader reader = null;
try {
reader = new FileReader(parms.getLogFile());
char[] buffer = new char[4096];
int howMany;
while (-1 != (howMany = reader.read(buffer))) {
w.write(buffer, 0, howMany);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
w.println(" </pre>");
w.println("</body>");
w.println("</html>");
}
private String formatElapsedTime(long elapsed) {
if (elapsed == 0) {
return "---";
}
long elapsedSeconds = elapsed / 1000L;
long seconds = elapsedSeconds % 60L;
long elapsedMinutes = elapsedSeconds / 60L;
long minutes = elapsedMinutes % 60L;
long hours = elapsedMinutes / 60L;
String elapsedTime = "";
if (hours > 0) {
elapsedTime += hours + "h ";
}
if (minutes > 0 || hours > 0) {
elapsedTime += minutes + "m ";
}
elapsedTime += seconds + "s";
return elapsedTime;
}
private String formatDateTime(long dateTime) {
if (dateTime == 0) {
return "---";
}
return dateFormat.format(new Date(dateTime));
}
private String outputLink(SuiteData s) {
if (s.getOutputLink() == null) {
return s.getName();
} else {
return "<a href=\"" + s.getOutputLink() + "\">" + s.getName()
+ "</a>";
}
}
private String outputLink(TestData t) {
if (t.getOutputLink() == null) {
return t.getTestName();
} else {
return "<a href=\"" + t.getOutputLink() + "\">" + t.getTestName()
+ "</a>";
}
}
}

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:vitro="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#"
xmlns:auth="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#"
xmlns="http://vitro.mannlib.cornell.edu/ns/vitro/default#"
xml:base="http://vitro.mannlib.cornell.edu/ns/vitro/default">
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/TestAdmin">
<auth:emailAddress rdf:datatype="http://www.w3.org/2001/XMLSchema#string">testAdmin@cornell.edu</auth:emailAddress>
<auth:externalAuthId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">testAdmin</auth:externalAuthId>
<auth:firstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Test</auth:firstName>
<auth:lastName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Admin</auth:lastName>
<auth:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DC647EB65E6711E155375218212B3964</auth:md5password>
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#ADMIN"/>
</auth:UserAccount>
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JohnCurator">
<auth:emailAddress rdf:datatype="http://www.w3.org/2001/XMLSchema#string">johnCurator@cornell.edu</auth:emailAddress>
<auth:externalAuthId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">johnCurator</auth:externalAuthId>
<auth:firstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">John</auth:firstName>
<auth:lastName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Curator</auth:lastName>
<auth:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DC647EB65E6711E155375218212B3964</auth:md5password>
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#CURATOR"/>
</auth:UserAccount>
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/SallyEditor">
<auth:emailAddress rdf:datatype="http://www.w3.org/2001/XMLSchema#string">sallyEditor@cornell.edu</auth:emailAddress>
<auth:externalAuthId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">sallyEditor</auth:externalAuthId>
<auth:firstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Sally</auth:firstName>
<auth:lastName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Editor</auth:lastName>
<auth:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DC647EB65E6711E155375218212B3964</auth:md5password>
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#EDITOR"/>
</auth:UserAccount>
<auth:UserAccount rdf:about="http://vivo.mydomain.edu/individual/JoeUser">
<auth:emailAddress rdf:datatype="http://www.w3.org/2001/XMLSchema#string">joeUser@cornell.edu</auth:emailAddress>
<auth:externalAuthId rdf:datatype="http://www.w3.org/2001/XMLSchema#string">joeUser</auth:externalAuthId>
<auth:firstName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Joe</auth:firstName>
<auth:lastName rdf:datatype="http://www.w3.org/2001/XMLSchema#string">User</auth:lastName>
<auth:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DC647EB65E6711E155375218212B3964</auth:md5password>
<auth:status rdf:datatype="http://www.w3.org/2001/XMLSchema#string">ACTIVE</auth:status>
<auth:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</auth:loginCount>
<auth:passwordLinkExpires rdf:datatype="http://www.w3.org/2001/XMLSchema#long">0</auth:passwordLinkExpires>
<auth:hasPermissionSet rdf:resource="http://vitro.mannlib.cornell.edu/ns/vitro/authorization#SELF_EDITOR"/>
</auth:UserAccount>
</rdf:RDF>

View file

@ -1,637 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!-- ======================================================================
Build script for the Vitro core webapp.
This can be used on its own, or invoked from a Product build script.
====================================================================== -->
<project name="vitroCore" default="describe">
<property environment="env" />
<!-- We must be using a suitable version of Java. -->
<fail>
<condition>
<not>
<or>
<equals arg1="1.7" arg2="${ant.java.version}" />
<equals arg1="1.8" arg2="${ant.java.version}" />
</or>
</not>
</condition>
The Vitro build script requires Java 7 or later.
Ant property ant.java.version = ${ant.java.version}
Java system property java.version = ${java.version}
Java system property java.home = ${java.home}
JAVA_HOME environment variable = ${env.JAVA_HOME}
</fail>
<!-- We must be using a suitable version of Ant. -->
<fail>
<condition>
<not>
<antversion atleast="1.8" />
</not>
</condition>
The Vitro build script requires Ant 1.8 or later.
Ant property ant.version = ${ant.version}
Ant property ant.home = ${ant.home}
ANT_HOME environment variable = ${env.ANT_HOME}
</fail>
<!-- A product script will override appbase.dir, but not corebase.dir -->
<dirname property="corebase.dir" file="${ant.file.vitroCore}" />
<property name="appbase.dir" location="${corebase.dir}" />
<property name="build.properties.file" location="config/build.properties" />
<property name="build.dir" location=".build" />
<property name="buildtools.dir" location="${corebase.dir}/../utilities/buildutils" />
<property name="buildtools.source.dir" location="${buildtools.dir}/src" />
<property name="buildtools.lib.dir" location="${buildtools.dir}/lib" />
<property name="buildtools.compiled.dir" location="${build.dir}/buildTools" />
<property name="main.build.dir" location="${build.dir}/main"/>
<property name="main.webapp.dir" location="${main.build.dir}/webapp" />
<property name="main.webinf.dir" location="${main.webapp.dir}/WEB-INF" />
<property name="main.compiled.dir" location="${main.webinf.dir}/classes" />
<property name="main.resources.dir" location="${main.webinf.dir}/resources" />
<property name="main.revisioninfo.file" location="${main.resources.dir}/revisionInfo.txt" />
<property name="unittests.compiled.dir" location="${main.build.dir}/testClasses" />
<property name="solr.template.dir" location="${corebase.dir}/../solr" />
<property name="solr.template.context.file" location="${solr.template.dir}/template.context.xml" />
<property name="solr.build.dir" location="${build.dir}/solr" />
<property name="solr.webapp.dir" location="${solr.build.dir}/webapp" />
<property name="solr.homeimage.dir" location="${solr.build.dir}/homeimage" />
<property name="vitrohome.build.dir" location="${build.dir}/vitrohome" />
<property name="vitrohome.image.dir" location="${vitrohome.build.dir}/image" />
<property name="distribution.dir" location="${build.dir}/distribution" />
<property name="distribution.tar.gz.file" location="${build.dir}/distribution.tar.gz" />
<property name="option.javac.deprecation" value="true" />
<!-- - - - - - - - - - - - - - - - - -
target: buildProperties
- - - - - - - - - - - - - - - - - -->
<target name="buildProperties">
<fail message="You must create a &quot;${build.properties.file}&quot; file.">
<condition>
<not>
<available file="${build.properties.file}" />
</not>
</condition>
</fail>
<property file="${build.properties.file}" />
<fail unless="webapp.name" message="${build.properties.file} must contain a value for webapp.name" />
<property name="solr.app.name" value="${webapp.name}solr" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deployProperties
- - - - - - - - - - - - - - - - - -->
<target name="deployProperties" depends="buildProperties">
<fail unless="vitro.home" message="${build.properties.file} must contain a value for vitro.home" />
<fail unless="tomcat.home" message="${build.properties.file} must contain a value for tomcat.home" />
<fail>
<condition>
<not>
<available file="${tomcat.home}" />
</not>
</condition>
Tomcat home directory '${tomcat.home}' does not exist.
Check the value of 'tomcat.home' in your build.properties file.
</fail>
<fail>
<condition>
<not>
<available file="${tomcat.home}/webapps" />
</not>
</condition>
'${tomcat.home}' does not refer to a valid Tomcat instance: it has no 'webapps' sub-directory.
Check the value of 'tomcat.home' in your build.properties file."
</fail>
<property name="solr.home.dir" location="${vitro.home}/solr" />
<property name="tomcat.context.filename" value="META-INF/context.xml" />
<property name="main.tomcat.webapp.dir" value="${tomcat.home}/webapps/${webapp.name}" />
<property name="main.tomcat.context.file" value="${main.tomcat.webapp.dir}/${tomcat.context.filename}" />
<property name="solr.tomcat.webapp.dir" value="${tomcat.home}/webapps/${solr.app.name}" />
<property name="solr.tomcat.context.file" value="${solr.tomcat.webapp.dir}/${tomcat.context.filename}" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compileBuildtools
- - - - - - - - - - - - - - - - - -->
<target name="compileBuildtools">
<path id="utility.compile.classpath">
<fileset dir="${buildtools.lib.dir}" includes="*.jar" />
<fileset dir="${appbase.dir}/lib">
<include name="commons-io-2.0.1.jar" />
<include name="commons-lang-2.6.jar" />
<include name="servlet-api.jar" />
</fileset>
</path>
<mkdir dir="${buildtools.compiled.dir}" />
<javac srcdir="${buildtools.source.dir}"
destdir="${buildtools.compiled.dir}"
debug="true"
deprecation="${option.javac.deprecation}"
encoding="UTF8"
includeantruntime="false"
optimize="false"
source="1.7">
<classpath refid="utility.compile.classpath" />
</javac>
<path id="utility.run.classpath">
<pathelement location="${buildtools.compiled.dir}" />
<path refid="utility.compile.classpath" />
</path>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepare
- - - - - - - - - - - - - - - - - -->
<target name="prepare">
<mkdir dir="${build.dir}" />
<!-- Get ready to copy language files.
Use JavaScript functions to add "includes" to this PatternSet,
depending on which languages are selected. -->
<patternset id="language_files" />
<script language="javascript"> <![CDATA[
function echo(e, message) {
e.setMessage(message);
e.perform();
}
prop = project.getProperty("languages.addToBuild");
ps = project.getReference("language_files");
e = project.createTask("echo");
if (prop != null) {
languages = prop.trim().split(",");
for (var i=0; i < languages.length; i++) {
ps.setIncludes([languages[i] + "/**/*"])
echo(e, "Adding language: " + languages[i])
}
} else {
ps.setExcludes(["**/*"])
}
]]> </script>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepareWebappDir
- - - - - - - - - - - - - - - - - -->
<target name="prepareWebappDir" depends="prepare">
<!-- copy all sorts of web stuff into the webapp directory. -->
<copy todir="${main.webapp.dir}">
<fileset dir="${appbase.dir}/web" />
<fileset dir="${appbase.dir}" includes="themes/**/*" />
</copy>
<copy todir="${main.webinf.dir}">
<fileset dir="${appbase.dir}">
<!-- copy the JARs into the war directory -->
<include name="lib/*" />
<!-- these will be in the servlet container: we mustn't conflict. -->
<exclude name="lib/jsp-api.jar" />
<exclude name="lib/servlet-api.jar" />
</fileset>
</copy>
<!-- use the production Log4J properties, unless a debug version exists. -->
<condition property="log4j.properties.file" value="debug.log4j.properties" else="log4j.properties">
<available file="${appbase.dir}/config/debug.log4j.properties" />
</condition>
<copy file="${appbase.dir}/config/${log4j.properties.file}"
tofile="${main.build.dir}/log4j.properties"
filtering="true"
overwrite="true">
<filterchain>
<expandproperties />
</filterchain>
</copy>
<copy todir="${main.compiled.dir}">
<fileset dir="${main.build.dir}">
<filename name="log4j.properties"/>
<different targetdir="${main.compiled.dir}" ignorefiletimes="true"/>
</fileset>
</copy>
<!-- Copy the build.properties file to the resources directory. -->
<copy tofile="${main.resources.dir}/build.properties" file="${build.properties.file}" />
<!-- copy any xml files from source tree to the war directory -->
<copy todir="${main.compiled.dir}">
<fileset dir="${appbase.dir}/src" includes="**/*.xml" />
</copy>
<!-- Copy any requested language files to the webapp directory. -->
<!-- Use a mapper to remove the language directory name when copying. -->
<copy todir="${main.webapp.dir}/">
<fileset dir="${appbase.dir}/languages" >
<patternset refid="language_files" />
<or>
<filename name="*/i18n/**/*" />
<filename name="*/templates/**/*" />
<filename name="*/themes/**/*" />
</or>
</fileset>
<regexpmapper from="^[^/]+/(.*)$$" to="\1" handledirsep="true" />
</copy>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepareVitroHomeDir
- - - - - - - - - - - - - - - - - -->
<target name="prepareVitroHomeDir" depends="prepare">
<mkdir dir="${vitrohome.build.dir}" />
<mkdir dir="${vitrohome.image.dir}" />
<copy todir="${vitrohome.image.dir}" >
<fileset dir="${appbase.dir}/config" >
<include name="example.runtime.properties" />
</fileset>
</copy>
<mkdir dir="${vitrohome.image.dir}/config" />
<copy todir="${vitrohome.image.dir}/config" >
<fileset dir="${appbase.dir}/config" >
<include name="example.applicationSetup.n3" />
<include name="example.developer.properties" />
</fileset>
</copy>
<copy todir="${vitrohome.image.dir}" >
<fileset dir="${appbase.dir}" >
<include name="rdf/**/*" />
</fileset>
</copy>
<!-- Copy any requested language files to the webapp directory. -->
<!-- Use a mapper to remove the language directory name when copying. -->
<copy todir="${vitrohome.image.dir}" >
<fileset dir="${appbase.dir}/languages" >
<patternset refid="language_files" />
<filename name="*/rdf/**/*" />
</fileset>
<regexpmapper from="^[^/]+/(.*)$$" to="\1" handledirsep="true" />
</copy>
</target>
<!-- =================================
target: clean
================================= -->
<target name="clean" description="--> Delete all artifacts.">
<delete dir="${build.dir}" />
<!-- delete the rdf files, removing any unused languages, for example. -->
<delete dir="${vitro.home}/rdf" />
</target>
<!-- =================================
target: compile
================================= -->
<target name="compile" depends="prepareWebappDir" description="--> Compile Java sources">
<path id="main.compile.classpath">
<fileset dir="${appbase.dir}/lib" includes="*.jar" />
</path>
<!-- deletes all files that depend on changed .java files -->
<depend srcdir="${appbase.dir}/src"
destdir="${main.compiled.dir}"
closure="false"
cache="${main.build.dir}/compileDependencyCache">
<classpath refid="main.compile.classpath" />
</depend>
<javac srcdir="${appbase.dir}/src"
destdir="${main.compiled.dir}"
debug="true"
deprecation="${option.javac.deprecation}"
encoding="UTF8"
includeantruntime="false"
optimize="true"
source="1.7">
<classpath refid="main.compile.classpath" />
</javac>
</target>
<!-- =================================
target: test
================================= -->
<target name="test" depends="compile, compileBuildtools, prepareSolr" unless="skiptests" description="--> Run JUnit tests">
<path id="test.compile.classpath">
<pathelement location="${main.compiled.dir}" />
<path refid="main.compile.classpath" />
<!-- need the solr runtime becuase we do a test where a solr server is started -->
<fileset dir="${solr.webapp.dir}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
</path>
<mkdir dir="${unittests.compiled.dir}" />
<javac srcdir="${appbase.dir}/test"
destdir="${unittests.compiled.dir}"
debug="true"
deprecation="${option.javac.deprecation}"
encoding="UTF8"
includeantruntime="false"
optimize="false"
source="1.7">
<classpath refid="test.compile.classpath" />
</javac>
<path id="test.run.classpath">
<pathelement location="${appbase.dir}/test" />
<pathelement location="${unittests.compiled.dir}" />
<path refid="test.compile.classpath" />
<path refid="utility.run.classpath" />
<fileset dir="${solr.webapp.dir}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
</path>
<java classname="edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner" fork="yes" failonerror="true">
<classpath refid="test.run.classpath" />
<arg file="${appbase.dir}/test" />
<arg value="${testlevel}" />
</java>
</target>
<!-- =================================
target: revisionInfo
================================= -->
<target name="revisionInfo" depends="test" unless="skipinfo" description="--> Store revision info in build">
<mkdir dir="${main.resources.dir}" />
<tstamp>
<format property="revisionInfo.timestamp" pattern="yyyy-MM-dd HH:mm:ss" />
</tstamp>
<echo file="${main.revisioninfo.file}">${revisionInfo.timestamp}
</echo>
<addRevisionInfoLine productName="vitroCore" productCheckoutDir="${corebase.dir}/.." />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deployWebapp
- - - - - - - - - - - - - - - - - -->
<target name="deployWebapp" depends="deployProperties, revisionInfo">
<mkdir dir="${main.tomcat.webapp.dir}" />
<sync todir="${main.tomcat.webapp.dir}" includeemptydirs="true">
<fileset dir="${main.webapp.dir}" />
<preserveintarget>
<include name="${tomcat.context.filename}"/>
</preserveintarget>
</sync>
<!-- Create the context XML with expanded properties. Store it in a temp file for now. -->
<copy tofile="${main.build.dir}/context.xml" filtering="true" overwrite="true">
<fileset file="${appbase.dir}/context.xml" />
<filterchain>
<expandproperties />
</filterchain>
</copy>
<!-- Copy the new context XML only if it differs from the existing one. -->
<copy todir="${main.tomcat.webapp.dir}/META-INF">
<fileset dir="${main.build.dir}">
<filename name="context.xml"/>
<different targetdir="${main.tomcat.webapp.dir}/META-INF" ignorefiletimes="true"/>
</fileset>
</copy>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepareSolr
- - - - - - - - - - - - - - - - - -->
<target name="prepareSolr" depends="prepare, buildProperties">
<!-- create an image of the Solr home directory -->
<copy todir="${solr.homeimage.dir}">
<fileset dir="${solr.template.dir}/homeDirectoryTemplate" />
</copy>
<!-- create an unpacked image of the Solr WAR -->
<unwar src="${solr.template.dir}/solr-4.7.2.war" dest="${solr.webapp.dir}" />
<!-- add logging JARs and logging options that Solr doesn't include -->
<copy todir="${solr.webapp.dir}">
<fileset dir="${solr.template.dir}/additions-to-solr-war/" />
</copy>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deploySolr
- - - - - - - - - - - - - - - - - -->
<target name="deploySolr" depends="deployProperties, prepareSolr">
<!-- Deploy to the Solr home directory. -->
<mkdir dir="${solr.home.dir}" />
<sync todir="${solr.home.dir}" includeemptydirs="true">
<fileset dir="${solr.homeimage.dir}" />
<preserveintarget>
<include name="data/**/*"/>
</preserveintarget>
</sync>
<!-- Deploy to Tomcat. -->
<mkdir dir="${solr.tomcat.webapp.dir}" />
<sync todir="${solr.tomcat.webapp.dir}" includeemptydirs="true">
<fileset dir="${solr.webapp.dir}" />
<preserveintarget>
<include name="${tomcat.context.filename}"/>
</preserveintarget>
</sync>
<!-- Create the context XML with expanded properties. Store it in a temp file for now. -->
<copy tofile="${solr.build.dir}/context.xml" filtering="true" overwrite="true">
<fileset file="${solr.template.context.file}" />
<filterchain>
<expandproperties />
</filterchain>
</copy>
<!-- Copy the new context XML only if it differs from the existing one. -->
<copy todir="${solr.tomcat.webapp.dir}/META-INF">
<fileset dir="${solr.build.dir}">
<filename name="context.xml"/>
<different targetdir="${solr.tomcat.webapp.dir}/META-INF" ignorefiletimes="true"/>
</fileset>
</copy>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deployVitroHome
- - - - - - - - - - - - - - - - - -->
<target name="deployVitroHome" depends="deployProperties, prepareVitroHomeDir">
<copy toDir="${vitro.home}" >
<fileset dir="${vitrohome.image.dir}" />
</copy>
</target>
<!-- =================================
target: deploy
================================= -->
<target name="deploy"
depends="deployWebapp, deploySolr, deployVitroHome"
description="--> Build the app and install in Tomcat">
</target>
<!-- =================================
target: all
================================= -->
<target name="all" depends="clean, deploy" description="--> Run 'clean', then 'deploy'" />
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OUTSIDE THE MAIN BUILD SEQUENCE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- =================================
target: distribute
================================= -->
<target name="distribute"
depends="revisionInfo, prepareVitroHomeDir, prepareSolr"
description="--> Build the app and create a distribution bundle">
<mkdir dir="${distribution.dir}" />
<jar basedir="${main.webapp.dir}" destfile="${distribution.dir}/${webapp.name}.war" />
<jar basedir="${solr.webapp.dir}" destfile="${distribution.dir}/${solr.app.name}.war" />
<tar basedir="${solr.homeimage.dir}" destfile="${distribution.dir}/solrhome.tar" />
<tar basedir="${vitrohome.image.dir}" destfile="${distribution.dir}/vitrohome.tar" />
<tar basedir="${distribution.dir}" destfile="${distribution.tar.gz.file}" compression="gzip" />
</target>
<!-- =================================
target: describe
================================= -->
<target name="describe"
description="--> Describe the targets (this is the default).">
<echo>
all - Runs "clean", then "deploy".
clean - Delete all artifacts so the next build will be from scratch.
compile - Compile the Java source files.
orng - Configure and deploy the ORNG Shindig application.
test - Compile and run the JUnit tests.
distribute - Create WAR files to be deployed in a servlet container.
deploy - Deploy the application directly into the Tomcat webapps directory.
</echo>
</target>
<!-- =================================
target: jar
================================= -->
<target name="jar" depends="test" description="--> Compile the Java, and build a JAR file">
<jar basedir="${main.compiled.dir}" destfile="${build.dir}/${ant.project.name}.jar" />
</target>
<!-- =================================
target: licenser
In regular use, checks that all appropriate source files have license tags.
At release time, applies license text to source files.
================================= -->
<target name="licenser" description="--> Check source files for licensing tags">
<property name="licenser.properties.file" location="${corebase.dir}/config/licenser/licenser.properties" />
<runLicenserScript productname="Vitro core" propertiesfile="${licenser.properties.file}" />
</target>
<!-- =================================
target: jarlist
================================= -->
<target name="jarlist" depends="compileBuildtools, jar" description="Figure out what JARs are not needed">
<java classname="edu.cornell.mannlib.vitro.utilities.jarlist.JarLister" fork="no" failonerror="true">
<classpath refid="utility.run.classpath" />
<arg value="${build.dir}/${ant.project.name}.jar" />
<arg value="${appbase.dir}/lib" />
<arg value="${appbase.dir}/config/jarlist/known_dependencies.txt" />
</java>
</target>
<!-- =================================
target: orng
================================= -->
<target name="orng" description="Configure and deploy the ORNG Shindig application">
<ant dir="${corebase.dir}/../opensocial" antfile="build_orng.xml" target="all" />
</target>
<!-- =================================
target: checkContainerNeutrality
================================= -->
<target name="checkContainerNeutrality" depends="compile, compileBuildtools" description="Look for things that Tomcat tolerates but shouldn't">
<junit haltonfailure="true">
<test name="edu.cornell.mannlib.vitro.utilities.containerneutral.CheckContainerNeutrality" />
<sysproperty key="CheckContainerNeutrality.webapp.dir" value="${main.webapp.dir}"/>
<classpath>
<path refid="utility.run.classpath" />
<path refid="main.compile.classpath" />
<pathelement location="${main.compiled.dir}" />
</classpath>
<formatter type="plain" usefile="false"/>
</junit>
</target>
<!-- =================================
target: migrateConfigurationModels
================================= -->
<target name="migrateConfigurationModels" description="copy the RDB models into TDB">
<dirname property="corebase.dir" file="${ant.file.vitroCore}" />
<property name="rdbmigration.dir" location="${corebase.dir}/../utilities/rdbmigration" />
<ant dir="${rdbmigration.dir}" target="all"></ant>
</target>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MACROS
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!--
Run the licenser script.
-->
<macrodef name="runLicenserScript">
<attribute name="productName" />
<attribute name="propertiesFile" />
<sequential>
<echo message="Checking license tags on @{productName}" />
<exec executable="ruby" dir="${corebase.dir}/../utilities/licenser" failonerror="true">
<arg value="licenser.rb" />
<arg value="@{propertiesFile}" />
<redirector outputproperty="licenser.test.output" alwayslog="true" />
</exec>
</sequential>
</macrodef>
<!--
Add a line to the revisionInfo file.
-->
<macrodef name="addRevisionInfoLine">
<attribute name="productName" />
<attribute name="productCheckoutDir" />
<sequential>
<java classname="edu.cornell.mannlib.vitro.utilities.revisioninfo.RevisionInfoBuilder"
fork="no"
failonerror="true">
<classpath refid="utility.run.classpath" />
<arg value="@{productName}" />
<arg file="@{productCheckoutDir}" />
<arg file="${main.revisioninfo.file}" />
</java>
</sequential>
</macrodef>
</project>

View file

@ -1,36 +0,0 @@
# -----------------------------------------------------------------------------
#
# Vitro build properties
#
# This file is provided as example.build.properties.
#
# Save a copy of this file as build.properties, and edit the properties as
# needed for your installation.
#
# -----------------------------------------------------------------------------
#
# The base install directory for your Tomcat server. The Vitro application
# will be deployed in the /webapps directory below this base.
#
tomcat.home = /usr/local/tomcat
#
# The name of the Vitro application. This will be used as the name of the
# subdirectory within your Tomcat server's /webapps directory. It also appears
# in the URL for the application. For example, http://my.vitro.server/vitro
#
webapp.name = vitro
#
# The location where the Vitro application will store the data that it creates.
# This includes uploaded files (usually images) and the search index.
#
vitro.home = /usr/local/vitro/home
#
# Additional languages to be built into your VIVO site. The locales specified
# here must appear as sub-directories of [vivo]/languages in the distribution.
# Find more information on the VIVO Wiki (https://wiki.duraspace.org/display/VIVO).
#
#languages.addToBuild =

View file

@ -1,155 +0,0 @@
# -----------------------------------------------------------------------------
#
# Vitro runtime properties
#
# This file is provided as example.runtime.properties.
#
# Save a copy of this file as runtime.properties in your Vitro home directory,
# and edit the properties as needed for your installation.
#
# -----------------------------------------------------------------------------
#
# This namespace will be used when generating URIs for objects created in the
# editor. In order to serve linked data, the default namespace must be composed
# as follows (optional elements in parentheses):
#
# scheme + server_name (+ port) (+ servlet_context) + "/individual/"
#
# For example, Cornell's default namespace is:
#
# http://vivo.cornell.edu/individual/
#
Vitro.defaultNamespace = http://vivo.mydomain.edu/individual/
#
# URL of Solr context used in local Vitro search. This will usually consist of:
# scheme + server_name + port + vitro_webapp_name + "solr"
# In the standard installation, the Solr context will be on the same server as Vitro,
# and in the same Tomcat instance. The path will be the Vitro webapp.name (specified
# above) + "solr"
# Example:
# vitro.local.solr.url = http://localhost:8080/vitrosolr
vitro.local.solr.url = http://localhost:8080/vitrosolr
#
# Email parameters which VIVO can use to send mail. If these are left empty,
# the "Contact Us" form will be disabled and users will not be notified of
# changes to their accounts.
#
email.smtpHost = smtp.my.domain.edu
email.replyTo = vivoAdmin@my.domain.edu
#
# The basic parameters for a MySQL database connection. Change the end of the
# URL to reflect your database name (if it is not "vitro"). Change the username
# and password to match the authorized user you created in MySQL.
#
VitroConnection.DataSource.url = jdbc:mysql://localhost/vitro
VitroConnection.DataSource.username = vitroweb
VitroConnection.DataSource.password = vitrovitro
#
# The maximum number of active connections in the database connection pool.
# Increase this value to support a greater number of concurrent page requests.
#
VitroConnection.DataSource.pool.maxActive = 40
#
# The maximum number of database connections that will be allowed
# to remain idle in the connection pool. Default is 25%
# of the maximum number of active connections.
#
VitroConnection.DataSource.pool.maxIdle = 10
#
# Parameters to change in order to use VIVO with a database other than
# MySQL.
#
VitroConnection.DataSource.dbtype = MySQL
VitroConnection.DataSource.driver = com.mysql.jdbc.Driver
VitroConnection.DataSource.validationQuery = SELECT 1
#
# The email address of the root user for the VIVO application. The password
# for this user is initially set to "rootPassword", but you will be asked to
# change the password the first time you log in.
#
rootUser.emailAddress = root@myDomain.com
#
# Argon2 password hashing parameters for time, memory and parallelism required to
# compute a hash.
#
# A time cost defines the amount of computation realized and therefore the execution
# time, given in a number of iterations.
# A memory cost defines the memory usage, given in kibibytes
# A parallelism degree defines the number of parallel threads
# For determining the optimal values of the parameters for your setup please refer to
# the white paper section 9
# https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
#
argon2.parallelism =1
argon2.memory = 1024
argon2.time = 1000
#
# How is a logged-in user associated with a particular Individual? One way is
# for the Individual to have a property whose value is the username of the user.
# This is the name of that property.
#
selfEditing.idMatchingProperty = http://vitro.mydomain.edu/ns#networkId
#
# If an external authentication system like Shibboleth or CUWebAuth is to be
# used, these properties say how the login button should be labeled, and which
# HTTP header will contain the user ID from the authentication system. If such
# as system is not to be used, leave these commented out. Consult the
# installation instructions for more details.
#
#externalAuth.buttonText = Log in using BearCat Shibboleth
#externalAuth.netIdHeaderName = remote_userID
#
# Types of individual for which we can create proxy editors.
# If this is omitted, defaults to http://www.w3.org/2002/07/owl#Thing
proxy.eligibleTypeList = http://www.w3.org/2002/07/owl#Thing
#
# Show only the most appropriate data values based on the Accept-Language
# header supplied by the browser. Default is false if not set.
#
# RDFService.languageFilter = true
#
# Tell VIVO to generate HTTP headers on its responses to facilitate caching the
# profile pages that it creates.
#
# For more information, see
# https://wiki.duraspace.org/display/VIVO/Use+HTTP+caching+to+improve+performance
#
# Developers will likely want to leave caching disabled, since a change to a
# Freemarker template or to a Java class would not cause the page to be
# considered stale.
#
# http.createCacheHeaders = true
#
# Force VIVO to use a specific language or Locale instead of those
# specified by the browser. This affects RDF data retrieved from the model,
# if RDFService.languageFilter is true. This also affects the text of pages
# that have been modified to support multiple languages.
#
# languages.forceLocale = en_US
#
# A list of supported languages or Locales that the user may choose to
# use instead of the one specified by the browser. Selection images must
# be available in the i18n/images directory of the theme. This affects
# RDF data retrieved from the model, if RDFService.languageFilter is true.
# This also affects the text of pages that have been modified to support
# multiple languages.
#
# This should not be used with languages.forceLocale, which will override it.
#
# languages.selectableLocales = en, es, fr

View file

@ -1,27 +0,0 @@
#
# A list of JARs that we know to be required by the source code (and notes on where they are required).
#
# The "jarlist" target of the build script will work on the assumption that these JARs and any JARs
# that they depend on are required by the app.
#
# For example, the JDBC drivers are never explicitly included, but instead are invoked using Class.forName(),
# so they are required even though the "jarlist" target won't find any such requirement.
#
# JDBC drivers that we want to include.
# Oracle and MySQL
ojdbc14_g.jar
mysql-connector-java-5.1.16-bin.jar
# Don't know who requires the Commons Logging package - Maybe JENA?
commons-logging-1.1.1.jar
# Needed by a variety of JSPs
# datapropertyBackButtonProblems.jsp
# n3Delete.jsp
# processDatapropRdfForm.jsp
# processRdfForm2.jsp
xstream-1.2.2.jar
# Used in error.jsp, which should probably go away.
cos.jar

View file

@ -1,198 +0,0 @@
#
# A list of files and directories that are known exceptions to the
# license-insertion process.
#
# Files will only be altered if they contain a "magic" license place-holder,
# but if they match one of the file-matchers and don't contain a place-holder,
# the process will write a warning.
#
# File-matchers are:
# '*.java', '*.jsp', '*.tld', '*.xsl', '*.xslt', '*.css', '*.js', 'build.xml'
#
# Known exceptions listed here produce no warnings.
#
# Any files added to this list should include a comment, so we know where they
# came from, or why they don't require a license statement.
#
# The AI ingest files are exceptions -- until we decide otherwise.
utilities/ingest/**/*
# PROBLEM: Can't find any info on licensing.
webapp/web/templates/freemarker/page/partials/doctype.html
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/src/edu/cornell/mannlib/vitro/webapp/web/ContentType.java
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/src/org/json/*
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/src/edu/cornell/mannlib/vitro/webapp/utils/JsonToFmModel.java
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/tiny_mce/*
webapp/web/js/tiny_mce/**/*
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/jquery-1.12.4.min.js
webapp/web/js/jquery-ui/*
webapp/web/js/jquery_plugins/*
webapp/web/js/jquery.fix.clone.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/dojo.js
webapp/web/src/AdapterRegistry.js
webapp/web/src/animation/*
webapp/web/src/animation.js
webapp/web/src/behavior.js
webapp/web/src/bootstrap1.js
webapp/web/src/bootstrap2.js
webapp/web/src/browser_debug.js
webapp/web/src/collections/*
webapp/web/src/compat/*
webapp/web/src/data/*
webapp/web/src/data.js
webapp/web/src/date.js
webapp/web/src/debug/*
webapp/web/src/debug.js
webapp/web/src/Deferred.js
webapp/web/src/dnd/*
webapp/web/src/doc.js
webapp/web/src/dom.js
webapp/web/src/event/*
webapp/web/src/event.js
webapp/web/src/experimental.js
webapp/web/src/flash.js
webapp/web/src/fx/*
webapp/web/src/graphics/*
webapp/web/src/hostenv_adobesvg.js
webapp/web/src/hostenv_browser.js
webapp/web/src/hostenv_dashboard.js
webapp/web/src/hostenv_jsc.js
webapp/web/src/hostenv_rhino.js
webapp/web/src/hostenv_spidermonkey.js
webapp/web/src/hostenv_svg.js
webapp/web/src/hostenv_wsh.js
webapp/web/src/html/*
webapp/web/src/html.js
webapp/web/src/i18n/*
webapp/web/src/iCalendar.js
webapp/web/src/io/*
webapp/web/src/io.js
webapp/web/src/json.js
webapp/web/src/lang/*
webapp/web/src/lang.js
webapp/web/src/lfx/*
webapp/web/src/loader.js
webapp/web/src/loader_xd.js
webapp/web/src/logging/*
webapp/web/src/math/*
webapp/web/src/math.js
webapp/web/src/profile.js
webapp/web/src/reflect/*
webapp/web/src/regexp.js
webapp/web/src/rpc/*
webapp/web/src/selection/*
webapp/web/src/storage/*
webapp/web/src/storage.js
webapp/web/src/string/*
webapp/web/src/string.js
webapp/web/src/style.js
webapp/web/src/svg.js
webapp/web/src/text/*
webapp/web/src/undo/*
webapp/web/src/uri/*
webapp/web/src/uuid/*
webapp/web/src/validate/*
webapp/web/src/validate.js
webapp/web/src/widget/*
webapp/web/src/widget/**/*
webapp/web/src/xml/*
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/templates/freemarker/page/partials/googleAnalytics.ftl
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/WEB-INF/tlds/sparqltag.tld
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/WEB-INF/tlds/c.tld
webapp/web/WEB-INF/tlds/fn.tld
# PROBLEM: Can't find any info on licensing.
webapp/web/WEB-INF/tlds/database.tld
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/WEB-INF/tlds/taglibs-mailer.tld
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/WEB-INF/tlds/taglibs-random.tld
webapp/web/WEB-INF/tlds/taglibs-string.tld
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/themes/enhanced/css/blueprint/grid.css
webapp/web/themes/enhanced/css/blueprint/ie.css
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/css/jquery_plugins/jquery.realperson.css
# PROBLEM: Can't find any info on licensing.
webapp/web/themes/enhanced/css/blueprint/liquid.css
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/betterDateInput.js
# PROBLEM: Can't find any info on licensing.
webapp/web/js/detect.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/toggle.js
webapp/web/js/toggle.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/html5.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/selectivizr.js
# PROBLEM: Can't find any info on licensing.
webapp/web/js/jquery_plugins/supersleight.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/raphael/*
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/sparql/prototype.js
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/js/amplify/amplify.store.min.js
# Apache Solr search platform. See /doc/3rd-party-licenses.txt for LICENSE file
solr/**/*
solr/*
# OWASP AntiSamy Project. See /doc/3rd-party-licenses.txt for LICENSE file
webapp/src/edu/cornell/mannlib/vitro/webapp/web/antisamy-vitro-1.4.4.xml
# A kluge class derived from JarJar code. See /doc/3rd-party-licenses.txt for LICENSE file
utilities/buildutils/src/com/tonicsystems/jarjar/KlugedDepFind.java
#Public Domain
webapp/web/js/json2.js
# Part of the OpenSocial integration - What license should apply here?
webapp/src/edu/ucsf/vitro/opensocial/GadgetController.java
webapp/src/edu/ucsf/vitro/opensocial/GadgetSpec.java
webapp/src/edu/ucsf/vitro/opensocial/GadgetViewRequirements.java
webapp/src/edu/ucsf/vitro/opensocial/OpenSocialManager.java
webapp/src/edu/ucsf/vitro/opensocial/PreparedGadget.java
webapp/web/js/openSocial/shindig.js
opensocial/sample-gadgets/SearchExample.xml
opensocial/sample-gadgets/ProfileListTool.xml
opensocial/sample-gadgets/SlideShare.xml
opensocial/sample-gadgets/Twitter.xml
opensocial/sample-gadgets/RDFTest.xml
opensocial/sample-gadgets/WEB-INF/web.xml
opensocial/sample-gadgets/Mentor.xml
opensocial/sample-gadgets/Links.xml

View file

@ -1,34 +0,0 @@
# --------------------------------------------------------------------------
# Properties for running the licenser utility in Vitro core.
# --------------------------------------------------------------------------
# The path to the top level directory to be scanned or copied
# (if relative, then relative to this file)
source_dir = ../../../
# The path to the top level directory to copy into (ignored if only scanning)
# (if relative, then relative to this file)
target_dir =
# A list of filename globs that match the files we want to license,
# delimited by commas with optional white-space.
file_matchers = *.java, *.jsp, *.tld, *.xsl, *.xslt, *.css, *.js, *.ftl, *.xml
# "globs" that describe paths that we won't follow for scanning OR FOR COPYING.
# (relative to the source_dir)
skip_directories = ./bin, ./.svn, ./**/.svn, ./webapp/.build
# The path to a file containing filename/path globs that match the files that
# we know should have no license tags in them.
# The file contains one glob per line; blank lines and comments ("#") are ignored.
# (if relative, then relative to the source directory)
known_exceptions = webapp/config/licenser/known_exceptions.txt
# The path to the text of the license agreement (ignored if only scanning)
# If the agreement contains a ${year} token, the current year will be substituted.
# (if relative, then relative to the source directory)
license_file = doc/license.txt
# Set to 'full' for a full report, 'short' for a brief statment, or to anything
# else for a medium-length summary.
report_level = short

View file

@ -1,49 +0,0 @@
#
# This file sets the log levels for the Vitro webapp.
#
# There are 8 principal logging levels, as follows:
# <-- more messages ALL TRACE DEBUG INFO WARN ERROR FATAL OFF fewer messages -->
#
# The default logging level is specified on the rootLogger. Other levels can be
# set for individual classes or packages as desired.
#
# Examples of setting levels:
# log4j.logger.edu.cornell.mannlib.vitro.webapp.ConfigurationProperties=INFO
# -- sets INFO level for this one class
# log4j.logger.org.apache.catalina=INFO
# -- sets INFO level for all classes in "org.apache.catalina" package
# and any sub-packages.
#
# Documentation for this file can be found here:
# http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html#doConfigure(java.lang.String,%20org.apache.log4j.spi.LoggerRepository)
#
# More information can be found here:
# http://logging.apache.org/log4j/1.2/manual.html
#
# The "production" version of this file is log4j.properties.
# debug.log4j.properties exists will be used instead, if it exists, but is not stored in Subversion.
log4j.appender.AllAppender=org.apache.log4j.RollingFileAppender
log4j.appender.AllAppender.File= $${catalina.base}/logs/${webapp.name}.all.log
log4j.appender.AllAppender.MaxFileSize=10MB
log4j.appender.AllAppender.MaxBackupIndex=10
log4j.appender.AllAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.AllAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] %m%n
log4j.rootLogger=INFO, AllAppender
# These classes are too chatty to display INFO messages.
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=WARN
log4j.logger.org.semanticweb.owlapi.rdf.rdfxml.parser=WARN
# Spring as a whole is too chatty to display INFO messages.
log4j.logger.org.springframework=WARN
# suppress odd warnings from libraries
log4j.logger.org.apache.jena.sdb.layout2.LoaderTuplesNodes=FATAL
log4j.logger.org.apache.jena.sdb.sql.SDBConnection=ERROR
log4j.logger.org.openjena.riot=FATAL
log4j.logger.org.apache.jena.riot=FATAL
log4j.logger.org.directwebremoting=FATAL

View file

@ -1,149 +0,0 @@
JAVA_HOME=/usr/local/java/jdk1.5.0_06
TOMCAT_HOME=/usr/local/tomcat
CATALINA_HOME=/usr/local/tomcat
#these are for options that are only set at start time
# useful for jmx or remote debugging.
START_OPTS=""
# the gc log and the jvm options are saved in the logs directory
DATESTR=`date +%Y%m%d.%H%M`
GCFILE=$CATALINA_HOME/logs/gc$DATESTR.txt
OPT_FILE=$CATALINA_HOME/logs/opts$DATESTR.txt
# This is an example of the setenv.sh file from
# cugir-tng.mannlib.cornell.edu
# To use this file copy it to /usr/local/tomcat/bin/setenv.sh
# When catalina.sh is called this file will be used to
# set the environmental variables that are
# in effect when starting the JVM for tomcat.
# java memory tools:
# jconsole is useful to watch the survivor, Edan, tenured and
# perm spaces. gcviewer is useful for statistics.
#An acceptable group of settings, use this as a starting point
# CATALINA_OPTS=" -Xms1024m -Xmx1024m -XX:MaxPermSize=128m \
# -XX:+UseParallelGC \
# -Dfile.encoding=UTF-8 \
# -Xloggc:$GCFILE -XX:+PrintGCDetails -XX:+PrintGCTimeStamps "
# attempting a low GCTimeRatio,
# GCTimeRatio indicates how much time to spend in gc vs. application
# app time / gc time = 1 / (1+ GCTimeRatio)
# GCTimeRatio of 11 is aprox %8 of the time in GC
#
# Result: best so far. After about 12 hours the heap is
# hovering around 100mb. This is the first group of settings
# that seem like they will be stable for a long period of time.
# throughput is 98.79%
# This is a log for these settings: /usr/local/tomcat/logs/gc20060809.1638.txt
CATALINA_OPTS=" -Xms1024m -Xmx1024m -XX:MaxPermSize=128m \
-XX:+UseParallelGC -XX:GCTimeRatio=11 -XX:+UseAdaptiveSizePolicy \
-Dfile.encoding=UTF-8 \
-Xloggc:$GCFILE -XX:+PrintGCDetails -XX:+PrintGCTimeStamps "
# bdc34 2006-08-08
# Trying adaptiveSizePolicy with parallel GC.
# Result: This did an out of memory when a crawler came along
# but even before that it looked bad.
# CATALINA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=128m \
# -XX:NewSize=512m \
# -XX:+UseParallelGC -XX:+UseAdaptiveSizePolicy \
# -Dfile.encoding=UTF-8 \
# -XX:+PrintGCDetails -XX:+PrintGCTimeStamps \
# -Xloggc:$GCFILE "
# bdc34 2006-08-08
# Trying the concurrent gc
# Result: after 10min it seems odd. The survivor space doesn't get
# used at all. It is always showing up in jconsole as zero mb. So
# objects are going directly from the edan space to the tenured space?
#
# Result: sort of rapid growth of heap with odd paterns of collection.
# doesn't seem useful
# CATALINA_OPTS="-Xms512m -Xmx512m -XX:MaxPermSize=256m \
# -XX:+UseConcMarkSweepGC \
# -XX:+UseAdaptiveSizePolicy \
# -XX:-TraceClassUnloading \
# -Dfile.encoding=UTF-8 \
# -XX:+PrintGCDetails -XX:+PrintGCTimeStamps \
# -Xloggc:/usr/local/tomcat/logs/gc.txt "
# bdc34 2006-08-07
# Attempting to increase the PermGen Size. Notice
# that PermGen size is in addition to the heap
# size specified in -Xmx.
#
# Also removing GCTimeRatio to allow for
# a lot of garbage collecting. I don't want
# any bound on GC, time or throughput. I don't
# know if not specifying a value will achieve this.
#
# Logging gc to /usr/local/tomcat/logs/gc.txt
# so I can look at it with http://www.tagtraum.com/gcviewer.html
#
# Setting max heap to initial heap to avoid growing the
# heap and associated gc cycles.
#
# Result: I ran this for two days and it seemed to work well.
# It would do minor collections for about 20h. The heap would
# get to around 1G and then the jvm would do
# a full colleciton that would drop the heap down to 50m.
# It seems that having the heap at 1G only buys time and
# that the application could live in 128-256mb.
# gcviewer was reporting 99.0% collection rates.
# It seems that these settings would work but might need to
# be restarted about once a week.
#
# Increasing the MaxPermSize seems to be important.
# The permGen includes things like classes and code. This is
# a problem since JSPs are classes and code so reloading a JSP
# adds to the permGen. The documentation weakly indicates that
# the permGen gets collected in full collections. I have not
# seen evidence that this it does when watching jconsole.
# Sun's JVM seperates the heap and classes but IBM and BEA do not.
#
# CATALINA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m \
# -XX:+UseParallelGC \
# -Dfile.encoding=UTF-8 \
# -XX:+PrintGCDetails -XX:+PrintGCTimeStamps \
# -Xloggc:/usr/local/tomcat/logs/gc.txt "
#bdc 2005-10-18
# CATALINA_OPTS="-server -Xms512m -Xmx1024m \
# -XX:+UseParallelGC \
# -XX:ParallelGCThreads=8 -XX:-PrintTenuringDistribution \
# -XX:MaxPermSize=256 \
# -XX:NewRatio=5 -XX:GCTimeRatio=19 -XX:SurvivorRatio=32 \
# -Dfile.encoding=UTF-8 \
# -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/local/tomcat/log/gc.txt \
# -verbose:gc "
#These are the java command args needed to allow remote jmx
JMXREMOTE=" -Dcom.sun.management.jmxremote.port=8022 "
#we only what jmxremote when we start, not on stop since the
#port will be in use. This also could be done with jpda
START_OPTS="$JMXREMOTE"
# we want to allow access to files created by tomcat by the mannit group
umask 002
# this makes a link from the current gc log to a place were we can get it over http
# those '&& true' are just to force success so we don't exit
rm -f /usr/local/apache/htdocs/private/tmp/gc.txt && true
ln -f -s $GCFILE /usr/local/apache/htdocs/private/tmp/gc.txt && true
#We want a record of the JVM options to compare with the gc log.
echo "CATALINA_OPTS: $CATALINA_OPTS" > $OPT_FILE
echo "START_OPTS: $START_OPTS" >> $OPT_FILE
# We need to export any variables that are to be used outside of script:
export JAVA_HOME CATALINA_OPTS TOMCAT_HOME CATALINA_HOME
export START_OPTS
# displays a note about what parameters will be used:
#echo "Using CATALINA Opts from tomcat/bin/setenv.sh: "
#echo " $CATALINA_OPTS"

View file

@ -1,7 +0,0 @@
<Context>
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
<!--
Disable the attempt to persist sessions when Tomcat shuts down.
-->
<Manager pathname="" />
</Context>

View file

@ -1,909 +0,0 @@
#
# Text strings for the controllers and templates
#
# Default (English)
#
save_changes = Guardar cambios
save_entry=Guardar entrada
select_existing=Seleccione existente
select_an_existing=Seleccione una existente
add_an_entry_to=Agregar una entrada de tipo
change_entry_for=Cambie la entrada de:
add_new_entry_for=Añadir nueva entrada para:
change_text_for=Cambie el texto para:
cancel_link = Cancelar
cancel_title = cancelar
required_fields = campos obligatorios
or = o
alt_error_alert = Icono de alerta con error
alt_confirmation = Icono de confirmación
for = para
email_address = Dirección de correo electrónico
first_name = Primer nombre
last_name = Apellido
roles = Roles
status = Estado
ascending_order = orden ascendente
descending_order = orden descendente
select_one = Seleccione uno
type_more_characters = escribir más caracteres
no_match = No hay resultados
request_failed = Error en la solicitud. Por favor, póngase en contacto con el administrador del sistema.
#
# Image upload pages
#
upload_page_title = Subir foto
upload_page_title_with_name = Subir imagen para {0}
upload_heading = Subir foto
replace_page_title = Reemplazar imagen
replace_page_title_with_name = Cambie la imagen por {0}
crop_page_title = Recortar imagen
crop_page_title_with_name = Recorte imagen para {0}
current_photo = Foto actual
upload_photo = Suba foto
replace_photo = Reemplace foto
photo_types = (JPEG, GIF, o PNG)
maximum_file_size = Tamaño máximo de archivo: {0} megabytes
minimum_image_dimensions = Dimensiones mínimas de imagen: {0} x {1} pixels
cropping_caption = La foto de tu perfil se verá como la imagen de abajo.
cropping_note = Para realizar ajustes, arrastre alrededor y cambie el tamaño de la foto de la derecha. Cuando esté satisfecho con su foto, haga clic en el botón "Guardar foto".
alt_thumbnail_photo = Foto de individuo
alt_image_to_crop = Imagen que desea recortar
alt_preview_crop = Vista previa de la foto recortada
delete_link = Borrar foto
submit_upload = Subir foto
submit_save = Guardar foto
confirm_delete = ¿Seguro que quiere borrar esta foto?
imageUpload.errorNoURI = No se proporcionó ninguna entidad URI
imageUpload.errorUnrecognizedURI = Este URI no se reconoce como perteneciente a cualquiera: ''{0}''
imageUpload.errorNoImageForCropping = No hay archivo de imagen que desea recortar.
imageUpload.errorImageTooSmall = La imagen cargada debe ser al menos {0} píxeles de alto y {1} píxeles de ancho.
imageUpload.errorUnknown = Lo sentimos, no pudimos procesar la foto que nos ha facilitado. Por favor, intente otra foto.
imageUpload.errorFileTooBig = Por favor, sube una imagen más pequeña que {0} megabytes.
imageUpload.errorUnrecognizedFileType = ''{0}'' no es un tipo de archivo de imagen reconocida. Por favor, sube JPEG, GIF o PNG solamente.
imageUpload.errorNoPhotoSelected = Por favor, busque y seleccione una foto.
imageUpload.errorBadMultipartRequest = Error al analizar la solicitud de varias partes para subir una imagen.
imageUpload.errorFormFieldMissing = El formulario no contiene a {0} ''campo'' ".
#
# User Accounts pages
#
account_management = Gestión de cuentas
user_accounts_link = Las cuentas de usuario
user_accounts_title = cuentas de usuario
login_count = Ingresa contar
last_login = Última sesión
add_new_account = Añadir nueva cuenta
edit_account = Edit cuenta
external_auth_only = Externamente autenticados
reset_password = Restablecer contraseña
reset_password_note = Nota: Las instrucciones para restablecer la contraseña serán enviados por correo electrónico a la dirección indicada anteriormente. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico.
new_password = Nueva contraseña
confirm_password = Confirmar nueva contraseña
minimum_password_length = Mínimo de {0} caracteres de longitud; maximo de {1}.
leave_password_unchanged = Dejando esto en blanco significa que no se puede cambiar la contraseña.
confirm_initial_password = Confirmar contraseña inicial
new_account_1 = Una nueva cuenta
new_account_2 = fue creado con éxito.
new_account_title = nueva cuenta
new_account_notification = Un correo electrónico de notificación ha sido enviada a {0} con las instrucciones para activar la cuenta y una contraseña.
updated_account_1 = La cuenta para el
updated_account_2 = se ha actualizado.
updated_account_title = descripción actualizada
updated_account_notification = Un correo electrónico de confirmación ha sido enviado a {0} con instrucciones para restablecer la contraseña. La contraseña no se restablecerá hasta que el usuario sigue el enlace que aparece en este correo electrónico.
deleted_accounts = Suprimido {0} {0, choice, 0#cuentas|1#cuenta|1<cuentas}.
enter_new_password = Introduzca su nueva contraseña para {0}
error_no_email_address = Introduzca su dirección de correo electrónico.
error_no_password = Por favor, introduzca su contraseña.
error_incorrect_credentials = El email o la contraseña son incorrectos.
logins_disabled_for_maintenance = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema.
error_no_new_password = Introduzca su nueva contraseña.
error_passwords_dont_match = Las contraseñas introducidas no coinciden.
error_password_length = Introduce una contraseña entre {0} y {1} caracteres de longitud.
error_previous_password = La nueva contraseña no puede coincidir con la actual.
search_accounts_button = Cuentas búsqueda
accounts_search_results = Resultados de la búsqueda
select_account_to_delete = seleccione esta cuenta para eliminarlo
click_to_view_account = haga clic para ver detalles de la cuenta
filter_by_roles = Filtrar por funciones
view_all_accounts = Ver todas las cuentas
view_all_accounts_title = ver todas las cuentas
new_account_note = Nota: Un correo electrónico será enviado a la dirección indicada anteriormente notificar que una cuenta ha sido creada. Se incluirá instrucciones para la activación de la cuenta y la creación de una contraseña.
initial_password = Contraseña inicial
submit_add_new_account = Añadir nueva cuenta
account_created = Su {0} cuenta ha sido creada.
account_created_subject = Su {0} cuenta ha sido creada.
confirm_delete_account_singular = ¿Está seguro de que desea eliminar esta cuenta?
confirm_delete_account_plural = ¿Está seguro de que desea eliminar estas cuentas?
verify_this_match = verificar este partido
verify_this_match_title = verificar este partido
change_profile = cambiar el perfil
change_profile_title = cambiar el perfil
auth_matching_id_label = Autenticación externo. ID / Matching ID
auth_id_label = Código del inmueble autenticación
auth_id_in_use = Este identificador está ya en uso.
auth_id_explanation = Se puede utilizar para asociar la cuenta con el perfil del usuario a través de la propiedad correspondiente.
associated_profile_label = Perfil asociada:
select_associated_profile = Seleccione el perfil asociado
create_associated_profile = Cree el perfil asociado
email_changed_subject = Su {0} cuenta de correo electrónico ha cambiado.
create_your_password = Crea tu Contraseña
password_created_subject = Su {0} contraseña ha sido creado con éxito.
password_reset_pending_subject = {0} restablecer solicitud de contraseña
password_reset_complete_subject = Su {0} ha cambiado la contraseña.
reset_your_password = Renovar su contraseña
first_time_login = Log Por primera vez en
create_account = Crear una cuenta
cant_activate_while_logged_in = Usted no puede activar la cuenta para {0} mientras está conectado como {1}. Por favor, cierre la sesión y vuelva a intentarlo.
account_already_activated = La cuenta para {0} ya se ha activado.
cant_change_password_while_logged_in = El usuario no puede cambiar la contraseña de {0} mientras está conectado como {1}. Por favor, cierre la sesión y vuelva a intentarlo.
password_change_not_pending = La contraseña para {0} ya se ha restablecido.
password_changed_subject = Contraseña cambiada.
account_no_longer_exists = La cuenta que está tratando de establecer una contraseña ya no está disponible. Por favor, póngase en contacto con el administrador del sistema si crees que esto es un error.
password_saved = Su contraseña ha sido guardada.
password_saved_please_login = Su contraseña ha sido guardada. Por favor, ingrese
please_provide_contact_information = Por favor proporcione su información de contacto para terminar de crear la cuenta.
first_time_login_note = Nota: Un correo electrónico será enviado a la dirección indicada anteriormente notificar que una cuenta ha sido creada.
myAccount_heading = Mi cuenta
myAccount_confirm_changes = Los cambios se han guardado.
myAccount_confirm_changes_plus_note = Los cambios se han guardado. Un correo electrónico de confirmación ha sido enviado a {0}.
email_change_will_be_confirmed = Nota: si los cambios por correo electrónico, un mensaje de confirmación será enviado a la nueva dirección de correo electrónico indicada anteriormente.
#email_changed_subject = "Your VIVO email account has been changed.");
who_can_edit_profile = ¿Quién puede modificar mi perfil
add_profile_editor = Añadir editor de perfiles
select_existing_last_name = Seleccione un apellido existente
selected_editors = Selección de los editores
remove_selection = Eliminar selección
remove_selection_title = eliminar la selección
external_id_not_provided = Error de acceso - ID externo no se encuentra.
external_id_already_in_use = Cuenta de usuario ya existe para ''{0}''
error_no_email = Debe proporcionar una dirección de correo electrónico.
error_email_already_exists = Una cuenta con la dirección de correo electrónico ya existe.
error_invalid_email = '' {0}'' no es una dirección de correo electrónico válida.
error_external_auth_already_exists = Una cuenta con dicho ID de autorización externa ya existe.
error_no_first_name = Debe proporcionar un nombre de pila.
error_no_last_name = Debe proporcionar un apellido.
error_no_role = Debe seleccionar una función.
error_password_mismatch = Las contraseñas no coinciden.
logged_in_but_no_profile = Usted ha ingresado, pero el sistema no contiene ningún perfil para usted.
unknown_user_name = amigo
login_welcome_message = Bienvenido {1, choice, 1# | 1< atrás}, {0}
external_login_failed = Acceso externo no
logged_out = Ha cerrado la sesión.
insufficient_authorization = Lo sentimos, pero no está autorizado para ver la página solicitada. Si crees que esto es un error, por favor póngase en contacto con nosotros y estaremos encantados de ayudarle.
#
# "partial" individual templates ( /templates/freemarker/body/partials/individual )
#
manage_publications_link = gestionar las publicaciones
manage_grants_and_projects_link = gestión de subvenciones y proyectos
manage_affiliated_people_link = gestión de personas afiliadas
group_name = Nombre del grupo
scroll_to_menus = desplazarse a los menús de grupo de propiedad
properties_capitalized = Propiedades
properties = propiedades
view_all_capitalized = Ver todos
name = nombre
admin_panel = Panel de Administración
edit_this_individual = Editar este individuo
verbose_status_on = en
verbose_status_off = de
verbose_property_status = Display propiedad detallado es
verbose_control = el control detallado
verbose_turn_on = Encender
verbose_turn_off = Apagar
resource_uri = URI de recursos
individual_not_found = Individual no encontrado
individual_not_found_msg = El individuo no se encontr<74> en el sistema.
entity_to_query_for = Este id es el identificador de la entidad para consultar. netid también funciona.
menu_ordering = Menú pedidos
refresh_page_after_reordering = Actualizar la página después de los artículos de menú reordenar
display_has_element_error = Se produjo un error en el sistema. La pantalla: propiedad hasElement no se pudo recuperar.
return_to = volver a {0}
other = otro
#
# admin templates ( /templates/freemarker/body/admin )
#
logins_already_restricted = Inicios de sesión ya se encuentran restringidas.
logins_not_already_restricted = Inicios de sesión ya no están restringidos.
logins_restricted = Inicios de sesión están restringidas.
logins_not_restricted = Inicios de sesión ya no están restringidos.
logins_are_open = Inicios de sesión están abiertas a todos.
logins_are_restricted = Inicios de sesión se encuentran restringidas.
remove_restrictions = Eliminar las restricciones
restrict_logins = Restringir inicios de sesión
error_alert_icon = Error icono de alerta
current_user = Usuario actual
external_auth_id = Autenticación del inmueble
user_role = Papel
not_logged_in = No conectado
identifiers = Identificadores
associated_individuals = Las personas asociadas
match_by = coincidir por {0}
matching_prop_not_defined = Inmueble con no se define
may_edit = Puede editar
may_not_edit = No puedes editar
none = ninguno
identifier_factories = Fábricas de identificación
policies = Políticas
authenticator = Autenticador
background_threads = Temas de fondo
name_capitalized = Nombre
work_level = Nivel de trabajo
since = Desde
flags = Banderas
search_index_status = Búsqueda Índice de Estado
search_index_not_connected = El índice de búsqueda no está conectado.
failed = fracasado
check_startup_status = Compruebe la página de estado de inicio y / o registros de Tomcat para obtener más información.
search_indexer_idle = El indizador de búsqueda está inactivo.
most_recent_update = La actualización más reciente fue en
rebuild_button = Reconstruir
reset_search_index = Restablecer el índice de búsqueda y volver a llenarla.
preparing_to_rebuild_index = Preparación para reconstruir el índice de búsqueda.
since_elapsed_time = vez desde {0}, {1} transcurrido
current_task = {0} el índice de búsqueda
since_elapsed_time_est_total = tiempo total desde {0}, el tiempo transcurrido {1}, {2} estima
index_recs_completed = Completado {0} de {1} registros de índice.
fatal_error = Error Fatal
fatal_error_detected = {0} detectado un error grave durante el inicio.
warning = Advertencia
warnings_issued = {0} emitido advertencias durante el arranque.
startup_trace = Rastro de inicio
full_list_startup = La lista completa de los eventos y mensajes de inicio.
startup_status = Estado de inicio
continue = Continuar
#
# contact form templates ( /templates/freemarker/body/contactForm )
#
rejected_spam = RECHAZADO - SPAM
feedback_thanks_heading = Gracias por su colaboración
feedback_thanks_text = Gracias por contactar con nuestra curación y equipo de desarrollo de usted. Nosotros responderemos a su consulta lo antes posible.
return_to_the = Vuelva a la
home_page = tu página de inicio
from_capitalized = De
ip_address = Dirección IP
viewing_page = Página de visualización Probable
comments = Comentarios
interest_thanks = Gracias por su interés en {0} usted. Por favor, envíe este formulario con preguntas, comentarios o sugerencias sobre el contenido de este sitio.
full_name = Nombre completo
comments_questions = Comentarios, preguntas o sugerencias
enter_in_security_field = Por favor introduce las letras se muestran a continuación en el campo de la seguridad
send_mail = Enviar correo
#
# display edit template ( /templates/freemarker/body/displayEdit )
#
display_admin_header = Mostrar administración y configuración
#
# error templates ( /templates/freemarker/body/error )
#
we_have_an_error = Se produjo un error en el sistema.
error_was_reported = Este error se ha informado que la administración del sitio.
error_message = Mensaje de error
stack_trace = Seguimiento de la pila
trace_available = completa rastro disponibles en el registro vivo
caused_by = Causada por
requested_url = URL solicitada
error_occurred = Se ha producido un error en el sitio VIVO
error_occurred_at = Se ha producido un error en su sitio VIVO en {0}.
#
# login templates ( /templates/freemarker/body/login )
#
internal_login = Login Interna
no_email_supplied = Sin correo electrónico suministrado.
no_password_supplied = Suministrado ninguna contraseña.
logins_temporarily_disabled = Los inicios de sesión de usuario están desactivados temporalmente mientras se mantiene el sistema.
incorrect_email_password = Email o contraseña es incorrecta.
password_length = La contraseña debe tener entre {0} y {1} caracteres.
password_mismatch = Las contraseñas no coinciden.
new_pwd_matches_existing = Su nueva contraseña debe ser diferente de la contraseña existente.
enter_email_password = Introduzca la dirección de correo electrónico y la contraseña de su cuenta de Vitro interna.
change_password = Debe cambiar su contraseña para entrar
email_capitalized = Email
password_capitalized = Contraseña
login_button = Iniciar la sesión
fake_external_auth = Autenticación externa Fake
enter_id_to_login = Introduzca el ID de usuario que desea firmar con el nombre, o haga clic en Cancelar.
username = Nombre de usuario
submit_button = Presentar
#
# body templates ( /templates/freemarker/body )
#
class_name = nombre de la clase
continued = continuación
expecting_content = Esperando contenido?
try_rebuilding_index = Intenta reconstruir el índice de búsqueda
please = Complacer
login_to_manage_site = una sesión para administrar este sitio
log_in = iniciar la sesión
to_manage_content = para gestionar el contenido.
no_content_in_system = Actualmente no existe {0} contenido en el sistema de
you_can = Usted puede
add_content_manage_site = agregar contenido y administrar este sitio
from_site_admin_page = desde la página de administración del sitio.
view_list_in_rdf = Ver la lista {0} en formato RDF
rdf = RDF
pages = páginas
menu_management = Gestión Menu
setup_navigation_menu = Configuración en el menú principal de navegación de su sitio web
save_button = Guardar
page_select_permission = Seleccione los permisos de página
page_select_permission_option = Seleccione permiso
page_admin_permission_option = Sólo los administradores pueden ver esta página
page_curator_permission_option = Curadores y superiores pueden ver esta página
page_editor_permission_option = Editores y arriba pueden ver esta página
page_loggedin_permission_option = Conectado individuos puede ver esta página
page_public_permission_option = Cualquier persona puede ver esta página
recompute_inferences = Las inferencias Recompute
revision_info = Información de revisiones
levels = Niveles
release = liberar
revision = revisión
build_date = Fecha de la estructura
dates = Fechas
current_date_time = Fecha y hora actual:
current_date = Fecha y hora actual:
current_time = Hora:
formatted_date_time = Con formato de fecha y hora
apples = Manzanas
fruit = Fruta
animal = Animal:
book_title = Título del libro:
zoo_one = Zoo 1
zoo_two = Zoo 2
berries = Bayas:
raw_string_literals = Literales de cadena primas
containers_do_not_pick_up_changes = Los contenedores no recogen los cambios en el valor de sus elementos
list_elements_of = Lista de los elementos de
contains_no_pears = no contiene peras
numbers = Números
undo_camelcasing = Uncamelcasing
run_sdb_setup = Ejecutar la instalación SDB
unrecognized_user = Usuario no reconocido
no_individual_associated_with_id = Por alguna razón, no hay ninguna persona en VIVO que se asocia con su ID de red. Tal vez usted debería ponerse en contacto con el administrador de VIVO.
page_not_created = p<EFBFBD>gina no pudo ser creado
page_not_created_msg = Se ha producido un error al crear la p<>gina, por favor, compruebe los registros.
page_not_found = P<EFBFBD>gina no encontrada
page_not_found_msg = La p<>gina no se ha encontrado en el sistema.
page_uri_missing = No se especifica la p<>gina URI
page_uri_missing_msg = No se pudo generar la p<>gina pd no estaba claro en qu<71> p<>gina se est<73> solicitando. Una asignaci<63>n de direcci<63>n URL es posible que falte.
#
# site admin templates ( /templates/freemarker/body/siteAdmin )
#
advanced_data_tools = Herramientas de datos avanzadas
add_remove_rdf = Añadir / Quitar datos RDF
ingest_tools = Ingerir herramientas
rdf_export = RDF exportación
sparql_query = Consulta SPARQL
sparql_query_builder = Generador de consultas SPARQL
display_options = Opciones de visualización
asserted_class_hierarchy = Confirmada jerarquía de las clases
inferred_class_hierarchy = Jerarquía de clases inferido
all_classes = Todas las Clases
classes_by_classgroup = Las clases por grupo de clase
add_new_classes = Añadir nueva clase
add_new_group = Agregar nuevo grupo
hide_show_subclasses = ocultar / mostrar las subclases
hide_subclasses = ocultar subclases
expand_all = expandir todo
data_input = Introducción de datos
add_individual_of_class = Añadir individuales de esta clase
create_classgroup = Crear un grupo de clase
please_create = Por favor, cree
a_classgroup = un grupo de clase
associate_classes_with_group = y las clases asociadas con el grupo creado.
site_maintenance = Mantenimiento del sitio
rebuild_search_index = Reconstruir índice de búsqueda
rebuild_vis_cache = Reconstruir caché de visualización
recompute_inferences_mixed_caps = Inferencias Recompute
site_administration = Administración del Sitio
add_property_group = Añadir un nuevo grupo de propiedades
hide_show_properties = ocultar / mostrar las propiedades
hide_properties = ocultar las propiedades
property_hierarchy = Jerarquía de la propiedad
all_x_properties = Todos los {0} Propiedades
property_groups = Grupos de propiedades
add_new = Añadir nuevo
object = objeto
data = datos
property = propiedad
ontology_editor = Editor Ontología
cause = Causa:
ontology_list = Lista de Ontología
class_management = Gestión de clases
class_hierarchy = Jerarquía de clases
class_groups = Los grupos de clase
property_management = Gestión de la propiedad
object_property_hierarchy = Jerarquía de propiedades de objetos
data_property_hierarchy = Jerarquía de propiedades de datos
site_config = Configuración del sitio
internal_class_i_capped = Clases interna Institucional
manage_profile_editing = Gestione edición de perfiles
page_management = Gestión de la página
menu_ordering_mixed_caps = Menú pedido
restrict_logins_mixed_caps = Restringir conexiones
site_information = Información del sitio
user_accounts = Las cuentas de usuario
activate_developer_panel = Activar el panel desarrollador
activate_developer_panel_mixed_caps = Activar el panel desarrollador
#
# search controller ( PagedSearchController.java )
#
error_in_search_request = La solicitud de búsqueda contenía errores.
enter_search_term = Por favor, introduzca un término de búsqueda.
invalid_search_term = Criterio de búsqueda no es válido
paging_link_more = Más información...
no_matching_results = No hay resultados.
search_failed = Buscar falló.
search_term_error_near = El término de búsqueda tuvo un error cerca
search_for = Búsqueda para ''{0}''
#
# search templates ( /templates/freemarker/body/search )
#
search_results_for = Resultados de la búsqueda
limited_to_type = limitado a escribir
search_help = buscar ayuda
not_expected_results = No son los resultados que esperaba?
display_only = Mostrar únicamente
class_group_link = enlace de un grupo de clases
limit = Limitar
limit_to = Limitar a
class_link = Enlace clase
previous = Anterior
page_link = enlace de la página
next_capitalized = Próximo
download_results = resultados de la transferencia directa
to = a
#
# shortview templates ( /templates/freemarker/body/partials/shortview )
#
view_profile_page_for = Ver la página de perfil de
#
# menupage templates ( /templates/freemarker/body/partials/menupage )
#
browse_page_javascript_one = Esta página de exploración requiere javascript, pero tu navegador está configurado para deshabilitar javascript. O habilitar Javascript o utilizar el
browse_page_javascript_two = para buscar información.
index_page = página de índice
browse_all_in_class = Examinar todos los individuos de esta clase
select_all = seleccionar todo
all = todo
browse_all_starts_with = Vea todas las personas cuyo apellido empieza por {0}
browse_all_public_content = Usted puede navegar por todo el contenido público actualmente en el sistema con el
browse_all_content = navegar por todo el contenido
#
# partial templates ( /templates/freemarker/body/partials )
#
no_content_create_groups_classes = Actualmente no hay ningún contenido en el sistema, o si necesita crear grupos de clase y asignar sus clases con ellos.
browse_capitalized = Busque
browse_by = Búsqueda por
#
# partial account templates ( /templates/freemarker/body/partials/accounts )
#
delete_button = Borrar
accounts = cuentas
accounts_per_page = cuentas por página
update_button = Actualizar
#
# pagemanagement templates ( /templates/freemarker/body/pagemanagement )
#
title_capitalized = Título
type_capitalized = Tipo
uri_not_defined = URI de página no definido
page_uri = Página URI
no_pages_defined = No hay páginas aún definidos.
add_page = Añadir página
custom_template = Plantilla Personalizada
menu_page = Menu Página
controls = Controles
listed_page_title = listado título de la página
untitled = Sin titulo-
delete_page = borrar esta página
view_profile_for_page = ver el perfil individual de esta página
menu_orering = Menú pedidos
use_capitalized = Utilizar
to_order_menu_items = para establecer el orden de los elementos del menú.
#
# menupage templates ( /templates/freemarker/body/menupage )
#
page_not_configured = Esta página aún no está configurado.
implement_capitalized = Implementar
a_link = un enlace
configure_page_if_permissable = para configurar esta página si el usuario tiene permiso.
no_html_specified = No HTML especificado.
page_text = texto de la página
sparql_query_results = SPARQL Query Resultados
no_results_returned = Se devolvió resultados.
solr_individual_results = Clase personas Solr
select_vclass_uri = Seleccione VClass
#
# manage proxies templates ( /templates/freemarker/body/manageproxies )
#
operation_successful = La operación se ha realizado correctamente.
operation_unsuccessful = La operación no tuvo éxito. Los detalles completos se pueden encontrar en el registro del sistema.
relate_editors_profiles = Relacionar editores de perfil y los perfiles
info_icon = info icon
profile_editing_title = Los editores que seleccione en el lado izquierdo tendrá la posibilidad de editar los perfiles VIVO seleccione en el lado derecho. Puede seleccionar varios editores y varios perfiles, pero debe seleccionar un mínimo de 1 cada uno.
select_editors = Seleccione editores
select_last_name = Seleccione un apellido existente
processing_indicator = Indicador de tiempo de procesamiento
type_more_chars = escribir más caracteres
select_profiles = Seleccione perfiles
profile_editors = Editores de perfil
search_button = Buscar
view_profile_editors = Ver todos los editores de perfil
delete_profile_editor = Eliminar editor de perfiles
add_profile = Añadir perfil
selected_profiles = Perfiles seleccionados
save_profile_changes = Guarde los cambios en los perfiles
#
# page partials templates ( /templates/freemarker/page/partials )
#
copyright = derechos de autor
all_rights_reserved = Todos los derechos reservados.
terms_of_use = Términos de uso
site_name = nombre del sitio
end_your_Session = Finalice la sesión
log_out = Finalizar la sesión
manage_site = Administrar este sitio
site_admin = Site Admin
more_details_about_site = Más detalles sobre este sitio
about = Acerca de
contact_us = Contáctenos
send_feedback_questions = Envíenos sus comentarios o hacer una pregunta
visit_project_website = Visite el sitio web del proyecto nacional
support = Apoyar
view_content_index = Ver un resumen de los contenidos de este sitio
index = Índice
search_form = Formulario de búsqueda
select_locale = seleccionar la configuración regional
language_selection_failed = Hubo un problema en el sistema. Su elección de la lengua fue rechazada.
menu_item = elemento de menú
version = Versión
#
# widget templates ( /templates/freemarker/widgets )
#
individual_name = nombre individual
vclassAlpha_not_implemented = vclassAlpha aún no está implementado.
test_for_logged_in_users = Este es el widget de pruebas para usuarios registrados.
test_for_nonlogged_in_users = Este es el widget de pruebas por falta de usuarios registrados.
login_status = Estado de ingreso:
alert_icon = Alerta Icono
javascript_require_to_edit = Para editar el contenido, tendrá que activar JavaScript.
javascript_instructions = java script de instrucciones
to_enable_javascript = Aquí están las instrucciones para habilitar JavaScript en su navegador web
external_auth_name = Nombre de autenticación externo
external_login_text = Entrar usando Shibboleth GatoOso
account = cuenta
change_password_to_login = Cambiar contraseña para iniciar sesión en
new_password_capitalized = Nueva contraseña
confirm_password_capitalized = Confirmar Contraseña
already_logged_in = Usted ya está registrado
#
# lib templates ( /templates/freemarker/lib )
#
statistics = Estadística
manage_list_of = Administrar la lista de
manage = gestionar
add = añadir
entry = entrada
edit_entry = modifique esta entrada
delete_entry = eliminar esta entrada
click_to_view_larger = clic para ampliar la imagen
photo = Foto
no_image = ninguna imagen
placeholder_image = imagen de marcador de posición
manage_labels = gestionar etiquetas
manage_list_of_labels = administrar la lista de etiquetas
view_list_of_labels = lista de etiquetas visualizarla
view = ver
add_label = Añadir etiqueta
add_label_for_language = idioma
unsupported_ie_version = Esta forma no se admite en las versiones de Internet Explorer debajo de la versión 8. Actualiza tu navegador, o cambiar a otro navegador, como Firefox.
#
# edit templates ( /templates/freemarker/edit and edit/forms )
#
edit_capitalized = Editar
add_capitalized = Añadir
create_entry = Crear entrada
select_existing_collaborator = Seleccione un colaborador existente para {0}
selected = Seleccionado
change_selection = cambiar la selección
there_are_no_entries_for_selection = No hay entradas en el sistema desde el cual elegir.
the_range_class_does_not_exist= La clase de rango de esta propiedad no existe en el sistema.
editing_prohibited = Esta propiedad no está configurado actualmente para prohibir la edición.
confirm_entry_deletion_from = ¿Está seguro de que desea eliminar la siguiente entrada del
edit_date_time_value = Editar fecha / hora Valor
create_date_time_value = Crear valor fecha / hora
date_time_value_for = valor de fecha y hora para
start_interval_must_precede_end_earlier = El intervalo de inicio debe ser anterior al intervalo End.
end_interval_must_follow_start_interval = El intervalo final debe ser posterior a la de inicio del intervalo.
start_capitalized = Iniciar
end_capitalized = Final
create_capitalized = Crear
delete_entry_capitalized = Borrar este mensaje?
add_new_of_type = Añadir un nuevo elemento de este tipo
create_new_entry = Por favor, cree una nueva entrada.
no_appropriate_entry = Si no encuentra la entrada correspondiente en la lista de selección anterior
return_to_individual = Volver a la página individual
remove_menu_item = Eliminar elemento de menú
confirm_menu_item_delete = ¿Está seguro de que desea eliminar
remove_capitalized = eliminar
pretty_url = URL Pretty
start_with_leading_slash = Debe comenzar con una barra diagonal principal: / (por ejemplo, / personas)
default = Defecto
custom_template_mixed_caps = Plantilla personalizada
change_content_type = Cambiar el tipo de contenido
select_page_content_type = Seleccione el tipo de contenido para la página asociada
select_content_display = Seleccione el contenido para mostrar
all_capitalized = Todo
template_capitalized = Plantilla
selected_page_content_type = Seleccionado tipo de contenido para la página asociada
create_new = Crear un nuevo
enter_value_name_field = Por favor, introduzca un valor en el campo Nombre.
class_group_all_caps = Clase Grupo
save_this_content = Guardar este contenido
enter_fixed_html_here = Ingrese HTML fijado aquí
query_model = Consultas de modelo
variable_name_all_caps = Nombre de la variable
enter_sparql_query_here = Introduzca consulta SPARQL aquí
add_new_page = Añadir una nueva página
save_new_page = Guardar página nueva
edit_page = Editar {0} Página
content_type = Tipo de contenido
select_type = Seleccione un tipo
browse_class_group = Examinar Grupo Clase
fixed_html = HTML fija
add_types = Agregar uno o más tipos
begin_with_slash_no_example = Debe comenzar con una barra diagonal principal: /
slash_example = (Por ejemplo, / personas)
custom_template_requiring_content = Plantilla personalizada que requiere el contenido
custom_template_containing_content = Plantilla personalizada que contiene todo el contenido
a_menu_page = Esta es una página de menú
menu_item_name = Menu Nombre del artículo
if_blank_page_title_used = Si se deja en blanco, se utilizará el título de la página.
multiple_content_default_template_error = Con varios tipos de contenido , debe especificar una plantilla personalizada .
label = etiqueta
no_classes_to_select = No hay clases en el sistema desde el cual elegir.
#
# vitro theme templates ( /themes/vitro/templates )
#
powered_by = Desarrollado por
javascript_ie_alert_text = Este sitio utiliza elementos HTML que no son reconocidos por el Internet Explorer 8 y por debajo de la ausencia de JavaScript. Como resultado, el sitio no se representará apropiadamente. Para corregir esto, por favor, ya sea habilitar JavaScript, actualice a Internet Explorer 9, o utilizar otro navegador.
what_is_vitro = ¿Qué es VITRO?
vitro_description = Vitro es una ontología basada en la web de propósito general y editor de instancia pública con la navegación personalizable. Vitro es una aplicación web Java que se ejecuta en un contenedor de servlets Tomcat.
with_vitro = Con Vitro, puede:
vitro_bullet_one = Crear o cargar ontologías en formato OWL
vitro_bullet_two = Editar instancias y relaciones
vitro_bullet_three = Construir un sitio web público para mostrar los datos
vitro_bullet_four = Buscar sus datos
search_vitro = Buscar VITRO
filter_search = filtro de búsqueda
#
# custom form javascript variables ( /templates/freemarker/edit/js)
#
select_an_existing = Seleccione una existente
or_create_new_one = o crear uno nuevo.
sunday = Domingo
monday = Lunes
tuesday = Martes
wednesday = Miércoles
thursday = Jueves
friday = Viernes
saturday = Sábado
january = Enero
february = Febrero
march = Marzo
april = Abril
may = Mayo
june = Junio
july = Julio
august = Agosto
september = Septiembre
october = Octubre
november = Noviembre
december = Deciembre
#
# miscellaneous javascript variables ( webapp/web/js)
#
select_editor_and_profile = Usted debe seleccionar un mínimo de 1 y editor de perfil.
display_more_ellipsis = Más ...
show_more_content = mostrar más contenido
display_less = menos
browse_all = Hojee todo
content = contenido
please_format_email = Formatee su dirección de correo electrónico como:
or_enter_valid_address = o introducir otra dirección de correo electrónico completa y válida.
share_profile_uri = compartir el URI para este perfil
view_profile_in_rdf = ver ficha en formato RDF
close = cerrar
error_processing_labels = Solicitud de procesamiento Error: las etiquetas sin control no pudo ser eliminado.
drag_drop_to_reorder_menus = Arrastrar y soltar para cambiar el orden de los elementos del menú
reordering_menus_failed = Reordenación de los elementos del menú no.
page = página
view_page = Ver página
of_the_results = de los resultados
there_are_no = No hay
individuals_names_starting_with = las personas cuyo apellido empieza por
try_another_letter = Por favor, intente otra carta o navegar por todos.
individuals_in_system = individuos en el sistema.
select_another_class = Por favor, seleccione otra clase de la lista.
supply_name = Debe proporcionar un título
supply_url = Debe proporcionar una URL bastante
start_url_with_slash = La URL amigable debe comenzar con una barra diagonal principal
supply_template = Debe proporcionar una plantilla
supply_content_type = Debe proporcionar un tipo de contenido
select_content_type = Usted debe seleccionar el contenido que se incluirán en la página
delete = borrar
map_processor_error = Se ha producido un error y el mapa de los procesadores de este contenido está desaparecida. Por favor, póngase en contacto con el administrador
code_processing_error = Se ha producido un error y el código para el procesamiento de este contenido le falta un componente. Por favor, póngase en contacto con el administrador.
supply_class_group = Debe proporcionar un grupo de clase.
select_classes_to_display = Debe seleccionar las clases que se vea.
select_class_for_solr = Debe seleccionar una clase para mostrar sus individuos.
supply_variable_name = Debe suministrar una variable para guardar el contenido HTML.
apostrophe_not_allowed = El nombre de la variable no debe tener un apóstrofe.
double_quote_note_allowed = El nombre de la variable no debe tener una doble cita.
supply_html = Debe proporcionar algo de HTML o de texto.
supply_query_variable = Debe suministrar una variable para guardar los resultados de la consulta.
supply_sparql_query = Debe proporcionar una consulta SPARQL.
confirm_page_deletion = ¿Está seguro de que desea eliminar esta página:
show_subclasses = mostrar subclases
ontology_capitalized = Ontología
subclasses_capitalized = Las subclases
collapse_all = Contraer todo
classes_capitalized = Clases
display_rank = Mostrar Rango
show_properties = mostrar las propiedades
local_name = Nombre local
group_capitalized = Grupo
domain_class = Clase de dominio
range_class = Clase Rango
range_data_type = Tipo de datos de gama
sub_properties = Subpropiedades
subproperty = subpropiedad
manage_labels_for = Gestione Etiquetas para
manage_labels_capitalized = Gestione Etiquetas
manage_labels_intro = En el caso de que existan varias etiquetas en el mismo idioma, por favor, utilice el vínculo Eliminar para eliminar las etiquetas que no desea que se muestren en la página de perfil para un determinado idioma.
processing_icon = tratamiento
selection_in_process = Su selección se está procesando.view_labels_capitalized = Ver etiquetas
view_labels_capitalized = Ver etiquetas
view_labels_for = Ver Etiquetas de
select_an_existing_document = Seleccione un documento existente
datetime_year_required = Intervalos de fecha / hora deben empezar por un año. Ingrese una Fecha de inicio, un fin de año o los dos.
select_a_language = Seleccione un idioma
base_property_capitalized = Base propiedad
faux_property_capitalized = Faux propiedad
faux_property_listing = Lista de faux propiedades
faux_property_by_base = Faux propiedades por base propriedad
faux_property_alpha = Faux propiedades en orden alfabético
no_class_restrictions=No hay clases con una restricción de esta propiedad.
invalid_format=Formato inválido
four_digit_year=Entrada invalida. Por favor, introduzca un año de 4 dígitos.
year_numeric=Entrada invalida. El Año debe ser numérico.
year_month_day=Entrada invalida. Por favor, introduzca un año, mes y día.
minimum_ymd=Entrada invalida. Introduzca por lo menos un año, mes y día.
minimum_hour=Entrada invalida. Especifique por lo menos una hora.
year_month=Entrada invalida. Por favor ingrese un Año y Mes.
decimal_only=Entrada invalida. Se permite un punto decimal, pero miles separadores no son.
whole_number=Entrada invalida. Por favor, introduzca un número entero sin punto decimal o miles separadores.

View file

@ -1,43 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#if origination?has_content && origination == "helpLink">
<h2>Consejos Para la Búsqueda</h2>
<span id="searchHelp">
<a href="#" onClick="history.back();return false;" title="regresar a los resultados">regresar a los resultados</a>
</span>
<#else>
<h3>Consejos Para la Búsqueda</h3>
</#if>
<ul class="searchTips">
<li>Debe ser sencillo. Utilice corto, único a menos que las búsquedas están regresando muchos resultados.</li>
<li>Utilice comillas para buscar una frase entera -- por ejemplo, "<i>el plegamiento de proteínas</i>".</li>
<li>A excepción de los operadores booleanos, búsquedas <strong>no distinguen</strong> entre mayúsculas y minúsculas, por lo que "Ginebra" y "ginebra" son equivalentes</li>
<li>Si no está seguro de la ortografía correcta, ponga ~ al final de su término de búsqueda -- por ejemplo, <i>cabage~</i> encuentra <i>cabbage</i>, <i>steven~</i> encuentra <i>Stephen</i> y <i>Stefan</i> (así como otros nombres similares).</li>
</ul>
<h4><a id="advTipsLink" href="#">Consejos Avanzados</a></h4>
<ul id="advanced" class="searchTips" style="visibility:hidden">
<li>Cuando se introduce más de un término, la búsqueda devolverá resultados que contengan todas ellas a menos que agregue el operador booleano "OR" -- por ejemplo, <i>pollo</i> OR <i>huevos</i>.</li>
<li>"NOT" puede ayudar búsquedas límite -- por ejemplo, <i>clima</i> NOT <i>cambiar</i>.</li>
<li>Las búsquedas de frases se pueden combinar con operadores booleanos -- por exemplo, "<i>cambio climático</i>" OR "<i>calentamiento global</i>".</li>
<li>Asimismo, se encuentra cerca variaciones de palabras -- por exemplo, <i>secuencia</i> emparejas <i>secuencias</i> y <i>secuenciación</i>.</li>
<li>Utilice el carácter comodín * para que coincida con una variación aún mayor -- por exemplo, <i>nano*</i> emparejas <i>nanotechnology</i> y <i>nanofabrication</i>.</li>
<li>Search utiliza versiones acortadas de palabras -- por exemplo, una búsqueda de "cogni*" no encuentra nada, mientras que la "cogn*" encuentra tanto <i>cognitivo</i> and <i>cognición</i>.</li>
</ul>
<a id="closeLink" href="#" style="visibility:hidden;font-size:.825em;padding-left:8px">Close</a>
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/search.css" />')}
<script type="text/javascript">
$(document).ready(function(){
$('a#advTipsLink').click(function() {
$('ul#advanced').css("visibility","visible");
$('a#closeLink').css("visibility","visible");
$('a#closeLink').click(function() {
$('ul#advanced').css("visibility","hidden");
$('a#closeLink').css("visibility","hidden");
return false;
});
return false;
});
});
</script>

View file

@ -1,41 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<section id="terms" role="region">
<h2>Condiciones de uso</h2>
<h3>Aviso legal</h3>
<p>Este ${termsOfUse.siteName} sitio web contiene material&mdash;información de texto, la publicación
citas, enlaces e imágenes&mdash;proporcionado por ${termsOfUse.siteHost} y varios terceros, tanto de los
individuos y las organizaciones, comerciales y de otro tipo. En la medida de derecho de autor, la información
presentada en el sitio web VIVO y disponible como Resource Description Framework (RDF) datos de VIVO en
${termsOfUse.siteHost} se destina para uso público y se distribuye libremente bajo los términos de la
<a href="http://creativecommons.org/licenses/by/3.0/" target="_blank" title="creative commons">Creative Commons
CC-BY 3.0</a> licencia, que le permite copiar, distribuir, mostrar y hacer que los derivados de esta
información, siempre le das crédito a ${termsOfUse.siteHost}. Cualquier información que no sea derecho de autor
está disponible para usted en virtud de una
<a href="http://creativecommons.org/publicdomain/zero/1.0/" target="_blank" title="cco waiver">exención
CC0</a>. Sin embargo, los documentos originales, imágenes o páginas web adjuntas o vinculado desde VIVO podrán
contener información con derechos de autor y sólo deben ser utilizados o distribuidos en los términos que se
incluyen con cada fuente o de acuerdo con los principios del uso justo.</p>
<h3>Descargo de responsabilidad</h3>
<p>${termsOfUse.siteHost?cap_first} ofrece ninguna garantía, expresa o implícita, incluyendo las garantías de
comerciabilidad y adecuación a un propósito particular, o asume cualquier responsabilidad legal o responsabilidad
por la exactitud, integridad, actualidad o utilidad de cualquier material mostrado o distribuido a través de la
página web ${termsOfUse.siteName} o representa que su uso no infringiría derechos de propiedad privada.
${termsOfUse.siteHost?cap_first} renuncia a cualquier garantía con respecto a la información proporcionada. Si
usted confía en dicha información es a su propio riesgo. En ningún caso ${termsOfUse.siteHost} será responsable
ante usted por daños o pérdidas que resulten de o causados por el sitio web ${termsOfUse.siteName} o su
contenido.</p>
<h3>Renuncia de aprobación</h3>
<p>La referencia en este documento a cualquier producto comercial específico, proceso o servicio por nombre
comercial, marca, fabricante, o de otro modo, no constituye necesariamente ni implica un endoso o recomendación
por parte de ${termsOfUse.siteHost}. Los puntos de vista y opiniones de los autores expresadas en este documento
no representan ni reflejan necesariamente las de Cornell y no podrá ser utilizado para fines publicitarios o
endoso de productos.</p>
</section>

View file

@ -1,68 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that an account has been created. -->
<#assign subject = "Su cuenta ${siteName} ha sido creado." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
<strong>Enhorabuena!</strong>
</p>
<p>
Hemos creado la nueva cuenta en ${siteName}, asociada con ${userAccount.emailAddress}.
</p>
<p>
Si no has solicitado esta nueva cuenta puede ignorar este mensaje.
Esta solicitud caducará si no se hubiere pronunciado sobre durante 30 días.
</p>
<p>
Haga clic en el enlace de abajo para crear la contraseña de su cuenta usando nuestro servidor seguro.
</p>
<p>
<a href="${passwordLink}" title="password">${passwordLink}</a>
</p>
<p>
Si el enlace no funciona, puedes copiar y pegar el enlace directamente en la barra de direcciones de su navegador.
</p>
<p>
¡Gracias!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Enhorabuena!
Hemos creado la nueva cuenta en ${siteName},
asociada con ${userAccount.emailAddress}.
Si no has solicitado esta nueva cuenta puede ignorar este mensaje.
Esta solicitud caducará si no se hubiere pronunciado sobre durante 30 días.
Pega el siguiente enlace en la barra de direcciones de su navegador para
crear su contraseña para su nueva cuenta usando nuestro servidor seguro.
${passwordLink}
¡Gracias!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,43 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that an account has been created. -->
<#assign subject = "Su cuenta ${siteName} ha sido creada." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
<strong>¡Enhorabuena!</strong>
</p>
<p>
Hemos creado la nueva cuenta VIVO asociado con ${userAccount.emailAddress}.
</p>
<p>
¡Gracias!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
¡Enhorabuena!
Hemos creado la nueva cuenta VIVO asociado con
${userAccount.emailAddress}.
¡Gracias!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,38 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that the user has changed his email account. -->
<#assign subject = "Su cuenta de correo electrónico ${siteName} ha cambiado." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
Hola, ${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
Ha cambiado recientemente la dirección de correo electrónico asociada a
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
Gracias.
</p>
</body>
</html>
</#assign>
<#assign text>
Hola, ${userAccount.firstName} ${userAccount.lastName}
Ha cambiado recientemente la dirección de correo electrónico asociada a
${userAccount.firstName} ${userAccount.lastName}
Gracias.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,43 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that an account has been created for an externally-authenticated user. -->
<#assign subject = "Su cuenta ${siteName} ha sido creada." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
<strong>¡Enhorabuena!</strong>
</p>
<p>
Hemos creado la nueva cuenta VIVO asociado con ${userAccount.emailAddress}.
</p>
<p>
¡Gracias!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
¡Enhorabuena!
Hemos creado la nueva cuenta VIVO asociado con
${userAccount.emailAddress}.
¡Gracias!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,43 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that an password has been created. -->
<#assign subject = "El ${siteName} contraseña ha sido creado con éxito." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
<strong>Contraseña creado con éxito.</strong>
</p>
<p>
Su nueva contraseña asociada con ${userAccount.emailAddress} se ha creado.
</p>
<p>
Gracias.
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Contraseña creado con éxito.
Su nueva contraseña asociada con ${userAccount.emailAddress}
se ha creado.
Gracias.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,44 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation that a password has been reset. -->
<#assign subject = "El ${siteName} contraseña cambiada." />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<p>
<strong>Contraseña cambiada con éxito.</strong>
</p>
<p>
Su nueva contraseña asociada con ${userAccount.emailAddress} ha sido cambiado.
</p>
<p>
Gracias.
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Contraseña cambiada con éxito.
Su nueva contraseña asociada con ${userAccount.emailAddress}
ha sido cambiado.
Gracias.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -1,62 +0,0 @@
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
<#-- Confirmation email for user account password reset -->
<#assign subject = "${siteName} restablecer solicitud de contraseña" />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
Estimado ${userAccount.firstName} ${userAccount.lastName}:
</p>
<p>
Hemos recibido una solicitud para restablecer la contraseña de su cuenta ${siteName}
(${userAccount.emailAddress}).
</p>
<p>
Por favor, siga las siguientes instrucciones para proceder con su restablecimiento de contraseña.
</p>
<p>
Si no has solicitado esta nueva cuenta puede ignorar este mensaje.
Esta solicitud caducará si no se hubiere pronunciado en un plazo de 30 días.
</p>
<p>
Haga clic en el enlace de abajo o pegarlo en la barra de direcciones de su navegador para
restablecer su contraseña usando nuestro servidor seguro.
</p>
<p>${passwordLink}</p>
<p>¡Gracias!</p>
</body>
</html>
</#assign>
<#assign text>
Estimado ${userAccount.firstName} ${userAccount.lastName}:
Hemos recibido una solicitud para restablecer la contraseña de su cuenta ${siteName}
(${userAccount.emailAddress}).
Por favor, siga las siguientes instrucciones para proceder con su restablecimiento de contraseña.
Si no has solicitado esta nueva cuenta puede ignorar este mensaje.
Esta solicitud caducará si no se hubiere pronunciado en un plazo de 30 días.
Pega el siguiente enlace en la barra de direcciones de su navegador para
restablecer su contraseña usando nuestro servidor seguro.
${passwordLink}
¡Gracias!
</#assign>
<@email subject=subject html=html text=text />

File diff suppressed because it is too large Load diff