Merge branch 'develop' of https://github.com/vivo-project/VIVO into develop

This commit is contained in:
Holly Mistlebauer 2014-06-26 14:53:21 -04:00
commit d0fb87c615
37 changed files with 86 additions and 682 deletions

1
.gitignore vendored
View file

@ -9,4 +9,3 @@
/ontology/public/catalog-v0001.xml
rdf/auth/firsttime/test-user-model.owl
utilities/rdbmigration/.work

View file

@ -134,14 +134,4 @@
</sync>
</target>
<!-- =================================
target: migrateConfigurationModels
================================= -->
<target name="migrateConfigurationModels" description="description">
<dirname property="nihvivobase.dir" file="${ant.file.nihvivo}" />
<property name="rdbmigration.dir" location="${nihvivobase.dir}/utilities/rdbmigration" />
<ant dir="${rdbmigration.dir}" target="all"></ant>
</target>
</project>

View file

@ -8,12 +8,12 @@ find these files in this directory:
Instructions for installing VIVO on your machine, including
a simple installation and several options.
Upgrade Instructions for VIVO release 1.6.pdf
Upgrade Instructions for VIVO release 1.7.pdf
Instructions for migrating a VIVO installation from release
1.5 to release 1.6
1.6 to release 1.7
If these files are not present, or to obtain the latest version of the
instructions, go to:
https://wiki.duraspace.org/display/VIVO/VIVO+Documentation
https://wiki.duraspace.org/display/VIVO/

View file

@ -12,7 +12,7 @@
PREFIX vitro: &lt;http://vitro.mannlib.cornell.edu/ns/vitro/0.7#&gt;
PREFIX vcard: &lt;http://www.w3.org/2006/vcard/ns#&gt;
SELECT DISTINCT <collated> ?subclass </collated>
SELECT DISTINCT ?subclass
?authorship
?author ?authorName
WHERE {
@ -21,13 +21,12 @@
OPTIONAL { ?authorship core:relates ?author .
?author a foaf:Agent .
?author rdfs:label ?authorName
<collated>
OPTIONAL { ?authorship core:relates ?author .
?author a foaf:Agent .
?author vitro:mostSpecificType ?subclass .
?subclass rdfs:subClassOf foaf:Agent
}
</collated>
}
OPTIONAL { ?authorship core:relates ?author .
?author a vcard:Kind .
@ -39,13 +38,12 @@
bind ( COALESCE(?middleName, "") As ?middleName1) .
bind ( COALESCE(?lastName, "") As ?lastName1) .
bind (concat(str(?lastName1 + ", "),str(?middleName1 + " "),str(?firstName1)) as ?authorName) .
<collated>
OPTIONAL { ?authorship core:relates ?author .
?author a vcard:Kind .
?author vitro:mostSpecificType ?subclass .
?subclass rdfs:subClassOf vcard:Kind
}
</collated>
}
<critical-data-required>
FILTER ( bound(?author) )

View file

@ -14,7 +14,7 @@
?subject ?property ?value
FILTER isLiteral(?value)
} ORDER BY ?object
} ORDER BY ?value
</query-select>
<query-construct>

View file

