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:
parent
a16815dc61
commit
8b08a01559
89 changed files with 0 additions and 12534 deletions
|
@ -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
|
@ -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.
|
|
@ -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 "${build.properties.file}" 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 "${runtime.properties.file}" 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 "${vitro.home}" does not exist.">
|
||||
<condition>
|
||||
<not>
|
||||
<available file="${vitro.home}" />
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
|
||||
<fail message="The Vitro home directory "${vitro.home}" is not writable.">
|
||||
<condition>
|
||||
<not>
|
||||
<isfileselected file="${vitro.home}">
|
||||
<writable />
|
||||
</isfileselected>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
|
||||
<fail message="The Shindig token key file "${OpenSocial.tokenKeyFile}" 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>
|
|
@ -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> </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> </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>
|
|
@ -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 Mentor Development Program</a>
|
||||
<br /><br />
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div style="float:left;">
|
||||
<span class="mentor_message">
|
||||
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> — <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 </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> </td>
|
||||
<td><label class='textlabel'>Phone</label>
|
||||
<input id="edit_assistant_phone"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class='question'>
|
||||
<h4>Mentoring Narrative: <img src="images/hovertiptarget.png" border="0" onClick="document.getElementById('sample').style.display='block';">
|
||||
<span class="mentor_message"> 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">
|
||||
|
||||
<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;"> <b>·</b> </span>Career Mentor</span>
|
||||
<span id="mentor_as_co_mentor" style="display:none; padding-botom:3px;"><span style="font-size:18px;"> <b>·</b> </span>Co-Mentor</span>
|
||||
<span id="mentor_as_lead_research" style="display:none; padding-botom:3px;"><span style="font-size:18px;"> <b>·</b> </span>Lead Research / Scholarly Mentor</span>
|
||||
<span id="mentor_as_project_mentor" style="display:none; padding-botom:3px;"><span style="font-size:18px;"> <b>·</b> </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;"> <b>·</b> </span>Email (see above)</li>
|
||||
<li id="mentor_contact_phone" style="display:none; padding-botom:3px;"><span style="font-size:18px;"> <b>·</b> </span>Phone (see above)</li>
|
||||
<li id="mentor_contact_assistant" style="display:none; padding-botom:3px;"><span style="font-size:18px;"> <b>·</b> </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: </div>
|
||||
<div id="mentor_assistant_email" style="display:none; height:20px;">Email: </div>
|
||||
<div id="mentor_assistant_phone" style="display:none; height:20px;">Phone: </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>
|
|
@ -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 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"> 1. </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"> 2. </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> |
|
||||
<a href="javascript:gadgetEventTrack('export_email');copyEmailDivToClipboard();">Export email addresses only</a> |
|
||||
<a href="javascript:gadgetEventTrack('export_all_data');copyFullDivToClipboard();">Export all data</a> |
|
||||
<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> |
|
||||
</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> </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>
|
|
@ -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> <a href="javascript: goback()">Back</a>
|
||||
</form>
|
||||
<div id='rdf'></div>
|
||||
</div> ]]>
|
||||
</Content>
|
||||
</Module>
|
|
@ -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>
|
|
@ -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: </span><input type="text" name="username" style="display:inline;width:20em;">
|
||||
</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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
|
|
@ -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 ;
|
||||
|
||||
|
|
@ -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.
|
@ -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.
|
||||
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 "${build.properties.file}" 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 "${runtime.properties.file}" 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>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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>
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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>
|
|
@ -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("title", "Test Document 1");
|
||||
* newDoc.addField("id", "doc-1");
|
||||
* newDoc.addField("text", "Hello world!");
|
||||
* server.add(newDoc);
|
||||
* server.commit();
|
||||
*
|
||||
* // ** And now let's query for it
|
||||
*
|
||||
* params.set("q", "title:test");
|
||||
* QueryResponse qResp = server.query(params);
|
||||
*
|
||||
* SolrDocumentList docList = qResp.getResults();
|
||||
* System.out.println("Num docs: " + docList.getNumFound());
|
||||
* SolrDocument doc = docList.get(0);
|
||||
* System.out.println("Title: " + doc.getFirstValue("title").toString());
|
||||
* </pre>
|
||||
*/
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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> </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/> <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/> <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>";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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 "${build.properties.file}" 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>
|
|
@ -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 =
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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>
|
|
@ -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.
|
|
@ -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>
|
|
@ -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—información de texto, la publicación
|
||||
citas, enlaces e imágenes—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>
|
|
@ -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 />
|
|
@ -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 />
|
|
@ -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 />
|
|
@ -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 />
|
|
@ -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 />
|
|
@ -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 />
|
|
@ -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
Loading…
Add table
Reference in a new issue