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

This commit is contained in:
hudajkhan 2013-01-17 11:55:12 -05:00
commit 1ba6204815
34 changed files with 1625 additions and 658 deletions

2
.gitignore vendored
View file

@ -4,5 +4,7 @@
/.settings
/bin/
/webapp/config/deploy.properties
/webapp/config/build.properties
/webapp/config/runtime.properties
/webapp/config/debug.log4j.properties
.build

View file

@ -3,7 +3,7 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Vitro Version 1.4 Installation Guide</title>
<title>Vitro Version 1.5.1 Installation Guide</title>
<link rel="stylesheet" href="./css/doc.css" media="screen">
</head>
<body>
@ -12,9 +12,9 @@
</div>
<!-- Start of content -->
<div id="wrapper-content" role="main">
<h1>Vitro Version 1.4 Installation Guide</h1>
<h1>Vitro Version 1.5. Installation Guide</h1>
<small>
November 15, 2011
January 6, 2013
</small>
<toc>
<ul>
@ -22,7 +22,7 @@
<a href="#introduction">Introduction to the Vitro installation</a>
</li>
<li>
<a href="#installation">Installation process for Version 1.4</a>
<a href="#installation">Installation process for Version 1.5.1</a>
</li>
</ul>
</toc>
@ -38,8 +38,13 @@
If you are upgrading a previous installation of Vitro,
you may need to adjust your procedure accordingly.
</p>
<br>
<hr><!-- Page break --><!-- Introduction to the Vitro installation --><h2 id="introduction">Introduction to the Vitro installation</h2>
<p>
Other servlet containers: If you want to use a servlet container
other than Tomcat, please consult <a href="other_servlet_containers.html">
instructions for other servlet containers</a> in this directory.
</p>
<hr><h2 id="introduction">Introduction to the Vitro installation</h2>
<p>
Before beginning the installation,
@ -54,8 +59,8 @@
<p>
This is created when you checkout the Vitro source code
(see <a href="#checkout_code">installation step III</a>, below).
This is where you will create your deploy.properties file
(see <a href="#deploy_properties">installation step V</a>, below),
This is where you will create your build.properties file
(see <a href="#build_properties">installation step IV</a>, below),
and where you will make any modifications to the Vitro
theme or code. You can create this wherever you choose.
</p>
@ -68,18 +73,20 @@
but you wont need to look at it or change it. If you need to change
Vitro, make the changes in the distribution directory, and run the build
script again. Tell the build script where to find Tomcat by setting <code>tomcat.home</code>
in the deploy.properties file (see <a href="#deploy_properties">installation step V</a>,
in the build.properties file (see <a href="#build_properties">installation step IV</a>,
below).
</p>
<h4>The Vitro home directory</h4>
<p>
Vitro will use this area to store some of the data it uses. Uploaded
image files are stored here, and the search index is stored here also.
This directory contains the runtime configuration properties for Vitro.
Vitro will also use this area to store some of the data it uses. Uploaded
image files are stored here, and the Solr home directory is stored here also.
You can create this wherever you choose. Tell Vitro where to find the
home directory by setting <code>vitro.home.directory</code>
in the
deploy.properties file (see <a href="#deploy_properties">installation step V</a>,
below). You must create this directory before starting Vitro, and you
home directory by setting <code>vitro.home</code> in the
build.properties file (see <a href="#build_properties">installation step IV</a>,
below). You must create this directory before starting Vitro,
you must create the <code>runtime.properties</code> file in this directory
(see <a href="#runtime_properties">Step V</a>, below), and you
must ensure that Tomcat has permission to read and write to this
directory when it runs.
</p>
@ -176,7 +183,10 @@
<a href="#checkout_code">Check out the Vitro Source Code</a>
</li>
<li>
<a href="#deploy_properties">Specify deployment properties</a>
<a href="#build_properties">Specify build properties</a>
</li>
<li>
<a href="#runtime_properties">Specify runtime properties</a>
</li>
<li>
<a href="#deploy">Compile and deploy</a>
@ -275,12 +285,91 @@
If you want the very latest Vitro source, you can use subversion to check it out from SourceForge:
<pre> svn checkout svn://svn.code.sf.net/p/vivo/vitro/code/trunk</code> <em>[Vitro_distribution_dir]</em></pre>
</p>
<h3 id="deploy_properties">IV. Specify deployment properties </h3>
<h3 id="build_properties">IV. Specify build properties </h3>
<p>
In the <code>webapp/config</code> directory of the Vitro distribution,
copy the file <code>example.deploy.properties</code>
to a file named simply <code>deploy.properties</code>. This file sets
several properties used in compilation and deployment.
copy the file <code>example.build.properties</code>
to a file named simply <code>build.properties</code>.
Edit the file to suit your installation, as described in the following table.
</p>
<p>
These properties are used in compilation and deployment.
They will be incorporated into Vitro when it is compiled in
<a href="#deploy">Step VI</a>. If you want to change these properties at
a later date, you will need to stop Tomcat, repeat <a href="#deploy">Step VI</a>,
and restart Tomcat.
</p>
<p>
<em>Windows:</em>
For those installing on Windows operating
system, include the windows drive and use the forward slash "/" and not
the back slash "\" in the directory locations, e.g. <code>c:/tomcat</code>.
</p>
<table border='1' bordercolor="#CCCCCC" cellspacing="5">
<tbody>
<tr>
<td colspan="2">
Directory where tomcat is installed.
</td>
</tr>
<tr class="odd_row">
<td>
tomcat.home
</td>
<td>
/usr/local/tomcat
</td>
</tr>
<tr>
<td colspan="2">
Name of your Vitro application.
</td>
</tr>
<tr class="odd_row">
<td>
webapp.name
</td>
<td>
vitro
</td>
</tr>
<tr>
<td colspan="2">
Directory where the Vitro application will store
the data that it creates. This includes uploaded files (usually images)
and the Solr search index. Be sure this directory exists and is
writable by the user who the Tomcat service is running as.
</td>
</tr>
<tr class="odd_row">
<td>
vitro.home
</td>
<td>
/usr/local/vitro/home
</td>
</tr>
</tr>
</tbody>
</table>
<h3 id="runtime_properties">V. Specify runtime properties </h3>
<p>
In <a href="#build_properties">Step IV</a>, you defined the location of the Vitro home directory,
by specifying <code>vitro.home</code> in the <code>build.properties</code> file.
Create that directory now.
</p>
<p>
In the <code>webapp/config</code> subdirectory of the Vitro distribution, you will find a file called
<code>example.runtime.properties</code>. Copy this to the Vitro home directory you have created,
renaming the copy to <code>runtime.properties</code>.
Edit the file to suit your installation, as described in the following table.
</p>
<p>
These properties are loaded when Vitro starts up. If you want to change these
properties at a later date, you will need to restart Tomcat for them to take
effect. You will not need to repeat <a href="#deploy">Step VI</a>.
</p>
<p>
<em>Windows:</em>
@ -329,32 +418,6 @@
http://vitro.mydomain.edu/individual/
</td>
</tr>
<tr>
<td colspan="2">
Directory where tomcat is installed.
</td>
</tr>
<tr class="odd_row">
<td>
tomcat.home
</td>
<td>
/usr/local/tomcat
</td>
</tr>
<tr>
<td colspan="2">
Name of your Vitro application.
</td>
</tr>
<tr class="odd_row">
<td>
webapp.name
</td>
<td>
vitro
</td>
</tr>
<tr>
<td colspan="2">
URL of Solr context used in local Vitro search.
@ -372,53 +435,6 @@
http://localhost:8080/vitrosolr
</td>
</tr>
<tr>
<td colspan="2">
Restricts access to the Solr search platform.
The value is a regular expression. When a request is
made to Solr, the IP address of the requestor must the expression,
or the request will be rejected.
<br>
Examples:<code>
<ul>
<li>
vitro.local.solr.ipaddress.mask = 127\.0\.0\.1
</li>
<li>
vitro.local.solr.ipaddress.mask =
127\.0\.0\.1|0:0:0:0:0:0:0:1
</li>
<li>
vitro.local.solr.ipaddress.mask = 169.254.*
</li>
</ul>
</code>
</td>
</tr>
<tr class="odd_row">
<td>
vitro.local.solr.ipaddress.mask
</td>
<td>
127\.0\.0\.1|[0:]+:1
</td>
</tr>
<tr>
<td colspan="2">
Directory where the Vitro application will store
the data that it creates. This includes uploaded files (usually images)
and the Solr search index. Be sure this directory exists and is
writable by the user who the Tomcat service is running as.
</td>
</tr>
<tr class="odd_row">
<td>
vitro.home.directory
</td>
<td>
/usr/local/vitro/data
</td>
</tr>
<tr>
<td colspan="2">
Specify an SMTP host that the application will
@ -641,7 +657,7 @@
</tr>
</tbody>
</table>
<h3 id="deploy">V. Compile and deploy</h3>
<h3 id="deploy">VI. Compile and deploy</h3>
<p>
At the command line, change to the <code>webapp</code> directory inside the Vitro distribution
directory. Then type:
@ -650,7 +666,7 @@
<p>
to build Vitro and deploy to Tomcat's webapps directory.
</p>
<h3 id="tomcat_settings">VI. Configure Tomcat</h3>
<h3 id="tomcat_settings">VII. Configure Tomcat</h3>
<h4>Set JVM parameters</h4>
<p>
Vitro may require more memory than that allocated to Tomcat by
@ -686,7 +702,7 @@
accepting percent-encoded UTF-8.
</p>
<p>
Edit Tomcat's conf/server.xml and add the following attribute to each of the
Edit Tomcat's <code>conf/server.xml</code> and add the following attribute to each of the
Connector elements: URIEncoding="UTF-8".
</p>
<pre>
@ -699,6 +715,9 @@
&lt;/Server&gt;
</pre>
<p>
Note: some versions of Tomcat already include this attribute as the default.
</p>
<h4>Take care when creating Context elements</h4>
<p>
Each of the webapps in the Vitro distribution (Vitro and Solr) includes a "context fragment" file,
@ -710,22 +729,35 @@
deployment parameters from the overridden context fragment.
</p>
<p>
See <a href="#tomcat_connector">Section X</a> below,
See <a href="#tomcat_connector">Section XI</a> below,
for an example of overriding the Vitro context fragment.
</p>
<h3 id="start_tomcat">VII. Start Tomcat </h3>
<h3 id="start_tomcat">VIII. Start Tomcat </h3>
<p>
Most Tomcat installations can be started by running <code>startup.sh</code>
or <code>startup.bat</code>
in Tomcat's bin directory. Point your
browser to "http://localhost:8080/vitro/" to test the application. If
Tomcat does not start up, or the Vitro application is not visible, check
the files in Tomcat's logs directory. Error messages are commonly found
browser to "http://localhost:8080/vitro/" to test the application.
</p>
<p>
On start up Vitro will run some diagnostic tests. If a
problem is detected, the normal Vitro pages will redirect
to a startup status page describing the problem. You
can stop tomcat, attempt to fix the problem and
proceeded from <a href="#deploy">Step VI</a>. The
startup status page may offer a continue link which
will allow you to use VIVO in spite of the problems.
</p>
<p>
If Tomcat does not start up, or the Vitro application is not visible, check
the files in Tomcat's <code>logs</code> directory. Error messages are commonly found
in <code>catalina.out</code>
or <code>localhost.log</code>
</p>
<h3 id="add_rdf">VIII. Log in and add RDF data </h3>
</p>
<h3 id="add_rdf">IX. Log in and add RDF data </h3>
<p>
If the startup was successful, you will see a welcome message
informing you that you have successfully installed Vitro. Click the "Log
@ -759,7 +791,7 @@
the page will show a simple index of the knowledge base.
</p>
<h3 id="contact_email">IX. Set the Contact Email Address (if using
<h3 id="contact_email">X. Set the Contact Email Address (if using
"Contact Us" form)</h3>
<p>
If you have configured your application to use the "Contact Us"
@ -781,7 +813,7 @@
provide an email address in this step, your users will receive a java
error in the interface.
</p>
<h3 id="tomcat_connector">X. Set up Apache Tomcat Connector </h3>
<h3 id="tomcat_connector">XI. Set up Apache Tomcat Connector </h3>
<p>
It is recommended that a Tomcat Connector such as mod_jk be used to
ensure that the site address does not include the port number (e.g.
@ -832,16 +864,11 @@
cookies="true" &gt;
&lt;Manager pathname="" /&gt;
&lt;Environment type="java.lang.String" override="false"
name="path.configuration"
value="deploy.properties"
/&gt;
&lt;/Context&gt;
...
</pre>
<h3 id="external_auth">XI. Using an External Authentication System
<h3 id="external_auth">XII. Using an External Authentication System
with Vitro </h3>
<p>
</p>
@ -878,7 +905,7 @@
<h4>Configuring Vitro</h4>
<p>
To enable external authentication, Vitro requires three values in
the <code>deploy.properties</code>
the <code>runtime.properties</code>
file.
</p>
<ul>
@ -893,7 +920,7 @@
</p>
<p>
You need to tell Vitro the name of that HTTP header. Insert a
line like this in the deploy.properties file:
line like this in the runtime.properties file:
</p>
<pre>externalAuth.netIdHeaderName = [the header name]</pre>
<p>
@ -907,7 +934,7 @@
the Vitro login form. You need to tell Vitro what text should appear in
that button.
<p>
Put a line like this in the deploy.properties file:
Put a line like this in the runtime.properties file:
externalAuth.buttonText = [the text for your login button] For example:
</p>
<pre>externalAuth.buttonText = Log in using BearCat Shibboleth</pre>
@ -924,7 +951,7 @@
data model for a person with a property that matches the Users network
ID (the value of the property must be either a String literal or an
untyped literal). You need to tell Vitro what property should be used
for matching. Insert a line like this in the deploy.properties file:
for matching. Insert a line like this in the runtime.properties file:
</p>
<pre>selfEditing.idMatchingProperty = [the URI of the property]</pre>
<p>
@ -933,40 +960,38 @@
<pre>selfEditing.idMatchingProperty = http://vitro.mydomain.edu/ns#networkId</pre>
</li>
</ul>
<h3 id="installation_check">XII. Was the installation successful? </h3>
<h3 id="installation_check">XIII. Was the installation successful? </h3>
<p>
If you have completed the previous steps, you have good indications
that the installation was successful.
</p>
<ul>
<li>
Step VII showed that Tomcat recognized the webapp, and that the
Step VIII showed that Tomcat recognized the webapp, and that the
webapp was able to present the initial page.
</li>
<li>
Step VIII verified that you can log in to the administrator
Step IX verified that you can log in to the administrator
account.
</li>
</ul>
<p>
Step VII also shows that the Vitro self-tests ran successfully.
Step VIII also shows that the Vitro self-tests ran successfully.
When Tomcat starts the Vitro webapp, it runs several tests.
If any of these tests produce warnings or error message,
you would see them instead of the Vitro home page.
</p>
<p>
Among other things, the self-tests check
</p>
<ul>
<li>The Vitro home directory exists and Vitro can write to it.</li>
<li>Vitro can connect to the database.</li>
<li>Vitro can connect to the Solr search application.</li>
</ul>
<p>
If you saw the Vitro home page in Step VII, you know that your installation passed all of these tests.
</p>
<h3 id="termsofuse">XIII. Review the Vitro Terms of Use</h3>
<h3 id="termsofuse">XIV. Review the Vitro Terms of Use</h3>
<p>
Vitro comes with a "Terms of Use" statement linked from the footer.
The "Site Name" you assign in the "Site Information" form under the <strong>Site Admin</strong>
@ -992,7 +1017,7 @@
<div id="footer" role="contentinfo">
<p class="copyright">
<small>
©2011 All Rights Reserved
©2013 All Rights Reserved
</small>
</p>
</div>

View file

@ -30,40 +30,53 @@ deploy - Configure the application and deploy directly into the Tomcat webapps
target: properties
- - - - - - - - - - - - - - - - - -->
<target name="properties">
<property name="deploy.properties.file" location="../webapp/config/deploy.properties" />
<property name="build.properties.file" location="../webapp/config/build.properties" />
<fail message="You must create a &quot;${deploy.properties.file}&quot; file.">
<fail message="You must create a &quot;${build.properties.file}&quot; file.">
<condition>
<not>
<available file="${deploy.properties.file}" />
<available file="${build.properties.file}" />
</not>
</condition>
</fail>
<property file="${deploy.properties.file}" />
<property file="${build.properties.file}" />
<fail unless="tomcat.home" message="${deploy.properties.file} must contain a value for tomcat.home" />
<fail unless="vitro.home.directory" message="${deploy.properties.file} must contain a value for vitro.home.directory" />
<fail unless="VitroConnection.DataSource.url" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.password" />
<fail unless="VitroConnection.DataSource.driver" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.driver" />
<fail unless="OpenSocial.shindigURL" message="${deploy.properties.file} must contain a value for OpenSocial.shindigURL" />
<fail unless="OpenSocial.tokenService" message="${deploy.properties.file} must contain a value for OpenSocial.tokenService" />
<fail unless="OpenSocial.tokenKeyFile" message="${deploy.properties.file} must contain a value for OpenSocial.tokenKeyFile" />
<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 message="The vitro.home.directory &quot;${vitro.home.directory}&quot; does not exist.">
<property name="runtime.properties.file" location="${vitro.home}/runtime.properties" />
<fail message="The runtime properties file &quot;${runtime.properties.file}&quot; does not exist.">
<condition>
<not>
<available file="${vitro.home.directory}" />
<available file="${runtime.properties.file}" />
</not>
</condition>
</fail>
<fail message="The vitro.home.directory &quot;${vitro.home.directory}&quot; is not writable.">
<property file="${runtime.properties.file}" />
<fail unless="VitroConnection.DataSource.url" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.password" />
<fail unless="VitroConnection.DataSource.driver" message="${runtime.properties.file} must contain a value for VitroConnection.DataSource.driver" />
<fail unless="OpenSocial.shindigURL" message="${runtime.properties.file} must contain a value for OpenSocial.shindigURL" />
<fail unless="OpenSocial.tokenService" message="${runtime.properties.file} must contain a value for OpenSocial.tokenService" />
<fail unless="OpenSocial.tokenKeyFile" message="${runtime.properties.file} must contain a value for OpenSocial.tokenKeyFile" />
<fail message="The Vitro home directory &quot;${vitro.home}&quot; does not exist.">
<condition>
<not>
<isfileselected file="${vitro.home.directory}">
<available file="${vitro.home}" />
</not>
</condition>
</fail>
<fail message="The Vitro home directory &quot;${vitro.home}&quot; is not writable.">
<condition>
<not>
<isfileselected file="${vitro.home}">
<writable />
</isfileselected>
</not>
@ -83,7 +96,7 @@ deploy - Configure the application and deploy directly into the Tomcat webapps
<property name="build.shindig.dir" location="${build.dir}/shindig" />
<!-- deploy directories -->
<property name="shindig.home.dir" location="${vitro.home.directory}/shindig" />
<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" />
@ -145,5 +158,4 @@ deploy - Configure the application and deploy directly into the Tomcat webapps
<copy file="${shindig.war.original.file}" tofile="${shindig.war.deployed.file}" overwrite="true" />
</target>
</project>

Binary file not shown.

BIN
solr/apache-solr-3.6.2.war Normal file

Binary file not shown.

View file

@ -1,11 +1,4 @@
<Context crossContext="true" override="true">
<!-- For security, restrict access to clients on this machine
for IPv4 requests, localhost is 127.0.0.1
for IPv6 requests, localhost is 0:0:0:0:0:0:0:1 -->
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="${vitro.local.solr.ipaddress.mask}"/>
<Environment
type="java.lang.String"
name="solr/home"

View file

@ -10,216 +10,226 @@
<project name="vitroCore" default="describe">
<!-- - - - - - - - - - - - - - - - - -
properties
- - - - - - - - - - - - - - - - -->
<dirname property="corebase.dir" file="${ant.file.vitroCore}" />
<!-- 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="deploy.properties.file" location="config/deploy.properties" />
<property name="utilities.base.dir" location="${corebase.dir}/../utilities/buildutils" />
<property name="utilities.source.dir" location="${utilities.base.dir}/src" />
<property name="utilities.lib.dir" location="${utilities.base.dir}/lib" />
<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="war.dir" location="${build.dir}/war" />
<property name="war.webinf.dir" location="${war.dir}/WEB-INF" />
<property name="war.classes.dir" location="${war.webinf.dir}/classes" />
<property name="war.resources.dir" location="${war.webinf.dir}/resources" />
<property name="revisionInfo.build.file" location="${war.resources.dir}/revisionInfo.txt" />
<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="test.classes.dir" location="${build.dir}/testClasses" />
<property name="utility.classes.dir" location="${build.dir}/utilityClasses" />
<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="javac.deprecation" value="true" />
<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" />
<!-- - - - - - - - - - - - - - - - - -
paths: for compiling and running
target: buildProperties
- - - - - - - - - - - - - - - - - -->
<path id="compile.classpath">
<fileset dir="${appbase.dir}/lib" includes="*.jar" />
</path>
<target name="buildProperties">
<fail message="You must create a &quot;${build.properties.file}&quot; file.">
<condition>
<not>
<available file="${build.properties.file}" />
</not>
</condition>
</fail>
<property file="${build.properties.file}" />
<fail unless="webapp.name" message="${build.properties.file} must contain a value for webapp.name" />
<property name="solr.app.name" value="${webapp.name}solr" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deployProperties
- - - - - - - - - - - - - - - - - -->
<target name="deployProperties" depends="buildProperties">
<fail unless="vitro.home" message="${build.properties.file} must contain a value for vitro.home" />
<fail unless="tomcat.home" message="${build.properties.file} must contain a value for tomcat.home" />
<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="${utilities.lib.dir}" includes="*.jar" />
<fileset dir="${buildtools.lib.dir}" includes="*.jar" />
</path>
<path id="utility.run.classpath">
<pathelement location="${utility.classes.dir}" />
<path refid="utility.compile.classpath" />
</path>
<path id="test.compile.classpath">
<pathelement location="${war.classes.dir}" />
<path refid="compile.classpath" />
</path>
<path id="test.run.classpath">
<pathelement location="${appbase.dir}/test" />
<pathelement location="${test.classes.dir}" />
<path refid="test.compile.classpath" />
<path refid="utility.run.classpath" />
</path>
<!-- =================================
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.
war - Create a WAR file to be deployed in a servlet container.
deploy - Deploy the application 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">
<fail message="You must create a &quot;${deploy.properties.file}&quot; file.">
<condition>
<not>
<available file="${deploy.properties.file}" />
</not>
</condition>
</fail>
<property file="${deploy.properties.file}" />
<fail unless="tomcat.home" message="${deploy.properties.file} must contain a value for tomcat.home" />
<fail unless="webapp.name" message="${deploy.properties.file} must contain a value for webapp.name" />
<fail unless="vitro.home.directory" message="${deploy.properties.file} must contain a value for vitro.home.directory" />
<fail unless="Vitro.defaultNamespace" message="${deploy.properties.file} must contain a value for Vitro.defaultNamespace" />
<fail unless="VitroConnection.DataSource.url" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.url" />
<fail unless="VitroConnection.DataSource.username" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.username" />
<fail unless="VitroConnection.DataSource.password" message="${deploy.properties.file} must contain a value for VitroConnection.DataSource.password" />
<fail unless="rootUser.emailAddress" message="${deploy.properties.file} must contain a value for rootUser.emailAddress" />
<fail message="The vitro.home.directory &quot;${vitro.home.directory}&quot; does not exist.">
<condition>
<not>
<available file="${vitro.home.directory}" />
</not>
</condition>
</fail>
<fail message="The vitro.home.directory &quot;${vitro.home.directory}&quot; is not writable.">
<condition>
<not>
<isfileselected file="${vitro.home.directory}">
<writable />
</isfileselected>
</not>
</condition>
</fail>
<property name="solr.home.dir" location="${vitro.home.directory}/solr" />
</target>
<!-- =================================
target: clean
================================= -->
<target name="clean" depends="properties" description="--> Delete all artifacts.">
<delete dir="${build.dir}" />
<delete dir="${solr.home.dir}" excludes="data/**/*" includeemptydirs="true" />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compileUtilities
- - - - - - - - - - - - - - - - - -->
<target name="compileUtilities">
<mkdir dir="${utility.classes.dir}" />
<javac srcdir="${utilities.source.dir}" destdir="${utility.classes.dir}" debug="true" deprecation="${javac.deprecation}" encoding="UTF8" includeantruntime="false" optimize="false" source="1.6">
<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.6">
<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" depends="properties, compileUtilities">
<target name="prepare">
<mkdir dir="${build.dir}" />
<mkdir dir="${war.classes.dir}" />
<mkdir dir="${war.resources.dir}" />
<mkdir dir="${test.classes.dir}" />
</target>
<!-- copy all sorts of web stuff into the war directory. -->
<copy todir="${war.dir}">
<!-- - - - - - - - - - - - - - - - - -
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="${war.webinf.dir}">
<copy todir="${main.webinf.dir}">
<fileset dir="${appbase.dir}">
<!-- copy the JARs into the war directory -->
<include name="lib/*" />
<!-- these are already in Tomcat: we mustn't conflict. -->
<!-- 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. -->
<available file="${appbase.dir}/config/debug.log4j.properties" property="debug.log4j.exists" />
<copy tofile="${war.classes.dir}/log4j.properties" filtering="true" overwrite="true">
<fileset dir="${appbase.dir}/config">
<include name="default.log4j.properties" unless="debug.log4j.exists" />
<include name="debug.log4j.properties" if="debug.log4j.exists" />
</fileset>
<condition property="log4j.properties.file" value="debug.log4j.properties" else="default.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="${war.classes.dir}">
<!-- copy the deploy.properties into the war directory -->
<fileset file="${deploy.properties.file}" />
<!-- copy any xml files from source tree to the war directory -->
<fileset dir="${appbase.dir}/src" includes="**/*.xml" />
<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 context file into the war directory -->
<copy file="${appbase.dir}/context.xml" tofile="${war.dir}/META-INF/context.xml" />
<!-- Copy the build.properties file to the resources directory. -->
<copy todir="${main.resources.dir}" file="${build.properties.file}" />
<!-- If there is a runtime.properties file in the same directory as build.properties, copy that too. -->
<dirname file="${build.properties.file}" property="runtime.properties.dir"/>
<copy todir="${main.resources.dir}" >
<fileset dir="${runtime.properties.dir}" >
<filename name="runtime.properties" />
</fileset>
</copy>
<!-- copy any xml files from source tree to the war directory -->
<copy todir="${main.compiled.dir}">
<fileset dir="${appbase.dir}/src" includes="**/*.xml" />
</copy>
</target>
<!-- =================================
target: clean
================================= -->
<target name="clean" description="--> Delete all artifacts.">
<delete dir="${build.dir}" />
</target>
<!-- =================================
target: compile
================================= -->
<target name="compile" depends="prepare" description="--> Compile Java sources">
<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="${war.classes.dir}" closure="false" cache="${build.dir}/.depcache">
<classpath refid="compile.classpath" />
<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="${war.classes.dir}" debug="true" deprecation="${javac.deprecation}" encoding="UTF8" includeantruntime="false" optimize="true" source="1.6">
<classpath refid="compile.classpath" />
<javac srcdir="${appbase.dir}/src"
destdir="${main.compiled.dir}"
debug="true"
deprecation="${option.javac.deprecation}"
encoding="UTF8"
includeantruntime="false"
optimize="true"
source="1.6">
<classpath refid="main.compile.classpath" />
</javac>
</target>
<!-- =================================
target: test
================================= -->
<target name="test" depends="compile" unless="skiptests" description="--> Run JUnit tests">
<javac srcdir="${appbase.dir}/test" destdir="${test.classes.dir}" debug="true" deprecation="${javac.deprecation}" encoding="UTF8" includeantruntime="false" optimize="false" source="1.6">
<target name="test" depends="compile, compileBuildtools" unless="skiptests" description="--> Run JUnit tests">
<path id="test.compile.classpath">
<pathelement location="${main.compiled.dir}" />
<path refid="main.compile.classpath" />
</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.6">
<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" />
</path>
<java classname="edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner" fork="yes" failonerror="true">
<classpath refid="test.run.classpath" />
<arg file="${appbase.dir}/test" />
@ -227,112 +237,160 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
</java>
</target>
<!-- =================================
target: jar
================================= -->
<target name="jar" depends="test" description="--> Compile the Java, and build a JAR file">
<jar basedir="${war.classes.dir}" destfile="${build.dir}/${ant.project.name}.jar" />
</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="${revisionInfo.build.file}">${revisionInfo.timestamp}
<echo file="${main.revisioninfo.file}">${revisionInfo.timestamp}
</echo>
<addRevisionInfoLine productName="vitroCore" productCheckoutDir="${corebase.dir}/.." />
</target>
<!-- - - - - - - - - - - - - - - - - -
target: prepareSolr
target: deployWebapp
- - - - - - - - - - - - - - - - - -->
<target name="prepareSolr" depends="properties" unless="skipsolr">
<mkdir dir="${solr.home.dir}" />
<mkdir dir="${solr.build.dir}" />
<target name="deployWebapp" depends="deployProperties, revisionInfo">
<mkdir dir="${main.tomcat.webapp.dir}" />
<property name="solr.distrib.dir" location="${corebase.dir}/../solr" />
<property name="solr.home.template.dir" location="${solr.distrib.dir}/homeDirectoryTemplate" />
<property name="solr.context.template.file" location="${solr.distrib.dir}/template.context.xml" />
<property name="solr.distrib.war" location="${solr.distrib.dir}/apache-solr-3.1.0.war" />
<sync todir="${main.tomcat.webapp.dir}" includeemptydirs="true">
<fileset dir="${main.webapp.dir}" />
<preserveintarget>
<include name="${tomcat.context.filename}"/>
</preserveintarget>
</sync>
<property name="solr.context.file" location="${solr.build.dir}/context.xml" />
<property name="solr.context.temp.file" location="${solr.build.dir}/context.temp.xml" />
<property name="solr.build.war" location="${solr.build.dir}/solr.war" />
<property name="solr.context.name" value="${webapp.name}solr" />
<property name="solr.deployed.war" value="${tomcat.home}/webapps/${solr.context.name}.war" />
<!-- if no mask is defined, leave Solr unsecured. -->
<property name="vitro.local.solr.ipaddress.mask" value=".*" />
<!-- Create and copy the example directory to the solr.home.dir directory. -->
<copy todir="${solr.home.dir}">
<fileset dir="${solr.home.template.dir}" includes="**/*" />
</copy>
<!-- Create the context configuration XML with expanded properties. Store it in a temp file for now. -->
<copy tofile="${solr.context.temp.file}" filtering="true" overwrite="true">
<fileset file="${solr.context.template.file}" />
<!-- 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>
<!-- If the WAR is up to date and the context file hasn't changed, we can skip the deploy. -->
<condition property="skipsolr">
<and>
<uptodate targetfile="${solr.build.war}">
<srcfiles file="${solr.distrib.war}" />
<srcfiles dir="${appbase.dir}/config/solr/" />
</uptodate>
<filesmatch file1="${solr.context.temp.file}" file2="${solr.context.file}" />
<filesmatch file1="${solr.context.temp.file}" file2="${tomcat.home}/webapps/${solr.context.name}/META-INF/context.xml" />
</and>
</condition>
<!-- 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, with our config options -->
<unwar src="${solr.template.dir}/apache-solr-3.6.2.war" dest="${solr.webapp.dir}" />
<copy todir="${solr.webapp.dir}/WEB-INF/classes">
<fileset dir="${appbase.dir}/config/solr/" />
</copy>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: deploySolr
- - - - - - - - - - - - - - - - - -->
<target name="deploySolr" depends="prepareSolr" unless="skipsolr">
<!-- save the new context file, so we can compare against it next time. -->
<copy file="${solr.context.temp.file}" tofile="${solr.context.file}" />
<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>
<war destfile="${solr.build.war}" needxmlfile="false">
<zipfileset src="${solr.distrib.war}" />
<classes dir="${appbase.dir}/config/solr" />
<metainf file="${solr.context.file}" />
</war>
<!-- 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>
<!-- deploy the new WAR -->
<unwar src="${solr.build.war}" dest="${tomcat.home}/webapps/${solr.context.name}" />
<!-- 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: deploy
================================= -->
<target name="deploy" depends="revisionInfo, deploySolr" description="--> Build the app and install in Tomcat">
<property name="webapp.deploy.home" value="${tomcat.home}/webapps/${webapp.name}" />
<mkdir dir="${webapp.deploy.home}" />
<sync todir="${webapp.deploy.home}" includeemptydirs="true">
<fileset dir="${build.dir}/war" />
</sync>
<target name="deploy"
depends="deployWebapp, deploySolr"
description="--> Build the app and install in Tomcat">
</target>
<!-- =================================
target: war
target: all
================================= -->
<target name="war" depends="revisionInfo" description="--> Build the app and create a WAR file">
<jar basedir="${build.dir}/war" destfile="${build.dir}/${webapp.name}.war" />
<target name="all" depends="clean, deploy" description="--> Run 'clean', then 'deploy'" />
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OUTSIDE THE MAIN BUILD SEQUENCE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- =================================
target: distribute
================================= -->
<target name="distribute"
depends="revisionInfo, 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="${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
@ -348,7 +406,7 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
<!-- =================================
target: jarlist
================================= -->
<target name="jarlist" depends="jar" description="Figure out what JARs are not needed">
<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" />
@ -393,13 +451,16 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
<attribute name="productName" />
<attribute name="productCheckoutDir" />
<sequential>
<java classname="edu.cornell.mannlib.vitro.utilities.revisioninfo.RevisionInfoBuilder" fork="no" failonerror="true">
<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="${revisionInfo.build.file}" />
<arg file="${main.revisioninfo.file}" />
</java>
</sequential>
</macrodef>
</project>

View file

@ -0,0 +1,29 @@
# -----------------------------------------------------------------------------
#
# 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

View file

@ -1,11 +1,11 @@
# -----------------------------------------------------------------------------
#
# Vitro deployment properties
# Vitro runtime properties
#
# This file is provided as example.deploy.properties.
# This file is provided as example.runtime.properties.
#
# Save a copy of this file as deploy.properties, and edit the properties as
# needed for your deployment.
# Save a copy of this file as runtime.properties in your Vitro home directory,
# and edit the properties as needed for your installation.
#
# -----------------------------------------------------------------------------
@ -22,19 +22,6 @@
#
Vitro.defaultNamespace = http://vivo.mydomain.edu/individual/
#
# 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
#
# URL of Solr context used in local Vitro search. This will usually consist of:
# scheme + server_name + port + vitro_webapp_name + "solr"
@ -45,28 +32,6 @@ webapp.name = vitro
# vitro.local.solr.url = http://localhost:8080/vitrosolr
vitro.local.solr.url = http://localhost:8080/vitrosolr
#
# Restricts access to the Solr search platform. The value is a regular expression.
# When a request is made to Solr, the IP address of the requestor must match the
# regular expression, or the request will be rejected.
#
# NOTE: don't leave a space on the end of the line, unless you want it to be
# part of the expression.
# Examples:
# vitro.local.solr.ipaddress.mask = 127\.0\.0\.1
# vitro.local.solr.ipaddress.mask = 127\.0\.0\.1|0:0:0:0:0:0:0:1
# vitro.local.solr.ipaddress.mask = 169\.254\..*
# If this line is removed, your Solr server will respond to requests from any
# location. This may be useful for experimenting but would likely be considered
# a security problem in a production environment.
vitro.local.solr.ipaddress.mask = 127\.0\.0\.1|[0:]+:1
#
# 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.directory = /usr/local/vitro/data
#
# 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

View file

@ -1,20 +1,5 @@
<Context>
<!-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<!--
Vitro will interpret this as either a file path or a resource path. So,
if a simple resource path is used, such as "deploy.properties", Vitro
will find the file at:
${Tomcat}/webapps/vitro/WEB-INF/classes/deploy.properties
For an external file, specify a full file path, like
"/usr/local/vitro/deploy.properties".
-->
<Environment type="java.lang.String" override="false"
name="path.configuration"
value="deploy.properties"
/>
<!--
Disable the attempt to persist sessions when Tomcat shuts down.
-->

View file

@ -120,7 +120,7 @@ public class RootUserPolicy implements PolicyIface {
PROPERTY_ROOT_USER_EMAIL);
if (email == null) {
throw new IllegalStateException(
"deploy.properties must contain a value for '"
"runtime.properties must contain a value for '"
+ PROPERTY_ROOT_USER_EMAIL + "'");
} else {
return email;
@ -177,7 +177,7 @@ public class RootUserPolicy implements PolicyIface {
private void complainAboutMultipleRootUsers() {
for (String other : otherRootUsers) {
ss.warning(this, "deploy.properties specifies '"
ss.warning(this, "runtime.properties specifies '"
+ configuredRootUser + "' as the value for '"
+ PROPERTY_ROOT_USER_EMAIL
+ "', but the system also contains this root user: "
@ -189,7 +189,7 @@ public class RootUserPolicy implements PolicyIface {
private void complainAboutWrongRootUsers() {
for (String other : otherRootUsers) {
ss.warning(this, "deploy.properties specifies '"
ss.warning(this, "runtime.properties specifies '"
+ configuredRootUser + "' as the value for '"
+ PROPERTY_ROOT_USER_EMAIL
+ "', but the system contains this root user instead: "

View file

@ -20,8 +20,8 @@ import org.apache.commons.logging.LogFactory;
* are attached to the servlet context.
*
* The customary behavior is for ConfigurationPropertiesSetup to create a
* ConfigurationPropertiesImpl, which will parse the deploy.properties file for
* these properties.
* ConfigurationPropertiesImpl, which will obtain the properties from the
* build.properties file and the runtime.properties file.
*/
public abstract class ConfigurationProperties {
private static final Log log = LogFactory

View file

@ -9,13 +9,16 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* The basic implementation of ConfigurationProperties. It loads the
* configuration properties from a properties file and stores them in a map.
* configuration properties from a properties file and stores them in a map. It
* also permits the caller to supply a map of "preemptive" properties that will
* be included and will override any matching properties from the file.
*
* Leading and trailing white space are trimmed from the property values.
*
@ -27,23 +30,25 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
private final Map<String, String> propertyMap;
public ConfigurationPropertiesImpl(InputStream stream) {
public ConfigurationPropertiesImpl(InputStream stream,
Map<String, String> preemptiveProperties) throws IOException {
Properties props = loadFromPropertiesFile(stream);
Map<String, String> map = copyPropertiesToMap(props);
trimWhiteSpaceFromValues(map);
this.propertyMap = Collections.unmodifiableMap(map);
if (preemptiveProperties != null) {
map.putAll(preemptiveProperties);
}
trimWhiteSpaceFromValues(map);
this.propertyMap = Collections.unmodifiableMap(map);
log.debug("Configuration properties are: " + map);
}
private Properties loadFromPropertiesFile(InputStream stream) {
private Properties loadFromPropertiesFile(InputStream stream)
throws IOException {
Properties props = new Properties();
try {
props.load(stream);
} catch (IOException e) {
throw new IllegalStateException(
"Failed to parse the configuration properties file.", e);
}
return props;
}
@ -84,7 +89,8 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
@Override
public String toString() {
return "ConfigurationPropertiesImpl[propertyMap=" + propertyMap + "]";
return "ConfigurationPropertiesImpl[propertyMap="
+ new TreeMap<String, String>(propertyMap) + "]";
}
}

View file

@ -4,11 +4,13 @@ package edu.cornell.mannlib.vitro.webapp.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
@ -21,61 +23,45 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Reads the configuration properties from a file and stores them in the servlet
* Locates the runtime configuration properties and stores them in the servlet
* context.
*
* This must be invoked before any listener that requires configuration
* properties.
*
* The path to the file can be specified by an Environment name in the Context,
* like this:
* The properties file must be called 'runtime.properties' in the Vitro home
* directory. The path to the Vitro home directory can be specifed by an JNDI
* value, or by a System property, or by a property in
* WEB-INF/resources/build.properties, in that order. If the Vitro home
* directory is specified in more than one way, a warning is issued and the
* first value is used.
*
* <pre>
* If the Vitro home directory cannot be located, or if it does not contain a
* file called 'runtime.properties', or if the file cannot be loaded, a fatal
* error is registered to abort the startup.
*
* <Context override="true">
* <Environment name="path.configuration"
* value="/wherever/the/file/lives/deploy.properties"
* type="java.lang.String"
* override="false" />
* </Context>
*
* </pre>
*
* We look in this environment variable to find the path to the properties file.
* If there is no such environment variable, the default path is used.
*
* Once the path has been determined, we will use it to look for a resource in
* the classpath. So if the path is "deploy.properties", it might be found in
* "tomcat/webapps/vivo/WEB-INF/classes/deploy.properties". Of course, it might
* also be found in any other portion of the classpath as well.
*
* If we can't find the resource in the classpath, we will use it to look for an
* external file. So, one might reasonably set this value to something like
* "/usr/local/vitro/stuff/my.deploy.properties".
*
* If neither a resource nor an external file can be found, we throw an
* exception and set AbortStartup.
* The ConfigurationProperties bean is created from the key/value pairs found in
* 'runtime.properties', and is stored in the servlet context. The value that
* was determined for 'vitro.home' is also included in the bean.
*/
public class ConfigurationPropertiesSetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSetup.class);
/**
* The JNDI naming context where Tomcat stores environment attributes.
*/
static final String JNDI_BASE = "java:comp/env";
/** JNDI path that defines the Vitro home directory */
private static final String VHD_JNDI_PATH = "java:comp/env/vitro/home";
/**
* The name of the JNDI environment mapping for the path to the
* configuration file (or resource).
*/
static final String PATH_CONFIGURATION = "path.configuration";
/** System property that defines the Vitro home directory */
private static final String VHD_SYSTEM_PROPERTY = "vitro.home";
/**
* If we don't find the path to the config properties from a JNDI mapping,
* use this. Not final, so we can jigger it for unit tests.
*/
private static String DEFAULT_CONFIG_PATH = "deploy.properties";
/** build.properties property that defines the Vitro home directory */
private static final String VHD_BUILD_PROPERTY = "vitro.home";
/** Configuration property to store the Vitro home directory */
private static final String VHD_CONFIGURATION_PROPERTY = "vitro.home";
/** Name of the file that contains runtime properties. */
private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties";
@Override
public void contextInitialized(ServletContextEvent sce) {
@ -85,12 +71,18 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
try {
InputStream stream = null;
try {
stream = locatePropertiesFile();
File vitroHomeDir = locateVitroHomeDirectory(ctx, ss);
File runtimePropertiesFile = locateRuntimePropertiesFile(
vitroHomeDir, ss);
stream = new FileInputStream(runtimePropertiesFile);
Map<String, String> preempts = createPreemptiveProperties(
VHD_CONFIGURATION_PROPERTY, vitroHomeDir);
ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl(
stream);
ConfigurationProperties.setBean(ctx, bean);
stream, preempts);
ConfigurationProperties.setBean(ctx, bean);
ss.info(this, "Loaded " + bean.getPropertyMap().size()
+ " properties.");
} finally {
@ -102,81 +94,171 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
}
}
}
} catch (IllegalStateException e) {
ss.fatal(this, e.getMessage(), e);
} catch (Exception e) {
log.error(e, e);
ss.fatal(this, e.getMessage(), e);
}
}
private InputStream locatePropertiesFile() {
String path = determinePathToProperties();
log.debug("Configuration properties path is '" + path + "'");
if (resourceExists(path)) {
log.debug("Found configuration properties as a resource.");
return getResourceStream(path);
}
if (externalFileExists(path)) {
log.debug("Found configuration properties as an external file.");
return getExternalFileStream(path);
}
throw new IllegalStateException("Can't find the properties file at '"
+ path + "'");
}
/**
* If we can't find it with JNDI, use the default.
* Look in the JDNI environment, the system properties, and the
* build.properties file.
*
* If we don't find it, fail. If we find it more than once, warn and use the
* first one.
*
* Confirm that it is an existing, readable directory.
*/
private String determinePathToProperties() {
private File locateVitroHomeDirectory(ServletContext ctx, StartupStatus ss) {
Map<String, String> whereWasIt = new LinkedHashMap<String, String>();
getVhdFromJndi(whereWasIt);
getVhdFromSystemProperties(whereWasIt);
getVhdFromBuildProperties(ctx, whereWasIt);
if (whereWasIt.isEmpty()) {
String message = String.format("Can't find a value "
+ "for the Vitro home directory. "
+ "Looked in JNDI environment at '%s'. "
+ "Looked for a system property named '%s'. "
+ "Looked in 'WEB-INF/resources/build.properties' "
+ "for '%s'.", VHD_JNDI_PATH, VHD_SYSTEM_PROPERTY,
VHD_BUILD_PROPERTY);
throw new IllegalStateException(message);
} else if (whereWasIt.size() > 1) {
String message = String.format("Found multiple values for the "
+ "Vitro home directory: " + whereWasIt.keySet());
ss.warning(this, message);
}
String message = whereWasIt.keySet().iterator().next();
String vhdPath = whereWasIt.values().iterator().next();
ss.info(this, message);
File vhd = new File(vhdPath);
if (!vhd.exists()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' does not exist.");
}
if (!vhd.isDirectory()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' is not a directory.");
}
if (!vhd.canRead()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' cannot be read.");
}
if (!vhd.canWrite()) {
throw new IllegalStateException(
"Can't write to Vitro home directory: '" + vhdPath + "'.");
}
return vhd;
}
private void getVhdFromJndi(Map<String, String> whereWasIt) {
try {
Context envCtx = (Context) new InitialContext().lookup(JNDI_BASE);
if (envCtx == null) {
log.debug("JNDI Lookup on '" + JNDI_BASE + "' failed.");
return DEFAULT_CONFIG_PATH;
String vhdPath = (String) new InitialContext()
.lookup(VHD_JNDI_PATH);
if (vhdPath == null) {
log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH
+ "'.");
return;
}
String configPath = (String) envCtx.lookup(PATH_CONFIGURATION);
if (configPath == null) {
log.debug("JNDI Lookup on '" + PATH_CONFIGURATION + "' failed.");
return DEFAULT_CONFIG_PATH;
}
log.debug("deploy.property as specified by JNDI: " + configPath);
return configPath;
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: "
+ vhdPath);
String message = String.format(
"JNDI environment '%s' was set to '%s'", VHD_JNDI_PATH,
vhdPath);
whereWasIt.put(message, vhdPath);
} catch (NamingException e) {
log.warn("JNDI lookup failed. "
+ "Using default path for config properties.", e);
return DEFAULT_CONFIG_PATH;
log.debug("JNDI lookup failed. " + e);
}
}
private boolean resourceExists(String path) {
return getResourceStream(path) != null;
private void getVhdFromSystemProperties(Map<String, String> whereWasIt) {
String vhdPath = System.getProperty(VHD_SYSTEM_PROPERTY);
if (vhdPath == null) {
log.debug("Didn't find a system property value at '"
+ VHD_SYSTEM_PROPERTY + "'.");
return;
}
private InputStream getResourceStream(String path) {
return getClass().getClassLoader().getResourceAsStream(path);
log.debug("'" + VHD_SYSTEM_PROPERTY
+ "' as specified by system property: " + vhdPath);
String message = String.format("System property '%s' was set to '%s'",
VHD_SYSTEM_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
}
private boolean externalFileExists(String path) {
File file = new File(path);
return file.isFile();
}
private void getVhdFromBuildProperties(ServletContext ctx,
Map<String, String> whereWasIt) {
String resourcePath = "/WEB-INF/resources/build.properties";
private InputStream getExternalFileStream(String path) {
InputStream stream = null;
File file = new File(path);
if (file.isFile()) {
try {
stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
// testing file.isFile() should have prevented this
log.error(e, e);
stream = ctx.getResourceAsStream(resourcePath);
if (stream == null) {
log.debug("Didn't find a resource at '" + resourcePath + "'.");
return;
}
Properties props = new Properties();
props.load(stream);
String vhdPath = props.getProperty(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("'" + resourcePath + "' didn't contain a value for '"
+ VHD_BUILD_PROPERTY + "'.");
return;
}
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.", resourcePath,
VHD_BUILD_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
} catch (IOException e) {
log.warn("Failed to load from '" + resourcePath + "'.", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return stream;
}
}
private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) {
File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES);
if (!rpf.exists()) {
throw new IllegalStateException("Did not find '"
+ FILE_RUNTIME_PROPERTIES + "' in vitro home directory '"
+ vitroHomeDir + "'");
}
if (!rpf.isFile()) {
throw new IllegalStateException("'" + rpf.getPath()
+ "' is not a file.");
}
if (!rpf.canRead()) {
throw new IllegalStateException("Cannot read '" + rpf.getPath()
+ "'.");
}
ss.info(this, "Loading runtime properties from '" + rpf.getPath() + "'");
return rpf;
}
private Map<String, String> createPreemptiveProperties(
String propertyVitroHome, File vitroHomeDir) {
Map<String, String> map = new HashMap<String, String>();
map.put(propertyVitroHome, vitroHomeDir.getAbsolutePath());
return map;
}
@Override

View file

@ -32,7 +32,7 @@ public class ConfigurationPropertiesSmokeTests implements
private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSmokeTests.class);
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory";
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home";
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
private static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username";
private static final String PROPERTY_DB_PASSWORD = "VitroConnection.DataSource.password";
@ -61,7 +61,7 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String homeDirectoryPath = props.getProperty(PROPERTY_HOME_DIRECTORY);
if (homeDirectoryPath == null || homeDirectoryPath.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "Can't find a value for the home directory: '"
+ PROPERTY_HOME_DIRECTORY + "'");
return;
}
@ -97,19 +97,19 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String url = props.getProperty(PROPERTY_DB_URL);
if (url == null || url.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_URL + "'");
return;
}
String username = props.getProperty(PROPERTY_DB_USERNAME);
if (username == null || username.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_USERNAME + "'");
return;
}
String password = props.getProperty(PROPERTY_DB_PASSWORD);
if (password == null || password.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_PASSWORD + "'");
return;
}
@ -259,7 +259,7 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String ns = props.getProperty(PROPERTY_DEFAULT_NAMESPACE);
if (ns == null || ns.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DEFAULT_NAMESPACE + "'");
return;
}

View file

@ -117,7 +117,7 @@ public class ExternalAuthHelper {
}
if (externalAuthServerUrl == null) {
log.debug("deploy.properties doesn't contain a value for '"
log.debug("runtime.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_SERVER_URL
+ "' -- sending directly to '" + returnUrl + "'");
return returnUrl;
@ -142,7 +142,7 @@ public class ExternalAuthHelper {
if (externalAuthHeaderName == null) {
log.error("User asked for external authentication, "
+ "but deploy.properties doesn't contain a value for '"
+ "but runtime.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_ID_HEADER + "'");
return null;
}

View file

@ -37,7 +37,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
* the header will contain the name of the user who just logged in.
*
* Deal with these possibilities:
* - The header name was not configured in deploy.properties. Complain.
* - The header name was not configured in runtime.properties. Complain.
* - No username: the login failed. Complain
* - User corresponds to a User acocunt. Record the login.
* - User corresponds to an Individual (self-editor).

View file

@ -50,7 +50,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private final static String TEMPLATE_FORM = "contactForm-form.ftl";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html";

View file

@ -5,11 +5,16 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -17,8 +22,12 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.i18n.freemarker.I18nMethodModel;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils;
import edu.cornell.mannlib.vitro.webapp.web.directives.IndividualShortViewDirective;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualPlaceholderImageUrlMethod;
@ -27,16 +36,22 @@ import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap;
public class FreemarkerConfiguration extends Configuration {
private static final Log log = LogFactory.getLog(FreemarkerConfiguration.class);
private static final String PROPERTY_DEVELOPER_DEFEAT_CACHE = "developer.defeatFreemarkerCache";
private final String themeDir;
private final ServletContext context;
private final ApplicationBean appBean;
@ -47,9 +62,9 @@ public class FreemarkerConfiguration extends Configuration {
this.context = context;
this.appBean = appBean;
String buildEnv = ConfigurationProperties.getBean(context).getProperty("Environment.build");
log.debug("Current build environment: " + buildEnv);
if ("development".equals(buildEnv)) { // Set Environment.build = development in deploy.properties
String flag = ConfigurationProperties.getBean(context).getProperty(
PROPERTY_DEVELOPER_DEFEAT_CACHE, "false");
if (Boolean.valueOf(flag.trim())) {
log.debug("Disabling Freemarker template caching in development build.");
setTemplateUpdateDelay(0); // no template caching in development
} else {
@ -164,6 +179,7 @@ public class FreemarkerConfiguration extends Configuration {
map.put("profileUrl", new IndividualProfileUrlMethod());
map.put("localName", new IndividualLocalNameMethod());
map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod());
map.put("i18n", new I18nMethodModel());
return map;
}
@ -199,4 +215,101 @@ public class FreemarkerConfiguration extends Configuration {
return mtl;
}
/**
* Override getTemplate(), so we can apply DataGetters to all included
* templates.
*
* This won't work for top-level Templates, since the Environment hasn't
* been created yet. When TemplateProcessingHelper creates the Environment,
* it must call retrieveAndRunDataGetters() for the top-level Template.
*/
@Override
public Template getTemplate(String name, Locale locale, String encoding,
boolean parse) throws IOException {
Template template = super.getTemplate(name, locale, encoding, parse);
if (template == null) {
log.debug("Template '" + name + "' not found for locale '" + locale + "'.");
return template;
}
Environment env = getEnvironment();
if (env == null) {
log.debug("Not fetching data getters for template '" + template.getName() + "'. No environment.");
return template;
}
retrieveAndRunDataGetters(env, template.getName());
return template;
}
/**
* Find the DataGetters for this template, and apply them to the Freemarker
* environment.
*/
public static void retrieveAndRunDataGetters(Environment env, String templateName) {
HttpServletRequest req = (HttpServletRequest) env.getCustomAttribute("request");
VitroRequest vreq = new VitroRequest(req);
if (dataGettersAlreadyApplied(env, templateName)) {
log.debug("DataGetters for '" + templateName+"' have already been applied");
return;
}
try {
List<DataGetter> dgList = DataGetterUtils.getDataGettersForTemplate(
vreq, vreq.getDisplayModel(), templateName);
log.debug("Retrieved " + dgList.size() + " data getters for template '" + templateName + "'");
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(env.getDataModel());
for (DataGetter dg : dgList) {
applyDataGetter(dg, env, dataMap);
}
} catch (Exception e) {
log.warn(e, e);
}
}
/**
* Have the DataGetters for this template already been applied to this environment?
* If not, record that they are being applied now.
*/
@SuppressWarnings("unchecked")
private static boolean dataGettersAlreadyApplied(Environment env, String templateName) {
Set<String> names;
Object o = env.getCustomAttribute("dataGettersApplied");
if (o instanceof Set) {
names = (Set<String>) o;
} else {
names = new HashSet<String>();
}
boolean added = names.add(templateName);
if (added) {
env.setCustomAttribute("dataGettersApplied", names);
return false;
} else {
return true;
}
}
/**
* Get the data from a DataGetter, and store it in global variables in the
* Freemarker environment.
*/
private static void applyDataGetter(DataGetter dg, Environment env,
Map<String, Object> dataMap) throws TemplateModelException {
Map<String, Object> moreData = dg.getData(dataMap);
ObjectWrapper wrapper = env.getObjectWrapper();
if (moreData != null) {
for (String key : moreData.keySet()) {
Object value = moreData.get(key);
env.setGlobalVariable(key, wrapper.wrap(value));
log.debug("Stored in environment: '" + key + "' = '" + value + "'");
}
}
}
}

View file

@ -51,12 +51,20 @@ public class TemplateProcessingHelper {
env.setCustomAttribute("request", request);
env.setCustomAttribute("context", context);
// Set the Locale from the request into the environment, so date builtins will be
// Locale-dependent
env.setLocale(request.getLocale());
// Define a setup template to be included by every page template
String templateType = (String) map.get("templateType");
if (FreemarkerHttpServlet.PAGE_TEMPLATE_TYPE.equals(templateType)) {
env.include(getTemplate("pageSetup.ftl"));
}
// Apply any data-getters that are associated with this template.
FreemarkerConfiguration.retrieveAndRunDataGetters(env, template.getName());
// Now process it.
env.process();
} catch (TemplateException e) {
throw new TemplateProcessingException("TemplateException creating processing environment", e);

View file

@ -201,7 +201,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
viewJson.put("url", urlBuf.toString() + "/individual?uri={{id}}");
json.put("view", viewJson);
// parse defaultTypeList from deploy.properties
// parse defaultTypeList from runtime.properties
if (defaultTypeList != null) {
String[] splitList = defaultTypeList.split(";");
String[][] idNameArray = new String[splitList.length][splitList.length];

View file

@ -35,7 +35,7 @@ public class FileStorageSetup implements ServletContextListener {
* {@link ConfigurationProperties} for the vivo home directory. The file
* storage base directory is in a subdirectory below this one.
*/
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
public static final String FILE_STORAGE_SUBDIRECTORY = "uploads";
/**

View file

@ -0,0 +1,228 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Provides access to a bundle of text strings, based on the name of the bundle,
* the Locale of the requesting browser, and the current theme directory.
*
* If the bundle name is not specified, the default name of "all" is used.
*
* If a requested bundle is not found, no error is thrown. Instead, an empty
* bundle is returned that produces error message strings when asked for text.
*/
public class I18n {
private static final Log log = LogFactory.getLog(I18n.class);
public static final String DEFAULT_BUNDLE_NAME = "all";
private static final String PROPERTY_DEVELOPER_DEFEAT_CACHE = "developer.defeatI18nCache";
/**
* This is where the work gets done. Not declared final, so it can be
* modified in unit tests.
*/
private static I18n instance = new I18n();
// ----------------------------------------------------------------------
// Static methods
// ----------------------------------------------------------------------
/**
* A convenience method to get a bundle and format the text.
*/
public static String text(String bundleName, HttpServletRequest req,
String key, Object... parameters) {
return bundle(bundleName, req).text(key, parameters);
}
/**
* A convenience method to get the default bundle and format the text.
*/
public static String text(HttpServletRequest req, String key,
Object... parameters) {
return bundle(req).text(key, parameters);
}
/**
* Get a I18nBundle by this name.
*/
public static I18nBundle bundle(String bundleName, HttpServletRequest req) {
return instance.getBundle(bundleName, req);
}
/**
* Get the default I18nBundle.
*/
public static I18nBundle bundle(HttpServletRequest req) {
return instance.getBundle(DEFAULT_BUNDLE_NAME, req);
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
/** Holds the current theme directory, as far as we know. */
private AtomicReference<String> themeDirectory = new AtomicReference<String>(
"");
/**
* Get an I18nBundle by this name. The request provides the preferred
* Locale, the theme directory and the development mode flag.
*
* If the request indicates that the system is in development mode, then the
* cache is cleared on each request.
*
* If the theme directory has changed, the cache is cleared.
*/
private I18nBundle getBundle(String bundleName, HttpServletRequest req) {
log.debug("Getting bundle '" + bundleName + "'");
try {
checkDevelopmentMode(req);
checkForChangeInThemeDirectory(req);
String dir = themeDirectory.get();
ServletContext ctx = req.getSession().getServletContext();
ResourceBundle.Control control = getControl(ctx, dir);
ResourceBundle rb = ResourceBundle.getBundle(bundleName,
req.getLocale(), control);
return new I18nBundle(bundleName, rb);
} catch (MissingResourceException e) {
log.warn("Didn't find text bundle '" + bundleName + "'");
return I18nBundle.emptyBundle(bundleName);
} catch (Exception e) {
log.error("Failed to create text bundle '" + bundleName + "'", e);
return I18nBundle.emptyBundle(bundleName);
}
}
/**
* If we are in development mode, clear the cache on each request.
*/
private void checkDevelopmentMode(HttpServletRequest req) {
ConfigurationProperties bean = ConfigurationProperties.getBean(req);
String flag = bean
.getProperty(PROPERTY_DEVELOPER_DEFEAT_CACHE, "false");
if (Boolean.valueOf(flag.trim())) {
log.debug("In development mode - clearing the cache.");
ResourceBundle.clearCache();
}
}
/**
* If the theme directory has changed from before, clear the cache of all
* ResourceBundles.
*/
private void checkForChangeInThemeDirectory(HttpServletRequest req) {
String currentDir = new VitroRequest(req).getAppBean().getThemeDir();
String previousDir = themeDirectory.getAndSet(currentDir);
if (!currentDir.equals(previousDir)) {
log.debug("Theme directory changed from '" + previousDir + "' to '"
+ currentDir + "' - clearing the cache.");
ResourceBundle.clearCache();
}
}
/**
* Override this method in the unit tests, to return a more testable Control
* instance.
*/
protected Control getControl(ServletContext ctx, String dir) {
return new ThemeBasedControl(ctx, dir);
}
// ----------------------------------------------------------------------
// Control classes for instantiating ResourceBundles
// ----------------------------------------------------------------------
/**
* Instead of looking in the classpath, look in the theme directory.
*/
private static class ThemeBasedControl extends ResourceBundle.Control {
private static final String BUNDLE_DIRECTORY = "i18n/";
private final ServletContext ctx;
private final String themeDirectory;
public ThemeBasedControl(ServletContext ctx, String themeDirectory) {
this.ctx = ctx;
this.themeDirectory = themeDirectory;
}
/**
* Don't look for classes to satisfy the request, just property files.
*/
@Override
public List<String> getFormats(String baseName) {
return FORMAT_PROPERTIES;
}
/**
* Don't look in the class path, look in the current servlet context, in
* the bundle directory under the theme directory.
*/
@Override
public ResourceBundle newBundle(String baseName, Locale locale,
String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException,
IOException {
checkArguments(baseName, locale, format);
log.debug("Creating bundle for '" + baseName + "', " + locale
+ ", '" + format + "', " + reload);
String bundleName = toBundleName(baseName, locale);
if (bundleName == null) {
throw new NullPointerException("bundleName may not be null.");
}
String themeI18nPath = "/" + themeDirectory + BUNDLE_DIRECTORY;
String appI18nPath = "/" + BUNDLE_DIRECTORY;
log.debug("Paths are '" + themeI18nPath + "' and '" + appI18nPath
+ "'");
return VivoResourceBundle.getBundle(bundleName, ctx, appI18nPath,
themeI18nPath, this);
}
/**
* The documentation for ResourceBundle.Control.newBundle() says I
* should throw these exceptions.
*/
private void checkArguments(String baseName, Locale locale,
String format) {
if (baseName == null) {
throw new NullPointerException("baseName may not be null.");
}
if (locale == null) {
throw new NullPointerException("locale may not be null.");
}
if (format == null) {
throw new NullPointerException("format may not be null.");
}
if (!FORMAT_DEFAULT.contains(format)) {
throw new IllegalArgumentException(
"format must be one of these: " + FORMAT_DEFAULT);
}
}
}
}

View file

@ -0,0 +1,102 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Enumeration;
import java.util.ResourceBundle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A wrapper for a ResourceBundle that will not throw an exception, no matter
* what string you request.
*
* If the ResourceBundle was not found, or if it doesn't contain the requested
* key, an error message string is returned, to help the developer diagnose the
* problem.
*/
public class I18nBundle {
private static final Log log = LogFactory.getLog(I18nBundle.class);
private static final String MESSAGE_BUNDLE_NOT_FOUND = "Text bundle ''{0}'' not found.";
private static final String MESSAGE_KEY_NOT_FOUND = "Text bundle ''{0}'' has no text for ''{1}''";
public static I18nBundle emptyBundle(String bundleName) {
return new I18nBundle(bundleName);
}
private final String bundleName;
private final ResourceBundle resources;
private final String notFoundMessage;
private I18nBundle(String bundleName) {
this(bundleName, new EmptyResourceBundle(), MESSAGE_BUNDLE_NOT_FOUND);
}
public I18nBundle(String bundleName, ResourceBundle resources) {
this(bundleName, resources, MESSAGE_KEY_NOT_FOUND);
}
private I18nBundle(String bundleName, ResourceBundle resources, String notFoundMessage) {
if (bundleName == null) {
throw new IllegalArgumentException("bundleName may not be null");
}
if (bundleName.isEmpty()) {
throw new IllegalArgumentException("bundleName may not be empty");
}
if (resources == null) {
throw new NullPointerException("resources may not be null.");
}if (notFoundMessage == null) {
throw new NullPointerException("notFoundMessage may not be null.");
}
this.bundleName = bundleName;
this.resources = resources;
this.notFoundMessage = notFoundMessage;
}
public String text(String key, Object... parameters) {
log.debug("Asking for '" + key + "' from bundle '" + bundleName + "'");
String textString;
if (resources.containsKey(key)) {
textString = resources.getString(key);
return formatString(textString, parameters);
} else {
String message = MessageFormat.format(notFoundMessage, bundleName,
key);
log.warn(message);
return "ERROR: " + message;
}
}
private static String formatString(String textString, Object... parameters) {
if (parameters.length == 0) {
return textString;
} else {
return MessageFormat.format(textString, parameters);
}
}
/**
* A resource bundle that contains no strings.
*/
public static class EmptyResourceBundle extends ResourceBundle {
@Override
public Enumeration<String> getKeys() {
return Collections.enumeration(Collections.<String> emptySet());
}
@Override
protected Object handleGetObject(String key) {
if (key == null) {
throw new NullPointerException("key may not be null.");
}
return null;
}
}
}

View file

@ -0,0 +1,207 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Works like a PropertyResourceBundle with two exceptions:
*
* It looks for the file in both the i18n directory of the theme and in the i18n
* directory of the application. Properties found in the theme override those
* found in the application.
*
* It allows a property to take its contents from a file. File paths are
* relative to the i18n directory. Again, a file in the theme will override one
* in the application.
*
* If a property has a value (after overriding) of "@@file <filepath>", the
* bundle looks for the file relative to the i18n directory of the theme, then
* relative to the i18n directory of the application. If the file is not found
* in either location, a warning is written to the log and the property will
* contain an error message for displayed.
*
* Note that the filename is not manipulated for Locale, so the author of the
* properties files must do it explicitly. For example:
*
* In all.properties: account_email_html = @@file accountEmail.html
*
* In all_es.properties: account_email_html = @@file accountEmail_es.html
*/
public class VivoResourceBundle extends ResourceBundle {
private static final Log log = LogFactory.getLog(VivoResourceBundle.class);
private static final String FILE_FLAG = "@@file ";
private static final String MESSAGE_FILE_NOT_FOUND = "File {1} not found for property {0}.";
// ----------------------------------------------------------------------
// Factory method
// ----------------------------------------------------------------------
public static VivoResourceBundle getBundle(String bundleName,
ServletContext ctx, String appI18nPath, String themeI18nPath,
Control control) {
try {
return new VivoResourceBundle(bundleName, ctx, appI18nPath,
themeI18nPath, control);
} catch (FileNotFoundException e) {
log.debug(e);
return null;
} catch (Exception e) {
log.warn(e, e);
return null;
}
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
private final String bundleName;
private final ServletContext ctx;
private final String appI18nPath;
private final String themeI18nPath;
private final Control control;
private final Properties defaults;
private final Properties properties;
private VivoResourceBundle(String bundleName, ServletContext ctx,
String appI18nPath, String themeI18nPath, Control control)
throws IOException {
this.bundleName = bundleName;
this.ctx = ctx;
this.appI18nPath = appI18nPath;
this.themeI18nPath = themeI18nPath;
this.control = control;
this.defaults = new Properties();
this.properties = new Properties(this.defaults);
loadProperties();
loadReferencedFiles();
}
private void loadProperties() throws IOException {
String resourceName = control.toResourceName(bundleName, "properties");
String defaultsPath = joinPath(appI18nPath, resourceName);
String propertiesPath = joinPath(themeI18nPath, resourceName);
File defaultsFile = locateFile(defaultsPath);
File propertiesFile = locateFile(propertiesPath);
if ((defaultsFile == null) && (propertiesFile == null)) {
throw new FileNotFoundException("Property file not found at '"
+ defaultsPath + "' or '" + propertiesPath + "'");
}
if (defaultsFile != null) {
log.debug("Loading bundle '" + bundleName + "' defaults from '"
+ defaultsPath + "'");
FileInputStream stream = new FileInputStream(defaultsFile);
try {
this.defaults.load(stream);
} finally {
stream.close();
}
}
if (propertiesFile != null) {
log.debug("Loading bundle '" + bundleName + "' overrides from '"
+ propertiesPath + "'");
FileInputStream stream = new FileInputStream(propertiesFile);
try {
this.properties.load(stream);
} finally {
stream.close();
}
}
}
private void loadReferencedFiles() throws IOException {
for (String key : this.properties.stringPropertyNames()) {
String value = this.properties.getProperty(key);
if (value.startsWith(FILE_FLAG)) {
String filepath = value.substring(FILE_FLAG.length()).trim();
loadReferencedFile(key, filepath);
}
}
}
private void loadReferencedFile(String key, String filepath)
throws IOException {
String appFilePath = joinPath(appI18nPath, filepath);
String themeFilePath = joinPath(themeI18nPath, filepath);
File appFile = locateFile(appFilePath);
File themeFile = locateFile(themeFilePath);
if (themeFile != null) {
this.properties.setProperty(key,
FileUtils.readFileToString(themeFile, "UTF-8"));
} else if (appFile != null) {
this.properties.setProperty(key,
FileUtils.readFileToString(appFile, "UTF-8"));
} else {
String message = MessageFormat.format(MESSAGE_FILE_NOT_FOUND, key,
themeFilePath, appFilePath);
this.properties.setProperty(key, message);
log.warn(message);
}
}
private String joinPath(String root, String twig) {
if ((root.charAt(root.length() - 1) == File.separatorChar)
|| (twig.charAt(0) == File.separatorChar)) {
return root + twig;
} else {
return root + File.separatorChar + twig;
}
}
private File locateFile(String path) {
String realPath = ctx.getRealPath(path);
if (realPath == null) {
log.debug("No real path for '" + path + "'");
return null;
}
File f = new File(realPath);
if (!f.isFile()) {
log.debug("No file at '" + realPath + "'");
return null;
}
if (!f.canRead()) {
log.error("Can't read the file at '" + realPath + "'");
return null;
}
log.debug("Located file '" + path + "' at '" + realPath + "'");
return f;
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getKeys() {
return (Enumeration<String>) this.properties.propertyNames();
}
@Override
protected Object handleGetObject(String key) {
String value = this.properties.getProperty(key);
if (value == null) {
log.debug(bundleName + " has no value for '" + key + "'");
}
return value;
}
}

View file

@ -0,0 +1,40 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
/**
* For Freemarker, this acts like a bundle of text strings. It is simply a
* wrapper around an I18nBundle.
*/
public class I18nBundleTemplateModel implements TemplateHashModel {
private static final Log log = LogFactory
.getLog(I18nBundleTemplateModel.class);
private final String bundleName;
private final I18nBundle textBundle;
public I18nBundleTemplateModel(String bundleName, I18nBundle textBundle) {
this.bundleName = bundleName;
this.textBundle = textBundle;
}
@Override
public TemplateModel get(String key) throws TemplateModelException {
return new I18nStringTemplateModel(bundleName, key,
textBundle.text(key));
}
@Override
public boolean isEmpty() throws TemplateModelException {
return false;
}
}

View file

@ -0,0 +1,50 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
import freemarker.core.Environment;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* This Freemarker method will produce a bundle of text strings. It is simply a
* wrapper around I18n that produces a wrapped I18nBundle.
*
* If the bundle name is not provided, the default bundle is assumed.
*/
public class I18nMethodModel implements TemplateMethodModel {
private static final Log log = LogFactory.getLog(I18nMethodModel.class);
@SuppressWarnings("rawtypes")
@Override
public Object exec(List args) throws TemplateModelException {
if (args.size() > 1) {
throw new TemplateModelException("Too many arguments: "
+ "displayText method only requires a bundle name.");
}
Object arg = args.isEmpty() ? I18n.DEFAULT_BUNDLE_NAME : args.get(0);
if (!(arg instanceof String)) {
throw new IllegalArgumentException(
"Arguments to a TemplateMethodModel are supposed to be Strings!");
}
log.debug("Asking for this bundle: " + arg);
String bundleName = (String) arg;
Environment env = Environment.getCurrentEnvironment();
HttpServletRequest request = (HttpServletRequest) env
.getCustomAttribute("request");
I18nBundle tb = I18n.bundle(bundleName, request);
return new I18nBundleTemplateModel(bundleName, tb);
}
}

View file

@ -0,0 +1,79 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import java.text.MessageFormat;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
import freemarker.template.utility.DeepUnwrap;
/**
* A Freemarker representation of a text string. Because it implements
* TemplateScalarModel, you can use it as a string value. And because it
* implements TemplateMethodModel, you can pass arguments to it for formatting.
*
* So if the string is "His name is {0}!", then these references could be used:
*
* ${string} ==> "His name is {0}!"
*
* ${string("Bozo")} ==> "His name is Bozo!"
*
* Note that the format of the message is determined by java.text.MessageFormat,
* so argument indices start at 0 and you can escape a substring by wrapping it
* in apostrophes.
*/
public class I18nStringTemplateModel implements TemplateMethodModelEx,
TemplateScalarModel {
private static final Log log = LogFactory
.getLog(I18nStringTemplateModel.class);
private final String bundleName;
private final String key;
private final String textString;
public I18nStringTemplateModel(String bundleName, String key,
String textString) {
this.bundleName = bundleName;
this.key = key;
this.textString = textString;
}
@Override
public String getAsString() throws TemplateModelException {
return textString;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Object exec(List args) throws TemplateModelException {
log.debug("Formatting string '" + key + "' from bundle '" + bundleName
+ "' with these arguments: " + args);
if (args.isEmpty()) {
return textString;
} else {
Object[] unwrappedArgs = new Object[args.size()];
for (int i = 0; i < args.size(); i++) {
unwrappedArgs[i] = DeepUnwrap.unwrap((TemplateModel) args
.get(i));
}
try {
return MessageFormat.format(textString, unwrappedArgs);
} catch (Exception e) {
String message = "Can't format '" + key + "' from bundle '"
+ bundleName + "', wrong argument types: " + args
+ " for message format'" + textString + "'";
log.warn(message);
return message;
}
}
}
}

View file

@ -89,7 +89,7 @@ public class SolrSetup implements javax.servlet.ServletContextListener{
/* setup the http connection with the solr server */
String solrServerUrlString = ConfigurationProperties.getBean(sce).getProperty("vitro.local.solr.url");
if( solrServerUrlString == null ){
ss.fatal(this, "Could not find vitro.local.solr.url in deploy.properties. "+
ss.fatal(this, "Could not find vitro.local.solr.url in runtime.properties. "+
"Vitro application needs a URL of a solr server that it can use to index its data. " +
"It should be something like http://localhost:${port}" + context.getContextPath() + "solr"
);
@ -101,7 +101,7 @@ public class SolrSetup implements javax.servlet.ServletContextListener{
solrServerUrl = new URL(solrServerUrlString);
} catch (MalformedURLException e) {
ss.fatal(this, "Can't connect with the solr server. " +
"The value for vitro.local.solr.url in deploy.properties is not a valid URL: " + solrServerUrlString);
"The value for vitro.local.solr.url in runtime.properties is not a valid URL: " + solrServerUrlString);
return;
}

View file

@ -546,7 +546,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
if ((dns != null) && (!dns.isEmpty())) {
return dns;
} else {
throw new IllegalStateException("deploy.properties does not "
throw new IllegalStateException("runtime.properties does not "
+ "contain a value for '" + VITRO_DEFAULT_NAMESPACE + "'");
}
}

View file

@ -50,7 +50,7 @@ public class SolrSmokeTest implements ServletContextListener {
.getProperty("vitro.local.solr.url", "");
if (solrUrlString.isEmpty()) {
ss.fatal(this, "Can't connect to Solr search engine. "
+ "deploy.properties must contain a value for "
+ "runtime.properties must contain a value for "
+ "vitro.local.solr.url");
return;
}
@ -62,7 +62,7 @@ public class SolrSmokeTest implements ServletContextListener {
} catch (MalformedURLException e) {
ss.fatal(this, "Can't connect to Solr search engine. "
+ "The value for vitro.local.solr.url "
+ "in deploy.properties is not a valid URL: '"
+ "in runtime.properties is not a valid URL: '"
+ solrUrlString + "'", e);
}
@ -124,9 +124,7 @@ public class SolrSmokeTest implements ServletContextListener {
int status = e.getStatusCode();
Throwable cause = e.getCause();
if (status == HttpStatus.SC_FORBIDDEN) {
warnForbidden();
} else if (status == SOCKET_TIMEOUT_STATUS) {
if (status == SOCKET_TIMEOUT_STATUS) {
warnSocketTimeout();
} else if (status != 0) {
warnBadHttpStatus(status);
@ -151,23 +149,14 @@ public class SolrSmokeTest implements ServletContextListener {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The socket connection has repeatedly timed out. "
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties. Is Solr responding at that URL?");
}
private void warnForbidden() {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The Solr server will not accept connections from this "
+ "host. Check the value of "
+ "vitro.local.solr.ipaddress.mask in "
+ "deploy.properties -- "
+ "does it authorize access from this IP address?");
+ "runtime.properties. Is Solr responding at that URL?");
}
private void warnBadHttpStatus(int status) {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The Solr server returned a status code of " + status
+ ". Check the value of vitro.local.solr.url in "
+ "deploy.properties.");
+ "runtime.properties.");
}
private void warnProtocolViolation(HttpException e) {
@ -179,7 +168,7 @@ public class SolrSmokeTest implements ServletContextListener {
ss.warning(listener, "Can't connect to the Solr search engine. '"
+ e.getMessage() + "' is an unknown host."
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties.", e);
+ "runtime.properties.", e);
}
private void warnConnectionRefused(ConnectException e) {
@ -187,7 +176,7 @@ public class SolrSmokeTest implements ServletContextListener {
+ "The host refused the connection. "
+ "Is it possible that the port number is incorrect? "
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties.", e);
+ "runtime.properties.", e);
}
private void warnTransportError(IOException e) {

View file

@ -182,10 +182,10 @@ public class UpdatePermissionSetUris implements ServletContextListener {
Journal(ServletContext ctx) throws IOException {
String homeDirectoryPath = ConfigurationProperties.getBean(ctx)
.getProperty("vitro.home.directory");
.getProperty("vitro.home");
if (homeDirectoryPath == null) {
throw new IllegalStateException(
"No value found for vitro.home.directory");
"No value found for vitro.home");
}
File homeDirectory = new File(homeDirectoryPath);
confirmIsDirectory(homeDirectory);

View file

@ -61,35 +61,54 @@ public class DataGetterUtils {
*/
public static List<DataGetter> getDataGettersForPage(VitroRequest vreq, Model displayModel, String pageURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException {
//get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForPageURI( displayModel, pageURI);
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
List<String> dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForPage: " + dgList);
return dgList;
}
/**
* Get a list of DataGetter objects that are associated with a JAVA class.
* Get a list of DataGetter objects that are associated with a Vitro VClass.
* This allows the individual profile for an individual of a specific class to be returned .
*/
public static List<DataGetter> getDataGettersForClass( VitroRequest vreq, Model displayModel, String classURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
//get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForClassURI( displayModel, classURI);
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, classURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForClass: " + dgList);
return dgList;
}
/**
* Get a list of DataGetter objects that are associated with a Freemarker template.
* @param templateName a filename like "index.ftl", which will be used as a URI like "freemarker:index.ftl".
*/
public static List<DataGetter> getDataGettersForTemplate( VitroRequest vreq, Model displayModel, String templateName)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
String templateUri = "freemarker:" + templateName;
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, templateUri);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForTemplate '" + templateName + "': " + dgList);
return dgList;
}
/**
* Return a list of DataGetters from the list of URIs. Each DataGetter will be configured from information
* in the displayModel.
*
* Problems instantiating and configuring a particular DataGetter may result in an exception,
* or may just mean that there will be no entry in the result for that URI.
*
* May return an empty list, but will not return null.
*/
private static List<DataGetter> dataGettersForURIs(VitroRequest vreq, Model displayModel, List<String> dgUris)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
log.debug("getDataGettersForClass: " + dgList);
return dgList;
}
@ -103,7 +122,7 @@ public class DataGetterUtils {
* that does not implement the DataGetter interface.
*/
public static DataGetter dataGetterForURI(VitroRequest vreq, Model displayModel, String dataGetterURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException
{
//get java class for dataGetterURI
String dgClassName = getJClassForDataGetterURI(displayModel, dataGetterURI);
@ -180,47 +199,18 @@ public class DataGetterUtils {
}
private static List<String> getDataGetterURIsForPageURI(Model displayModel, String pageURI) {
private static List<String> getDataGetterURIsForAssociatedURI(Model displayModel, String associatedURI) {
String query = prefixes +
"SELECT ?dataGetter WHERE { ?pageURI display:hasDataGetter ?dataGetter. }";
Query dgForPageQuery = QueryFactory.create(query);
"SELECT ?dataGetter WHERE { ?associatedURI display:hasDataGetter ?dataGetter }";
Query dgForUriQuery = QueryFactory.create(query);
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("pageURI", ResourceFactory.createResource( pageURI ));
initialBindings.add("associatedURI", ResourceFactory.createResource( associatedURI ));
List<String> dgURIs = new ArrayList<String>();
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(dgForPageQuery,displayModel,initialBindings );
try{
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
Resource dg = soln.getResource("dataGetter");
if( dg != null && dg.getURI() != null){
dgURIs.add( dg.getURI());
}
}
}finally{ qexec.close(); }
}finally{ displayModel.leaveCriticalSection(); }
return dgURIs;
}
//Get data getters for a specific JAVA class - associates data getters with individuals for a specific JAVA class
private static List<String> getDataGetterURIsForClassURI(Model displayModel, String classURI) {
//Class URI will be substituted in so this is for a specific class uri
String query = prefixes +
"SELECT ?dataGetter WHERE { ?classURI display:hasDataGetter ?dataGetter }";
Query dgForPageQuery = QueryFactory.create(query);
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("classURI", ResourceFactory.createResource( classURI ));
List<String> dgURIs = new ArrayList<String>();
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(dgForPageQuery,displayModel,initialBindings );
QueryExecution qexec = QueryExecutionFactory.create(dgForUriQuery,displayModel,initialBindings );
try{
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
@ -233,6 +223,7 @@ public class DataGetterUtils {
}finally{ qexec.close(); }
}finally{ displayModel.leaveCriticalSection(); }
log.debug("Found " + dgURIs.size() +" DataGetter URIs for '" + associatedURI + "': " + dgURIs);
return dgURIs;
}

View file

@ -70,7 +70,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
configProps = ConfigurationProperties.getBean(ctx);
/*
* If OpenSocial is not configured in deploy.properties, skip the tests.
* If OpenSocial is not configured in runtime.properties, skip the tests.
*/
if (!configurationPresent()) {
ss.info(this, "The OpenSocial connection is not configured.");
@ -188,7 +188,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
}
/**
* Check that the Token Key file has been specified in deploy.properties,
* Check that the Token Key file has been specified in runtime.properties,
* and that it actually does exist.
*/
private void checkTokenKeyFile() {
@ -210,14 +210,14 @@ public class OpenSocialSmokeTests implements ServletContextListener {
}
/**
* Get the Token Service info from deploy.properties. It must be in the form
* Get the Token Service info from runtime.properties. It must be in the form
* of host:port, and may not refer to localhost.
*/
private void checkTokenServiceInfo() {
String tsInfo = configProps.getProperty(PROPERTY_SHINDIG_TOKEN_SERVICE);
if (StringUtils.isEmpty(tsInfo)) {
warnings.add(new Warning("There is no value for '"
+ PROPERTY_SHINDIG_TOKEN_SERVICE + "' in deploy.properties"));
+ PROPERTY_SHINDIG_TOKEN_SERVICE + "' in runtime.properties"));
return;
}
@ -278,7 +278,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
private static class NoSuchPropertyException extends Exception {
NoSuchPropertyException(String key) {
super("There is no value for '" + key + "' in deploy.properties");
super("There is no value for '" + key + "' in build.properties");
}
}