@ -17,8 +17,8 @@
<span class="hideThis">&nbsp;</span>
<script type="text/javascript" >
$('span.hideThis').parent().parent().addClass("hideThis");
if ( $('h3#hasResearcherRole').attr('class').length == 0 ) {
$('h3#hasResearcherRole').addClass('hiddenGrants');
if ( $('h3#RO_0000053-ResearcherRole').attr('class').length == 0 ) {
$('h3#RO_0000053-ResearcherRole').addClass('hiddenGrants');
}
$('span.hideThis').parent().remove();
</script>

View file

@ -13,7 +13,11 @@
next statement -->
<#macro showAuthorship statement>
<#if statement.author??>
<#if statement.subclass?? && statement.subclass?contains("vcard")>
${statement.authorName}
<#else>
<a href="${profileUrl(statement.uri("author"))}" title="${i18n().author_name}">${statement.authorName}</a>
</#if>
<#else>
<#-- This shouldn't happen, but we must provide for it -->
<a href="${profileUrl(statement.uri("authorship"))}" title="${i18n().missing_author}">${i18n().missing_author}</a>

View file

@ -581,6 +581,10 @@ var addAuthorForm = {
this.labelField.val(name);
}
// If user selected org via autocomplete, clear the org name field
if ( this.orgUriField.val() != '' ) {
this.orgName.val("");
}
},
@ -765,6 +769,7 @@ var addAuthorForm = {
if ( authType == "org" ) {
this.personSection.hide();
this.orgSection.show();
this.orgNameWrapper.show();
// person fields
this.personRadio.attr('checked', false); // needed for reset when cancel button is clicked
this.acSelector.removeClass("acSelector");

View file

@ -1,6 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var manageGrants = {
var manageHideShowStatus = {
/* *** Initial page setup *** */
@ -20,7 +20,7 @@ var manageGrants = {
// Initial page setup. Called only at page load.
initPage: function() {
this.initGrantData();
this.initItemData();
this.bindEventListeners();
@ -29,28 +29,28 @@ var manageGrants = {
// On page load, associate data with each list item. Then we don't
// have to keep retrieving data from or modifying the DOM as we manipulate the
// items.
initGrantData: function() {
$('.grantCheckbox').each(function(index) {
$(this).data(grantData[index]);
initItemData: function() {
$('.itemCheckbox').each(function(index) {
$(this).data(itemData[index]);
});
},
bindEventListeners: function() {
$('.grantCheckbox').click(function() {
manageGrants.processGrant(this);
$('.itemCheckbox').click(function() {
manageHideShowStatus.processItem(this);
//return false;
});
},
processGrant: function(grant) {
processItem: function(item) {
var add = "";
var retract = "";
var n3String = "<" + $(grant).data('roleUri') + "> <http://vivoweb.org/ontology/core#hideFromDisplay> \"true\" ." ;
var n3String = "<" + $(item).data('relatedUri') + "> <http://vivoweb.org/ontology/core#hideFromDisplay> \"true\" ." ;
if ( $(grant).is(':checked') ) {
if ( $(item).is(':checked') ) {
add = n3String;
}
else {
@ -58,22 +58,22 @@ var manageGrants = {
}
$.ajax({
url: manageGrants.processingUrl,
url: manageHideShowStatus.processingUrl,
type: 'POST',
data: {
additions: add,
retractions: retract
},
dataType: 'json',
context: grant, // context for callback
context: item, // context for callback
complete: function(request, status) {
if (status === 'success') {
window.status = manageGrants.grantSuccessfullyExcluded;
window.status = manageHideShowStatus.itemSuccessfullyExcluded;
} else {
alert(manageGrants.errorExcludingGrant);
$(grant).removeAttr('checked');
alert(manageHideShowStatus.errorExcludingItem);
$(item).removeAttr('checked');
}
}
});
@ -82,5 +82,5 @@ var manageGrants = {
};
$(document).ready(function() {
manageGrants.onLoad();
manageHideShowStatus.onLoad();
});

View file

@ -1,86 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var managePeople = {
/* *** Initial page setup *** */
onLoad: function() {
this.mixIn();
this.initPage();
},
mixIn: function() {
// Get the custom form data from the page
$.extend(this, customFormData);
$.extend(this, i18nStrings);
},
// Initial page setup. Called only at page load.
initPage: function() {
this.initPeopleData();
this.bindEventListeners();
},
// On page load, associate data with each list item. Then we don't
// have to keep retrieving data from or modifying the DOM as we manipulate the
// items.
initPeopleData: function() {
$('.pubCheckbox').each(function(index) {
$(this).data(peopleData[index]);
});
},
bindEventListeners: function() {
$('.pubCheckbox').click(function() {
managePeople.processPeople(this);
//return false;
});
},
processPeople: function(person) {
var add = "";
var retract = "";
var n3String = "<" + $(person).data('positionUri') + "> <http://vivoweb.org/ontology/core#hideFromDisplay> \"true\" ." ;
if ( $(person).is(':checked') ) {
add = n3String;
}
else {
retract = n3String;
}
$.ajax({
url: managePeople.processingUrl,
type: 'POST',
data: {
additions: add,
retractions: retract
},
dataType: 'json',
context: person, // context for callback
complete: function(request, status) {
if (status === 'success') {
window.status = managePeople.personSuccessfullyExcluded;
} else {
alert(managePeople.errorExcludingPerson);
$(person).removeAttr('checked');
}
}
});
},
};
$(document).ready(function() {
managePeople.onLoad();
});

View file

@ -1,86 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
var managePublications = {
/* *** Initial page setup *** */
onLoad: function() {
this.mixIn();
this.initPage();
},
mixIn: function() {
// Get the custom form data from the page
$.extend(this, customFormData);
$.extend(this, i18nStrings);
},
// Initial page setup. Called only at page load.
initPage: function() {
this.initPublicationData();
this.bindEventListeners();
},
// On page load, associate data with each list item. Then we don't
// have to keep retrieving data from or modifying the DOM as we manipulate the
// items.
initPublicationData: function() {
$('.pubCheckbox').each(function(index) {
$(this).data(publicationData[index]);
});
},
bindEventListeners: function() {
$('.pubCheckbox').click(function() {
managePublications.processPublication(this);
//return false;
});
},
processPublication: function(publication) {
var add = "";
var retract = "";
var n3String = "<" + $(publication).data('authorshipUri') + "> <http://vivoweb.org/ontology/core#hideFromDisplay> \"true\" ." ;
if ( $(publication).is(':checked') ) {
add = n3String;
}
else {
retract = n3String;
}
$.ajax({
url: managePublications.processingUrl,
type: 'POST',
data: {
additions: add,
retractions: retract
},
dataType: 'json',
context: publication, // context for callback
complete: function(request, status) {
if (status === 'success') {
window.status = managePublications.publicationSuccessfullyExcluded;
} else {
alert(managePublications.errorExcludingPublication);
$(publication).removeAttr('checked');
}
}
});
},
};
$(document).ready(function() {
managePublications.onLoad();
});

View file

@ -13,7 +13,7 @@
<p style="margin-left:25px;margin-bottom:12px">
${i18n().check_grants_to_exclude}
<script type="text/javascript">
var grantData = [];
var itemData = [];
</script>
</p>
<@lvf.unsupportedBrowser urls.base />
@ -25,11 +25,11 @@ ${i18n().check_grants_to_exclude}
<ul >
<#list grantList as grant>
<li>
<input type="checkbox" class="grantCheckbox" <#if grant.hideThis??>checked</#if> />${grant.label!grant.activity!}
<input type="checkbox" class="itemCheckbox" <#if grant.hideThis??>checked</#if> />${grant.label!grant.activity!}
</li>
<script type="text/javascript">
grantData.push({
"roleUri": "${grant.role!}"
itemData.push({
"relatedUri": "${grant.role!}"
});
</script>
@ -48,8 +48,8 @@ var customFormData = {
processingUrl: '${urls.base}/edit/primitiveRdfEdit'
};
var i18nStrings = {
grantSuccessfullyExcluded: '${i18n().grant_successfully_excluded}',
errorExcludingGrant: '${i18n().error_excluding_grant}'
itemSuccessfullyExcluded: '${i18n().grant_successfully_excluded}',
errorExcludingItem: '${i18n().error_excluding_grant}'
};
</script>
@ -59,5 +59,5 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarke
${scripts.add('<script type="text/javascript" src="${urls.base}/js/utils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/manageGrantsForIndividual.js"></script>')}
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/manageHideShowStatus.js"></script>')}

View file

@ -7,7 +7,7 @@
<p style="margin-left:25px;margin-bottom:12px">
${i18n().check_people_to_exclude}
<script type="text/javascript">
var peopleData = [];
var itemData = [];
</script>
</p>
@ -21,11 +21,11 @@ ${i18n().check_people_to_exclude}
<ul >
<#list peeps as person>
<li>
<input type="checkbox" class="pubCheckbox" <#if person.hideThis??>checked</#if> />${person.name}
<input type="checkbox" class="itemCheckbox" <#if person.hideThis??>checked</#if> />${person.name}
</li>
<script type="text/javascript">
peopleData.push({
"positionUri": "${person.position}"
itemData.push({
"relatedUri": "${person.position}"
});
</script>
@ -44,8 +44,8 @@ var customFormData = {
processingUrl: '${urls.base}/edit/primitiveRdfEdit'
};
var i18nStrings = {
personSuccessfullyExcluded: '${i18n().person_successfully_excluded}',
errorExcludingPerson: '${i18n().error_excluding_person}'
itemSuccessfullyExcluded: '${i18n().person_successfully_excluded}',
errorExcludingItem: '${i18n().error_excluding_person}'
};
</script>
@ -55,5 +55,5 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarke
${scripts.add('<script type="text/javascript" src="${urls.base}/js/utils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/managePeopleForOrganization.js"></script>')}
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/manageHideShowStatus.js"></script>')}

View file

@ -13,7 +13,7 @@
<p style="margin-left:25px;margin-bottom:12px">
${i18n().check_pubs_to_exclude}
<script type="text/javascript">
var publicationData = [];
var itemData = [];
</script>
</p>
@ -37,12 +37,12 @@ ${i18n().check_pubs_to_exclude}
<ul >
<#list pubs as pub>
<li>
<input type="checkbox" class="pubCheckbox" <#if pub.hideThis??>checked</#if> />
<input type="checkbox" class="itemCheckbox" <#if pub.hideThis??>checked</#if> />
<#if pub.title?has_content>${pub.title!}<#else>${i18n().title_not_found}</#if>
</li>
<script type="text/javascript">
publicationData.push({
"authorshipUri": "${pub.authorship}"
itemData.push({
"relatedUri": "${pub.authorship}"
});
</script>
@ -61,8 +61,8 @@ var customFormData = {
processingUrl: '${urls.base}/edit/primitiveRdfEdit'
};
var i18nStrings = {
publicationSuccessfullyExcluded: '${i18n().publication_successfully_excluded}',
errorExcludingPublication: '${i18n().error_excluding_publication}'
itemSuccessfullyExcluded: '${i18n().publication_successfully_excluded}',
errorExcludingItem: '${i18n().error_excluding_publication}'
};
</script>
@ -72,5 +72,5 @@ ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/templates/freemarke
${scripts.add('<script type="text/javascript" src="${urls.base}/js/utils.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
'<script type="text/javascript" src="${urls.base}/js/customFormUtils.js"></script>',
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/managePublicationsForIndividual.js"></script>')}
'<script type="text/javascript" src="${urls.base}/templates/freemarker/edit/forms/js/manageHideShowStatus.js"></script>')}

View file

@ -53,7 +53,7 @@
<div id="error-notification" class="ui-state-error" style="padding:10px; -moz-box-shadow:0 0 6px #980000; -webkit-box-shadow:0 0 6px #980000; box-shadow:0 0 6px #980000;">
<a class="ui-notify-close" href="#" title="${i18n().error_notification}"><span class="ui-icon ui-icon-close" style="float:right"></span></a>
<span style="float:left; margin:0 5px 0 0;" class="ui-icon ui-icon-alert"></span>
<h1>&#035;{title}</h1>
<h1>&#035;{title!}</h1>
<p>&#035;{text}</p>
<p style="text-align:center"><a class="ui-notify-close" href="#">${i18n().close_me}</a></p>
</div>
@ -61,7 +61,7 @@
<div id="warning-notification" class="ui-state-highlight ui-corner-all" >
<a class="ui-notify-close ui-notify-cross" href="#" title="${i18n().error_notification}">x</a>
<span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-info"></span>
<h1>&#035;{title}</h1>
<h1>&#035;{title!}</h1>
<p>&#035;{text}</p>
</div>

View file

@ -27,7 +27,7 @@ corresponding changes in the included Templates. -->
<div id="error-notification" class="ui-state-error" style="padding:10px; -moz-box-shadow:0 0 6px #980000; -webkit-box-shadow:0 0 6px #980000; box-shadow:0 0 6px #980000;">
<a class="ui-notify-close" href="#" title="${i18n().error_notification}"><span class="ui-icon ui-icon-close" style="float:right"></span></a>
<span style="float:left; margin:0 5px 0 0;" class="ui-icon ui-icon-alert"></span>
<h1>&#035;{title}</h1>
<h1>&#035;{title!}</h1>
<p>&#035;{text}</p>
<p style="text-align:center"><a class="ui-notify-close" href="#">${i18n().close_me}</a></p>
</div>
@ -35,7 +35,7 @@ corresponding changes in the included Templates. -->
<div id="warning-notification" class="ui-state-highlight ui-corner-all" >
<a class="ui-notify-close ui-notify-cross" href="#" title="${i18n().error_notification}">x</a>
<span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-info"></span>
<h1>&#035;{title}</h1>
<h1>&#035;{title!}</h1>
<p>&#035;{text}</p>
</div>
</div>

View file

@ -28,21 +28,16 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import edu.cornell.mannlib.semservices.util.MetadataNamespaceContext;
/**
* Convenience Class to parse XML strings to DOM Document for XML contents
* retrieval.
@ -117,14 +112,16 @@ public class XMLUtils {
* @param doc
* @throws IOException
*/
@SuppressWarnings("deprecation")
public static void serializeDoc(Document doc) throws IOException {
XMLSerializer serializer = new XMLSerializer();
org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer();
serializer.setOutputByteStream(System.out);
serializer.serialize(doc);
}
@SuppressWarnings("deprecation")
public static String serializeDoctoString(Document doc) throws IOException {
XMLSerializer serializer = new XMLSerializer();
org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
serializer.setOutputByteStream(bout);

View file

@ -72,8 +72,11 @@ public class ManagePeopleForOrganizationController extends FreemarkerHttpServlet
+ " OPTIONAL { ?position core:relates ?person . "
+ " ?person a foaf:Person . \n"
+ " ?person rdfs:label ?label } \n"
+ " OPTIONAL { ?position vitro:mostSpecificType ?subclass } \n"
+ " OPTIONAL { ?position vitro:mostSpecificType ?subclass . \n"
+ " OPTIONAL { ?subclass vitro:displayRankAnnot ?displayRank } \n"
+ " } \n "
+ " OPTIONAL { ?position core:hideFromDisplay ?hideThis } \n "
+ " FILTER ( ?displayRank < 500 )"
+ "} ORDER BY ?subclass ?name";
HashMap<String, List<Map<String,String>>> getPeople(String subjectUri, VitroRequest vreq) {

View file

@ -2,7 +2,7 @@
<#-- Template for the body of the GadgetDetails page -->
<div class="pageTitle" id="gadgets-title"><h2>${title}</h2></div>
<div class="pageTitle" id="gadgets-title"><h2>${title!}</h2></div>
<#-- VIVO OpenSocial Extension by UCSF -->
<#if openSocial??>

View file

@ -11,7 +11,7 @@ th {
}
</style>
<div class="pageTitle" id="gadgets-title"><h2>${title}</h2></div>
<div class="pageTitle" id="gadgets-title"><h2>${title!}</h2></div>
<#-- VIVO OpenSocial Extension by UCSF -->
<#if openSocial??>

View file

@ -4,7 +4,7 @@
<!-- Google Chrome Frame open source plug-in brings Google Chrome's open web technologies and speedy JavaScript engine to Internet Explorer-->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>${title}</title>
<title>${siteName!}</title>
<#-- VIVO OpenSocial Extension by UCSF -->
<#if openSocial??>

View file

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

View file

@ -1,303 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
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.Properties;
import com.hp.hpl.jena.db.DBConnection;
import com.hp.hpl.jena.db.GraphRDB;
import com.hp.hpl.jena.db.IDBConnection;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.sparql.core.DatasetGraph;
import com.hp.hpl.jena.tdb.TDBFactory;
/**
* TODO
*/
public class RdbMigrator {
private static final String TABLE_RDB = "jena_graph";
private static final String TABLE_MIGRATED = "vivo_rdb_migrated";
private final String vivoHomeDir;
private final String jdbcUrl;
private final String username;
private final String password;
private File targetDir;
private boolean alreadyMigrated;
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;
confirmTargetDirectory();
if (doesTdbExist()) {
askContinueOverTdb();
}
testDbConnection();
checkThatRdbExists();
if (isAlreadyMigrated()) {
askMigrateAgain();
}
askApprovalForMigrationPlan();
}
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, "tdbmodels");
}
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 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 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 askApprovalForMigrationPlan() throws SQLException,
UserDeclinedException, IOException {
int modelCount = 0;
int tripleCount = 0;
try (Connection conn = getSqlConnection()) {
IDBConnection rdb = null;
try {
rdb = getRdbConnection(conn);
for (String modelName : rdb.getAllModelNames().toList()) {
modelCount++;
Graph graph = new GraphRDB(
rdb,
modelName,
null,
GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING,
false);
tripleCount += graph.size();
graph.close();
}
} finally {
if (rdb != null) {
rdb.close();
}
}
}
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);
}
public void migrate() throws SQLException {
copyData();
writeMigratedRecord();
}
private void copyData() throws SQLException {
try (Connection conn = getSqlConnection()) {
IDBConnection rdbConnection = null;
try {
rdbConnection = getRdbConnection(conn);
Dataset tdbDataset = TDBFactory.createDataset(targetDir
.getAbsolutePath());
copyGraphs(rdbConnection, tdbDataset);
} finally {
if (rdbConnection != null) {
rdbConnection.close();
}
}
}
}
@SuppressWarnings("deprecation")
private void copyGraphs(IDBConnection rdbConnection, Dataset tdbDataset) {
DatasetGraph tdbDsGraph = tdbDataset.asDatasetGraph();
for (String modelName : rdbConnection.getAllModelNames().toList()) {
Graph graph = null;
try {
graph = new GraphRDB(rdbConnection, modelName, null,
GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING,
false);
tdbDsGraph.addGraph(Node.createURI(modelName), graph);
System.out
.println(String.format(" copied %4d triples from %s",
graph.size(), modelName));
} finally {
if (graph != null) {
graph.close();
}
}
}
}
private void writeMigratedRecord() 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 void quit(String message) {
throw new IllegalArgumentException(message);
}
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);
}
}
private Connection getSqlConnection() throws SQLException {
Properties connectionProps;
connectionProps = new Properties();
connectionProps.put("user", username);
connectionProps.put("password", password);
return DriverManager.getConnection(jdbcUrl, connectionProps);
}
private IDBConnection getRdbConnection(Connection sqlConnection) {
return new DBConnection(sqlConnection, "MySQL");
}
public static void main(String[] args) throws SQLException {
if (args.length != 4) {
System.out.println("Usage: RdbMigrator vivoHomeDir, jdbcUrl, "
+ "username, password");
}
try {
RdbMigrator rdbm = new RdbMigrator(args[0], args[1], args[2], args[3]);
rdbm.migrate();
} catch (IllegalArgumentException | UserDeclinedException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,15 @@
=begin
--------------------------------------------------------------------------------
Create PDF versions of the Installation Instructions and the Upgrade Guide,
from the VIVONEXT Wiki space.
Store them in the docs directory.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
=end
puts "-------------------------------------------------------------------"
puts " Not automated yet. Get Installation and Upgrade PDFs and put "
puts " them into the /doc directory. "
puts "-------------------------------------------------------------------"