Merge branch 'maint-rel-1.6' of https://github.com/vivo-project/Vitro into maint-rel-1.6

This commit is contained in:
hudajkhan 2013-10-31 15:49:31 -04:00
commit 11a35739ae
86 changed files with 2050 additions and 1115 deletions

View file

@ -67,7 +67,7 @@
<h4>Vitro inside Tomcat</h4>
<p>
When you run the build script to compile and deploy Vitro
(see <a href="#deploy">installation step VI</a>, below),
(see <a href="#deploy">installation step V</a>, below),
the files will be deployed to a
directory inside Tomcat. This is the actual executing code for Vitro,
but you wont need to look at it or change it. If you need to change
@ -86,7 +86,7 @@
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
(see <a href="#runtime_properties">Step VI</a>, below), and you
must ensure that Tomcat has permission to read and write to this
directory when it runs.
</p>
@ -186,10 +186,10 @@
<a href="#build_properties">Specify build properties</a>
</li>
<li>
<a href="#runtime_properties">Specify runtime properties</a>
<a href="#deploy">Compile and deploy</a>
</li>
<li>
<a href="#deploy">Compile and deploy</a>
<a href="#runtime_properties">Specify runtime properties</a>
</li>
<li>
<a href="#tomcat_settings">Configure Tomcat</a>
@ -226,20 +226,19 @@
</p>
<ul>
<li>
Java (SE) 1.6 or higher, <a href="http://java.sun.com">http://java.sun.com</a>
(Not OpenJDK)
Java (SE) 1.7.x <a href="http://java.sun.com">http://java.sun.com</a>
<ul>
<li>VIVO has not been tested with OpenJDK</li>
</ul>
</li>
<li>
Apache Tomcat 6.x or higher, <a href="http://tomcat.apache.org">http://tomcat.apache.org</a>
Apache Tomcat 6.x or 7.x <a href="http://tomcat.apache.org">http://tomcat.apache.org</a>
</li>
<li>
Apache Ant 1.8 or higher, <a href="http://ant.apache.org">http://ant.apache.org</a>
</li>
<li>
MySQL 5.1 or higher*, <a href="http://www.mysql.com">http://www.mysql.com</a>
</li>
<li>
Apache Subversion 1.6.x or higher*, <a href="http://subversion.apache.org/">http://subversion.apache.org/</a>
MySQL 5.1 or higher, <a href="http://www.mysql.com">http://www.mysql.com</a>
</li>
</ul>
<p>
@ -320,8 +319,8 @@
<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>,
<a href="#deploy">Step V</a>. If you want to change these properties at
a later date, you will need to stop Tomcat, repeat <a href="#deploy">Step V</a>,
and restart Tomcat.
</p>
<p>
@ -394,22 +393,64 @@
</tbody>
</table>
<h3 id="runtime_properties">V. Specify runtime properties </h3>
<h3 id="deploy">V. Compile and deploy</h3>
<p>
In <a href="#build_properties">Step IV</a>, you defined the location of the Vitro home directory,
In <a href="#build_properties">Step IV</a>, you defined the location of the VIVO 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.
At the command line, change to the <code>webapp</code> directory inside the Vitro distribution
directory. Then type:
</p>
<pre> ant all<br> </pre>
<p>
to build Vitro and deploy to Tomcat's webapps directory.
</p>
<p>
The build script may run for as much as five minutes,
and creates more than 100 lines of output.
The process comprises several steps:
<ul>
<li>collecting the source files from the distribution directory,</li>
<li>compiling the Java source code,</li>
<li>compiling and running unit tests,</li>
<li>preparing the Solr search engine,</li>
<li>deploying Vitro and Solr to Tomcat.</li>
</ul>
</p>
<p>
The output of the build may include a variety of warning messages.
The Java compiler may warn of code that is outdated.
Unit tests may produce warning messages,
and some tests may be ignored if they do not produce consistent results.
</p>
<table align="center"><tr><td>
BUILD SUCCESSFUL<br>Total time: 1 minute 49 seconds
</td></tr></table>
<p>
If the output ends with a success message, the build was successful.
Proceed to the next step.
</p>
<table align="center"><tr><td>
BUILD FAILED<br>Total time: 35 seconds
</td></tr></table>
<p>
If the output ends with a failure message, the build has failed.
Find the cause of the failure, fix the problem, and run the script again.
</p>
<h3 id="runtime_properties">VI. Specify runtime properties </h3>
<p>
The build process in <a href="deploy">Step V</a> created a file called <code>example.runtime.properties</code>
in your Vitro home directory (<code>vitro.home</code> in the <code>build.properties</code> file).
Rename this file to <code>runtime.properties</code>, and
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>.
effect. You will not need to repeat <a href="#deploy">Step V</a>.
</p>
<p>
<em>Windows:</em>
@ -800,47 +841,6 @@
</tbody>
</table>
<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:
</p>
<pre> ant all<br> </pre>
<p>
to build Vitro and deploy to Tomcat's webapps directory.
</p>
<p>
The build script may run for as much as five minutes,
and creates more than 100 lines of output.
The process comprises several steps:
<ul>
<li>collecting the source files from the distribution directory,</li>
<li>compiling the Java source code,</li>
<li>compiling and running unit tests,</li>
<li>preparing the Solr search engine,</li>
<li>deploying Vitro and Solr to Tomcat.</li>
</ul>
</p>
<p>
The output of the build may include a variety of warning messages.
The Java compiler may warn of code that is outdated.
Unit tests may produce warning messages,
and some tests may be ignored if they do not produce consistent results.
</p>
<table align="center"><tr><td>
BUILD SUCCESSFUL<br>Total time: 1 minute 49 seconds
</td></tr></table>
<p>
If the output ends with a success message, the build was successful.
Proceed to the next step.
</p>
<table align="center"><tr><td>
BUILD FAILED<br>Total time: 35 seconds
</td></tr></table>
<p>
If the output ends with a failure message, the build has failed.
Find the cause of the failure, fix the problem, and run the script again.
</p>
<h3 id="tomcat_settings">VII. Configure Tomcat</h3>
<h4>Set JVM parameters</h4>
@ -921,8 +921,8 @@
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
proceed from <a href="#deploy">Step V</a>. If the problem is not serious, the
startup status page may offer a <code>continue</code> link which
will allow you to use VIVO in spite of the problems.
</p>
<p>

View file

@ -102,6 +102,24 @@
<target name="deployProperties" depends="buildProperties">
<fail unless="vitro.home" message="${build.properties.file} must contain a value for vitro.home" />
<fail unless="tomcat.home" message="${build.properties.file} must contain a value for tomcat.home" />
<fail>
<condition>
<not>
<available file="${tomcat.home}" />
</not>
</condition>
Tomcat home directory '${tomcat.home}' does not exist.
Check the value of 'tomcat.home' in your build.properties file.
</fail>
<fail>
<condition>
<not>
<available file="${tomcat.home}/webapps" />
</not>
</condition>
'${tomcat.home}' does not refer to a valid Tomcat instance: it has no 'webapps' sub-directory.
Check the value of 'tomcat.home' in your build.properties file."
</fail>
<property name="solr.home.dir" location="${vitro.home}/solr" />

View file

@ -126,10 +126,6 @@ submit_add_new_account = Añadir nueva cuenta
account_created = Su {0} cuenta ha sido creada.
account_created_subject = Su {0} cuenta ha sido creada.
account_created_email_html = @@file files/accountCreatedEmail.html
account_created_email_text = @@file files/accountCreatedEmail.txt
account_created_external_email_html = @@file files/accountCreatedExternalOnlyEmail.html
account_created_external_email_text = @@file files/accountCreatedExternalOnlyEmail.txt
confirm_delete_account_singular = ¿Está seguro de que desea eliminar esta cuenta?
confirm_delete_account_plural = ¿Está seguro de que desea eliminar estas cuentas?
@ -148,21 +144,11 @@ select_associated_profile = Seleccione el perfil asociado
create_associated_profile = Cree el perfil asociado
email_changed_subject = Su {0} cuenta de correo electrónico ha cambiado.
email_changed_html = @@file files/accountEmailChanged.html
email_changed_text = @@file files/accountEmailChanged.txt
create_your_password = Crea tu Contraseña
password_created_subject = Su {0} contraseña ha sido creado con éxito.
password_created_email_html = @@file files/passwordCreatedEmail.html
password_created_email_text = @@file files/passwordCreatedEmail.txt
password_reset_pending_subject = {0} restablecer solicitud de contraseña
password_reset_pending_email_html = @@file files/passwordResetPending.html
password_reset_pending_email_text = @@file files/passwordResetPending.txt
password_reset_complete_subject = Su {0} ha cambiado la contraseña.
password_reset_complete_email_html = @@file files/passwordResetComplete.html
password_reset_complete_email_text = @@file files/passwordResetComplete.txt
reset_your_password = Renovar su contraseña
first_time_login = Log Por primera vez en
@ -181,8 +167,6 @@ password_saved_please_login = Su contraseña ha sido guardada. Por favor, ingres
please_provide_contact_information = Por favor proporcione su información de contacto para terminar de crear la cuenta.
first_time_login_note = Nota: Un correo electrónico será enviado a la dirección indicada anteriormente notificar que una cuenta ha sido creada.
first_time_external_email_html = @@file files/accountFirstTimeExternal.html
first_time_external_email_text = @@file files/accountFirstTimeExternal.txt
myAccount_heading = Mi cuenta
myAccount_confirm_changes = Los cambios se han guardado.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,7 +11,6 @@ import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
@ -20,7 +19,6 @@ import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
@ -136,7 +134,8 @@ public class PolicyHelper {
.asResource().getURI());
} else {
action = new AddDataPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI());
subject.getURI(), predicate.getURI(), objectNode
.asLiteral().getString());
}
return isAuthorizedForActions(req, action);
}
@ -169,7 +168,8 @@ public class PolicyHelper {
.asResource().getURI());
} else {
action = new DropDataPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI());
subject.getURI(), predicate.getURI(), objectNode
.asLiteral().getString());
}
return isAuthorizedForActions(req, action);
}

View file

@ -16,15 +16,17 @@ public abstract class AbstractDataPropertyStatementAction extends
private final String subjectUri;
private final String predicateUri;
private final Property predicate;
private final String dataValue;
public AbstractDataPropertyStatementAction(OntModel ontModel,
String subjectUri, String predicateUri) {
String subjectUri, String predicateUri, String dataValue) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
this.dataValue = dataValue;
}
public AbstractDataPropertyStatementAction(OntModel ontModel,
@ -36,12 +38,14 @@ public abstract class AbstractDataPropertyStatementAction extends
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
this.dataValue = dps.getData();
}
public String getSubjectUri() {
return subjectUri;
}
@Override
public Property getPredicate() {
return predicate;
}

View file

@ -13,8 +13,8 @@ public class AddDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public AddDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
String predicateUri, String dataValue) {
super(ontModel, subjectUri, predicateUri, dataValue);
}
public AddDataPropertyStatement(OntModel ontModel, DataPropertyStatement dps) {

View file

@ -14,8 +14,8 @@ public class DropDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public DropDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
String predicateUri, String dataValue) {
super(ontModel, subjectUri, predicateUri, dataValue);
}
public DropDataPropertyStatement(OntModel ontModel,

View file

@ -12,8 +12,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
public class EditDataPropertyStatement extends
AbstractDataPropertyStatementAction {
public EditDataPropertyStatement(OntModel ontModel, String subjectUri,
String predicateUri) {
super(ontModel, subjectUri, predicateUri);
String predicateUri, String dataValue) {
super(ontModel, subjectUri, predicateUri, dataValue);
}
public EditDataPropertyStatement(OntModel ontModel,

View file

@ -34,6 +34,13 @@ public interface Individual extends ResourceBean, Comparable<Individual> {
List<ObjectProperty> getObjectPropertyList();
void setPropertyList(List<ObjectProperty> propertyList);
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
List<ObjectProperty> getPopulatedObjectPropertyList();
void setPopulatedObjectPropertyList(List<ObjectProperty> propertyList);

View file

@ -22,7 +22,7 @@ import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
* a class representing an object property
*
*/
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable
{
private static final Log log = LogFactory.getLog(ObjectProperty.class.getName());
@ -610,6 +610,55 @@ public class ObjectProperty extends Property implements Comparable<ObjectPropert
"selectFromExisting" + getSelectFromExisting() + "\n\t" +
"offerCreateNewOption" + getOfferCreateNewOption() + "\n\t" +
"** object property statements: " + list + "\n";
}
@Override
public ObjectProperty clone()
{
ObjectProperty clone = new ObjectProperty();
clone.setAddLinkSuppressed(this.isAddLinkSuppressed());
clone.setCollateBySubclass(this.getCollateBySubclass());
clone.setCustomEntryForm(this.getCustomEntryForm());
clone.setDeleteLinkSuppressed(this.isDeleteLinkSuppressed());
clone.setDescription(this.getDescription());
clone.setDomainDisplayLimit(this.getDomainDisplayLimitInteger());
clone.setDomainDisplayTier(this.getDomainDisplayTier());
clone.setDomainEntitySortDirection(this.getDomainEntitySortDirection());
clone.setDomainEntityURI(this.getDomainEntityURI());
clone.setDomainPublic(this.getDomainPublic());
clone.setDomainVClass(this.getDomainVClass());
clone.setDomainVClassURI(this.getDomainVClassURI());
clone.setEditLinkSuppressed(this.isEditLinkSuppressed());
clone.setExample(this.getExample());
clone.setFunctional(this.getFunctional());
clone.setGroupURI(this.getGroupURI());
clone.setHiddenFromDisplayBelowRoleLevel(this.getHiddenFromDisplayBelowRoleLevel());
clone.setInverseFunctional(this.getInverseFunctional());
clone.setLabel(this.getLabel());
clone.setLocalName(this.getLocalName());
clone.setLocalNameInverse(this.getLocalNameInverse());
clone.setLocalNameWithPrefix(this.getLocalNameWithPrefix());
clone.setNamespace(this.getNamespace());
clone.setNamespaceInverse(this.getNamespaceInverse());
clone.setObjectIndividualSortPropertyURI(this.getObjectIndividualSortPropertyURI());
clone.setOfferCreateNewOption(this.getOfferCreateNewOption());
clone.setParentURI(this.getParentURI());
clone.setPickListName(this.getPickListName());
clone.setProhibitedFromUpdateBelowRoleLevel(this.getProhibitedFromUpdateBelowRoleLevel());
clone.setPublicDescription(this.getPublicDescription());
clone.setRangeDisplayLimit(this.getRangeDisplayLimit());
clone.setRangeDisplayTier(this.getRangeDisplayTier());
clone.setRangeEntitySortDirection(this.getRangeEntitySortDirection());
clone.setRangeEntityURI(this.getRangeEntityURI());
clone.setRangePublic(this.getRangePublic());
clone.setRangeVClass(this.getRangeVClass());
clone.setRangeVClassURI(this.getRangeVClassURI());
clone.setSelectFromExisting(this.getSelectFromExisting());
clone.setStubObjectRelation(this.getStubObjectRelation());
clone.setSymmetric(this.getSymmetric());
clone.setTransitive(this.getTransitive());
clone.setURI(this.getURI());
clone.setURIInverse(this.getURIInverse());
return clone;
}
}

View file

@ -13,10 +13,7 @@ import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -25,9 +22,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ExceptionResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
@ -94,16 +90,15 @@ public class IndividualListController extends FreemarkerHttpServlet {
String alpha = getAlphaParameter(vreq);
int page = getPageParameter(vreq);
Map<String,Object> map = getResultsForVClass(
IndividualListResults vcResults = getResultsForVClass(
vclass.getURI(),
page,
alpha,
vreq.getWebappDaoFactory().getIndividualDao(),
getServletContext());
body.putAll(map);
body.putAll(vcResults.asFreemarkerMap());
@SuppressWarnings("unchecked")
List<Individual> inds = (List<Individual>)map.get("entities");
List<Individual> inds = vcResults.getEntities();
List<ListedIndividual> indsTm = new ArrayList<ListedIndividual>();
if (inds != null) {
for ( Individual ind : inds ) {
@ -154,13 +149,12 @@ public class IndividualListController extends FreemarkerHttpServlet {
return SolrQueryUtils.getPageParameter(request);
}
public static Map<String,Object> getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
public static IndividualListResults getResultsForVClass(String vclassURI, int page, String alpha, IndividualDao indDao, ServletContext context)
throws SearchException{
Map<String,Object> rvMap = new HashMap<String,Object>();
try{
List<String> classUris = Collections.singletonList(vclassURI);
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(classUris, alpha, page, INDIVIDUALS_PER_PAGE, context, indDao);
rvMap = getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
return getResultsForVClassQuery(results, page, INDIVIDUALS_PER_PAGE, alpha);
} catch (SolrServerException e) {
String msg = "An error occurred retrieving results for vclass query";
log.error(msg, e);
@ -168,31 +162,29 @@ public class IndividualListController extends FreemarkerHttpServlet {
throw new SearchException(msg);
} catch(Throwable th) {
log.error("An error occurred retrieving results for vclass query", th);
return IndividualListResults.EMPTY;
}
return rvMap;
}
public static Map<String,Object> getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
Map<String,Object> rvMap = new HashMap<String,Object>();
public static IndividualListResults getResultsForVClassIntersections(List<String> vclassURIs, int page, int pageSize, String alpha, IndividualDao indDao, ServletContext context) {
try{
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteVClassQuery(vclassURIs, alpha, page, pageSize, context, indDao);
rvMap = getResultsForVClassQuery(results, page, pageSize, alpha);
return getResultsForVClassQuery(results, page, pageSize, alpha);
} catch(Throwable th) {
log.error("Error retrieving individuals corresponding to intersection multiple classes." + vclassURIs.toString(), th);
return IndividualListResults.EMPTY;
}
return rvMap;
}
public static Map<String,Object> getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao, ServletContext context) {
Map<String,Object> rvMap = new HashMap<String,Object>();
public static IndividualListResults getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao, ServletContext context) {
try{
List<String> classUris = Collections.singletonList(vclassURI);
IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteRandomVClassQuery(classUris, page, pageSize, context, indDao);
rvMap = getResultsForVClassQuery(results, page, pageSize, "");
return getResultsForVClassQuery(results, page, pageSize, "");
} catch(Throwable th) {
log.error("An error occurred retrieving random results for vclass query", th);
return IndividualListResults.EMPTY;
}
return rvMap;
}
//TODO: Get rid of this method and utilize SolrQueryUtils - currently appears to be referenced
@ -201,24 +193,13 @@ public class IndividualListController extends FreemarkerHttpServlet {
return SolrQueryUtils.getIndividualCount(vclassUris, indDao, context);
}
private static Map<String,Object> getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
Map<String,Object> rvMap = new HashMap<String,Object>();
private static IndividualListResults getResultsForVClassQuery(IndividualListQueryResults results, int page, int pageSize, String alpha) {
long hitCount = results.getHitCount();
if ( hitCount > pageSize ){
rvMap.put("showPages", Boolean.TRUE);
List<PageRecord> pageRecords = makePagesList(hitCount, pageSize, page);
rvMap.put("pages", pageRecords);
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, true, makePagesList(hitCount, pageSize, page));
}else{
rvMap.put("showPages", Boolean.FALSE);
rvMap.put("pages", Collections.emptyList());
return new IndividualListResults(hitCount, results.getIndividuals(), alpha, false, Collections.<PageRecord>emptyList());
}
rvMap.put("alpha",alpha);
rvMap.put("totalCount", hitCount);
rvMap.put("entities", results.getIndividuals());
return rvMap;
}

View file

@ -4,11 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.individual;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -22,18 +17,13 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
*/
public class IndividualRequestAnalysisContextImpl implements
IndividualRequestAnalysisContext {
private static final Log log = LogFactory
.getLog(IndividualRequestAnalysisContextImpl.class);
private final VitroRequest vreq;
private final ServletContext ctx;
private final VitroRequest vreq;
private final WebappDaoFactory wadf;
private final IndividualDao iDao;
public IndividualRequestAnalysisContextImpl(VitroRequest vreq) {
this.vreq = vreq;
this.ctx = vreq.getSession().getServletContext();
this.vreq = vreq;
this.wadf = vreq.getWebappDaoFactory();
this.iDao = wadf.getIndividualDao();
}

View file

@ -0,0 +1,48 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.individuallist;
import java.util.Collection;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
/**
* Wrap an Individual in a JSON object for display by the script.
*
* This will be overridden in VIVO so we can have more info in the display.
*/
public class IndividualJsonWrapper {
static JSONObject packageIndividualAsJson(VitroRequest vreq, Individual ind)
throws JSONException {
// need an unfiltered dao to get firstnames and lastnames
WebappDaoFactory fullWdf = vreq.getUnfilteredWebappDaoFactory();
JSONObject jo = new JSONObject();
jo.put("URI", ind.getURI());
jo.put("label", ind.getRdfsLabel());
jo.put("name", ind.getName());
jo.put("thumbUrl", ind.getThumbUrl());
jo.put("imageUrl", ind.getImageUrl());
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
jo.put("mostSpecificTypes", getMostSpecificTypes(ind, fullWdf));
return jo;
}
public static Collection<String> getMostSpecificTypes(
Individual individual, WebappDaoFactory wdf) {
ObjectPropertyStatementDao opsDao = wdf.getObjectPropertyStatementDao();
Map<String, String> mostSpecificTypes = opsDao
.getMostSpecificTypesInClassgroupsForIndividual(individual
.getURI());
return mostSpecificTypes.values();
}
}

View file

@ -0,0 +1,87 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.individuallist;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
/**
* These are the paged results of a query for Individuals.
*
* The criteria for the search are the index of the desired page, the number of
* results displayed on each page, and an optional initial letter to search
* against.
*
* By the time this is built, the results have already been partially processed.
* A list of PageRecord object is included, with values that the GUI can use to
* create Alphabetical links. Maybe this processing should have been done later.
* Maybe it should have been left to the GUI.
*/
public class IndividualListResults {
private static final Log log = LogFactory
.getLog(IndividualListResults.class);
public static final IndividualListResults EMPTY = new IndividualListResults();
private final long totalCount;
private final List<Individual> entities;
private final String alpha;
private final boolean showPages;
private final List<PageRecord> pages;
public IndividualListResults(long totalCount, List<Individual> entities,
String alpha, boolean showPages, List<PageRecord> pages) {
this.totalCount = totalCount;
this.entities = entities;
this.alpha = alpha;
this.showPages = showPages;
this.pages = pages;
}
private IndividualListResults() {
this(0L, Collections.<Individual> emptyList(), "", false, Collections
.<PageRecord> emptyList());
}
public long getTotalCount() {
return totalCount;
}
public String getAlpha() {
return alpha;
}
public List<Individual> getEntities() {
return entities;
}
public List<PageRecord> getPages() {
return pages;
}
public boolean isShowPages() {
return showPages;
}
/**
* Some controllers put this data directly into the Freemarker body map.
* Others wrap it in JSON.
*/
public Map<String, Object> asFreemarkerMap() {
Map<String, Object> m = new HashMap<>();
m.put("showPages", showPages);
m.put("pages", pages);
m.put("alpha", alpha);
m.put("totalCount", totalCount);
m.put("entities", entities);
return m;
}
}

View file

@ -0,0 +1,148 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.individuallist;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
/**
* Utility methods for procesing the paged results of a query for a list of Individuals.
*
* Right now, there is only a method to wrap the results in Json.
*/
public class IndividualListResultsUtils {
private static final Log log = LogFactory
.getLog(IndividualListResultsUtils.class);
/**
* Process results related to VClass or vclasses. Handles both single and
* multiple vclasses being sent.
*/
public static JSONObject wrapIndividualListResultsInJson(IndividualListResults results, VitroRequest vreq,
boolean multipleVclasses) {
JSONObject rObj = new JSONObject();
if (log.isDebugEnabled()) {
dumpParametersFromRequest(vreq);
}
try {
List<VClass> vclasses = buildListOfRequestedVClasses(vreq);
VClass vclass = null;
// if single vclass expected, then include vclass.
// This relates to what the expected behavior is, not size of list
if (!multipleVclasses) {
vclass = vclasses.get(0);
// currently used for ClassGroupPage
} else {
// For now, utilize very last VClass (assume that that is the one to be employed)
// TODO: Find more general way of dealing with this: put multiple ones in?
vclass = vclasses.get(vclasses.size() - 1);
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr).put("name",vclass.getName()));
}
rObj.put("vclass", packageVClassAsJson(vclass));
rObj.put("totalCount", results.getTotalCount());
rObj.put("alpha", results.getAlpha());
rObj.put("individuals", packageIndividualsAsJson(vreq, results.getEntities()));
rObj.put("pages", packagePageRecordsAsJson(results.getPages()));
rObj.put("letters", packageLettersAsJson());
} catch (Exception ex) {
log.error("Error occurred in processing JSON object", ex);
}
return rObj;
}
private static List<VClass> buildListOfRequestedVClasses(VitroRequest vreq)
throws Exception {
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if (ArrayUtils.isEmpty(vitroClassIdStr)) {
log.error("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<VClass> list = new ArrayList<>();
for (String vclassId : vitroClassIdStr) {
VClass vclass = vreq.getWebappDaoFactory().getVClassDao()
.getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception("Class " + vclassId + " not found");
}
list.add(vclass);
}
return list;
}
private static JSONObject packageVClassAsJson(VClass vclass)
throws JSONException {
JSONObject jvclass = new JSONObject();
jvclass.put("URI", vclass.getURI());
jvclass.put("name", vclass.getName());
return jvclass;
}
private static JSONArray packageLettersAsJson() throws JSONException,
UnsupportedEncodingException {
List<String> letters = Controllers.getLetters();
JSONArray jletters = new JSONArray();
for (String s : letters) {
JSONObject jo = new JSONObject();
jo.put("text", s);
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
jletters.put(jo);
}
return jletters;
}
private static JSONArray packagePageRecordsAsJson(List<PageRecord> pages)
throws JSONException {
JSONArray wpages = new JSONArray();
for (PageRecord pr : pages) {
JSONObject p = new JSONObject();
p.put("text", pr.text);
p.put("param", pr.param);
p.put("index", pr.index);
wpages.put(p);
}
return wpages;
}
private static JSONArray packageIndividualsAsJson(VitroRequest vreq,
List<Individual> inds) throws JSONException {
log.debug("Number of individuals returned from request: " + inds.size());
JSONArray jInds = new JSONArray();
for (Individual ind : inds) {
jInds.put(IndividualJsonWrapper.packageIndividualAsJson(vreq, ind));
}
return jInds;
}
private static void dumpParametersFromRequest(VitroRequest vreq) {
Map<String, String[]> pMap = vreq.getParameterMap();
for (String name : pMap.keySet()) {
for (String value : pMap.get(name)) {
log.debug("value for " + name + ": '" + value + "'");
}
}
}
}

View file

@ -3,11 +3,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@ -18,18 +15,15 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResultsUtils;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
@ -94,29 +88,28 @@ public class JsonServlet extends VitroHttpServlet {
List<String> vclassURIs = Collections.singletonList(vclassURI);
VitroRequest vreq = new VitroRequest(req);
Map<String, Object> map = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
IndividualListResults vcResults = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
//last parameter indicates single vclass instead of multiple vclasses
return processVclassResultsJSON(map, vreq, false);
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, false);
}
public static JSONObject getSolrIndividualsByVClasses(List<String> vclassURIs, HttpServletRequest req, ServletContext context) throws Exception {
VitroRequest vreq = new VitroRequest(req);
log.debug("Retrieve solr results for vclasses" + vclassURIs.toString());
Map<String, Object> map = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
log.debug("Results returned from Solr for " + vclassURIs.toString() + " are of size " + map.size());
IndividualListResults vcResults = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
log.debug("Results returned from Solr for " + vclassURIs.toString() + " are of size " + vcResults.getTotalCount());
return processVclassResultsJSON(map, vreq, true);
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, true);
}
//Including version for Solr query for Vclass Intersections
private static Map<String,Object> getSolrVClassIntersectionResults(List<String> vclassURIs, VitroRequest vreq, ServletContext context){
private static IndividualListResults getSolrVClassIntersectionResults(List<String> vclassURIs, VitroRequest vreq, ServletContext context){
log.debug("Retrieving Solr intersection results for " + vclassURIs.toString());
String alpha = IndividualListController.getAlphaParameter(vreq);
int page = IndividualListController.getPageParameter(vreq);
log.debug("Alpha and page parameters are " + alpha + " and " + page);
Map<String,Object> map = null;
try {
map = IndividualListController.getResultsForVClassIntersections(
return IndividualListController.getResultsForVClassIntersections(
vclassURIs,
page, INDIVIDUALS_PER_PAGE,
alpha,
@ -124,23 +117,10 @@ public class JsonServlet extends VitroHttpServlet {
context);
} catch(Exception ex) {
log.error("Error in retrieval of search results for VClass " + vclassURIs.toString(), ex);
return IndividualListResults.EMPTY;
}
return map;
}
// Map given to process method includes the actual individuals returned from the search
// public static JSONObject processVClassResults(Map<String, Object> map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{
// JSONObject rObj = processVclassResultsJSON(map, vreq, multipleVclasses);
// return rObj;
// }
public static Collection<String> getMostSpecificTypes(Individual individual, WebappDaoFactory wdf) {
ObjectPropertyStatementDao opsDao = wdf.getObjectPropertyStatementDao();
Map<String, String> mostSpecificTypes = opsDao.getMostSpecificTypesInClassgroupsForIndividual(individual.getURI());
return mostSpecificTypes.values();
}
public static String getDataPropertyValue(Individual ind, DataProperty dp, WebappDaoFactory wdf){
String value = ind.getDataValue(dp.getURI());
if( value == null || value.isEmpty() )
@ -152,21 +132,20 @@ public class JsonServlet extends VitroHttpServlet {
public static JSONObject getRandomSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
VitroRequest vreq = new VitroRequest(req);
Map<String, Object> map = getRandomSolrVClassResults(vclassURI, vreq, context);
IndividualListResults vcResults = getRandomSolrVClassResults(vclassURI, vreq, context);
//last parameter indicates single vclass instead of multiple vclasses
return processVclassResultsJSON(map, vreq, false);
return IndividualListResultsUtils.wrapIndividualListResultsInJson(vcResults, vreq, false);
}
//Including version for Random Solr query for Vclass Intersections
private static Map<String,Object> getRandomSolrVClassResults(String vclassURI, VitroRequest vreq, ServletContext context){
private static IndividualListResults getRandomSolrVClassResults(String vclassURI, VitroRequest vreq, ServletContext context){
log.debug("Retrieving random Solr intersection results for " + vclassURI);
int page = IndividualListController.getPageParameter(vreq);
int pageSize = Integer.parseInt(vreq.getParameter("pageSize"));
log.debug("page and pageSize parameters = " + page + " and " + pageSize);
Map<String,Object> map = null;
try {
map = IndividualListController.getRandomResultsForVClass(
return IndividualListController.getRandomResultsForVClass(
vclassURI,
page,
pageSize,
@ -174,126 +153,8 @@ public class JsonServlet extends VitroHttpServlet {
context);
} catch(Exception ex) {
log.error("Error in retrieval of search results for VClass " + vclassURI, ex);
return IndividualListResults.EMPTY;
}
return map;
}
/**
* Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent.
*/
public static JSONObject processVclassResultsJSON(Map<String, Object> map, VitroRequest vreq, boolean multipleVclasses) {
JSONObject rObj = new JSONObject();
VClass vclass=null;
try {
// Properties from ontologies used by VIVO - should not be in vitro
DataProperty fNameDp = (new DataProperty());
fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName");
DataProperty lNameDp = (new DataProperty());
lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName");
DataProperty preferredTitleDp = (new DataProperty());
preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle");
if( log.isDebugEnabled() ){
@SuppressWarnings("unchecked")
Enumeration<String> e = vreq.getParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
log.debug("parameter: " + name);
for( String value : vreq.getParameterValues(name) ){
log.debug("value for " + name + ": '" + value + "'");
}
}
}
//need an unfiltered dao to get firstnames and lastnames
WebappDaoFactory fullWdf = vreq.getUnfilteredWebappDaoFactory();
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception ("Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
//if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list
if(!multipleVclasses) {
//currently used for ClassGroupPage
rObj.put("vclass",
new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
} else {
//For now, utilize very last VClass (assume that that is the one to be employed)
//TODO: Find more general way of dealing with this
//put multiple ones in?
if(vclassIds.size() > 0) {
int numberVClasses = vclassIds.size();
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(numberVClasses - 1));
rObj.put("vclass", new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
}
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr)
// .put("name",vclass.getName()));
}
if (vclass != null) {
rObj.put("totalCount", map.get("totalCount"));
rObj.put("alpha", map.get("alpha"));
List<Individual> inds = (List<Individual>)map.get("entities");
log.debug("Number of individuals returned from request: " + inds.size());
JSONArray jInds = new JSONArray();
for(Individual ind : inds ){
JSONObject jo = new JSONObject();
jo.put("URI", ind.getURI());
jo.put("label",ind.getRdfsLabel());
jo.put("name",ind.getName());
jo.put("thumbUrl", ind.getThumbUrl());
jo.put("imageUrl", ind.getImageUrl());
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
jInds.put(jo);
}
rObj.put("individuals", jInds);
JSONArray wpages = new JSONArray();
//Made sure that PageRecord here is SolrIndividualListController not IndividualListController
List<PageRecord> pages = (List<PageRecord>)map.get("pages");
for( PageRecord pr: pages ){
JSONObject p = new JSONObject();
p.put("text", pr.text);
p.put("param", pr.param);
p.put("index", pr.index);
wpages.put( p );
}
rObj.put("pages",wpages);
JSONArray jletters = new JSONArray();
List<String> letters = Controllers.getLetters();
for( String s : letters){
JSONObject jo = new JSONObject();
jo.put("text", s);
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
jletters.put( jo );
}
rObj.put("letters", jletters);
}
} catch(Exception ex) {
log.error("Error occurred in processing JSON object", ex);
}
return rObj;
}
}

View file

@ -16,6 +16,18 @@ public interface ObjectPropertyDao extends PropertyDao {
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI);
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI);
/**
* Use this method to supply a base ObjectProperty whose fields will be updated
* as necessary to correspond to the configuration for the specified Domain
* and Range.
* @param objectPropertyURI
* @param domainURI
* @param rangeURI
* @param base
* @return ObjectProperty
*/
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI, ObjectProperty base);
public List <ObjectProperty> getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements);
@ -54,8 +66,22 @@ public interface ObjectPropertyDao extends PropertyDao {
List <ObjectProperty> getRootObjectProperties();
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
public List<ObjectProperty> getObjectPropertyList(Individual subject);
/**
* Returns a list of ObjectProperty objects for which statements exist about
* the individual. Note that this method now returns multiple copies of
* a given predicate, with the rangeVClassURI changed to indicate the distinct
* types of the related objects. This supports finding the approriate list
* views for the "faux" qualified properties.
*/
public List<ObjectProperty> getObjectPropertyList(String subjectUri);
public String getCustomListViewConfigFileName(ObjectProperty objectProperty);

View file

@ -5,14 +5,20 @@ package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openjena.atlas.lib.Pair;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
public class WebappDaoFactoryConfig {
private List<String> preferredLanguages;
private String defaultNamespace;
private Set<String> nonUserNamespaces;
private boolean isUnderlyingStoreReasoned = false;
public Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap;
public WebappDaoFactoryConfig() {
preferredLanguages = Arrays.asList("en-US", "en", "EN");
@ -53,4 +59,13 @@ public class WebappDaoFactoryConfig {
return this.isUnderlyingStoreReasoned;
}
public Map<Pair<String,Pair<ObjectProperty, String>>, String> getCustomListViewConfigFileMap() {
return this.getCustomListViewConfigFileMap();
}
public void setCustomListViewConfigFileMap(
Map<Pair<String,Pair<ObjectProperty, String>>, String> map) {
this.customListViewConfigFileMap = map;
}
}

View file

@ -54,6 +54,11 @@ class ObjectPropertyDaoFiltering extends BaseFiltering implements ObjectProperty
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
}
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI, ObjectProperty base) {
ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIs(objectPropertyURI, domainURI, rangeURI, base);
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
}
public List<ObjectPropertyStatement> getStatementsUsingObjectProperty(ObjectProperty op) {
return ObjectPropertyStatementDaoFiltering.filterAndWrapList(innerObjectPropertyDao.getStatementsUsingObjectProperty(op),filters);
}

View file

@ -45,15 +45,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class DataPropertyDaoJena extends PropertyDaoJena implements
DataPropertyDao {
@ -71,9 +70,10 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
}
public DataPropertyDaoJena(DatasetWrapperFactory dwf,
public DataPropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(dwf, wadf);
super(rdfService, dwf, wadf);
}
public void deleteDataProperty(DataProperty dtp) {
@ -672,7 +672,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
PREFIXES + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?property a owl:DatatypeProperty . \n" +
//" ?property a owl:DatatypeProperty . \n" +
" FILTER ( \n" +
" isLiteral(?object) && \n" +
" ( !regex(str(?property), \"^" + VitroVocabulary.PUBLIC + "\" )) && \n" +
@ -708,7 +708,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
}
log.debug("Data property query string:\n" + query);
ResultSet results = getPropertyQueryResults(query);
ResultSet results = getPropertyQueryResults(queryString);
List<DataProperty> properties = new ArrayList<DataProperty>();
while (results.hasNext()) {
QuerySolution sol = results.next();

View file

@ -13,11 +13,13 @@ import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openjena.atlas.lib.Pair;
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.ontology.ConversionException;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.ontology.ProfileException;
@ -28,7 +30,6 @@ import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
@ -37,30 +38,31 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.expr.NodeValue;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.sdb.util.Pair;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectPropertyDao {
private static final Log log = LogFactory.getLog(ObjectPropertyDaoJena.class.getName());
public ObjectPropertyDaoJena(DatasetWrapperFactory dwf,
public ObjectPropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
Map<Pair<String,Pair<ObjectProperty, String>>, String>
customListViewConfigFileMap,
WebappDaoFactoryJena wadf) {
super(dwf, wadf);
super(rdfService, dwf, wadf);
this.customListViewConfigFileMap = customListViewConfigFileMap;
}
@Override
@ -69,7 +71,6 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
public void deleteObjectProperty(String propertyURI) {
OntProperty p = getOntModel().getOntProperty(propertyURI);
ObjectProperty op = new ObjectProperty();
op.setURI(propertyURI);
deleteObjectProperty(op);
@ -269,22 +270,35 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
public ObjectProperty getObjectPropertyByURI(String propertyURI) {
long start = System.currentTimeMillis();
if( propertyURI == null ) return null;
getOntModel().enterCriticalSection(Lock.READ);
OntModel ontModel = getOntModel();
OntModel localModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
ontModel.enterCriticalSection(Lock.READ);
try {
OntProperty op = getOntModel().getObjectProperty(propertyURI);
localModel.add(ontModel.listStatements(ontModel.getResource(propertyURI), null, (RDFNode) null));
OntProperty op = localModel.getObjectProperty(propertyURI);
return propertyFromOntProperty(op);
} finally {
getOntModel().leaveCriticalSection();
ontModel.leaveCriticalSection();
}
}
public ObjectProperty getObjectPropertyByURIs(String propertyURI, String domainURI, String rangeURI) {
public ObjectProperty getObjectPropertyByURIs(String propertyURI,
String domainURI, String rangeURI) {
return getObjectPropertyByURIs(propertyURI, domainURI, rangeURI, null);
}
public ObjectProperty getObjectPropertyByURIs(String propertyURI,
String domainURI, String rangeURI, ObjectProperty base) {
if(log.isDebugEnabled()) {
log.debug("Getting " + propertyURI + " with domain " + domainURI + " and range " + rangeURI);
}
ObjectProperty op = getObjectPropertyByURI(propertyURI);
long start = System.currentTimeMillis();
ObjectProperty op = (base != null) ? base : getObjectPropertyByURI(propertyURI);
if (op == null || rangeURI == null) {
return op;
}
@ -293,7 +307,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel " +
"SELECT ?range ?rangeRoot ?label ?group ?customForm ?displayRank ?displayLevel " +
" ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" ?collateBySubclass ?displayLimit ?individualSortProperty \n" +
" ?entitySortDirection ?selectFromExisting ?offerCreateNew \n" +
@ -308,7 +322,8 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (rangeURI != null) {
propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n";
};
propQuery += " ?context config:hasConfiguration ?configuration . \n" +
propQuery += " OPTIONAL { ?context config:qualifiedByRoot ?rangeRoot } \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?configuration config:propertyGroup ?group } \n" +
" OPTIONAL { ?configuration config:displayName ?label } \n" +
@ -334,6 +349,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
ResultSet rs = qe.execSelect();
if (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
// This is a bit of hack, used for things where the type of the
// immediately-related object ("root," for lack of a better term)
// is important to record but not the type directly associated with
// a configuration
Resource rangeRootRes = qsoln.getResource("rangeRoot");
if (rangeRootRes != null) {
// reusing this obsolete field for now
op.setRangeEntityURI(rangeRootRes.getURI());
}
Resource groupRes = qsoln.getResource("group");
if (groupRes != null) {
op.setGroupURI(groupRes.getURI());
@ -407,7 +431,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
} finally {
qe.close();
}
}
return op;
}
@ -918,24 +942,30 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
"?property = vitro:additionalLink ||" +
"!regex(str(?property), \"^http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" ))");
PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && ");
}
}
protected static final String OBJECT_PROPERTY_QUERY_STRING =
PREFIXES + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
"SELECT DISTINCT ?property ?objType WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?object a ?objType . \n" +
// " ?property a owl:ObjectProperty . \n" +
" FILTER ( \n" +
" isURI(?object) && \n" +
PROPERTY_FILTERS + "\n" +
" ) \n" +
"}";
"} ORDER BY ?property ?objType";
@Override
public List<ObjectProperty> getObjectPropertyList(Individual subject) {
return getObjectPropertyList(subject.getURI());
}
// Returns a list of ObjectProperty objects for which statements exist about
// the individual. Note that this method now returns additional copies of
// a given predicate, with the rangeVClassURI changed to indicate the distinct
// types of the related objects. This supports finding the approriate list
// views for the "faux" qualified properties.
@Override
public List<ObjectProperty> getObjectPropertyList(String subjectUri) {
@ -954,15 +984,35 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
}
log.debug("Object property query:\n" + query);
ResultSet results = getPropertyQueryResults(query);
ObjectProperty propRegister = new ObjectProperty();
propRegister.setURI("");
ResultSet results = getPropertyQueryResults(queryString);
List<ObjectProperty> properties = new ArrayList<ObjectProperty>();
while (results.hasNext()) {
QuerySolution soln = results.next();
Resource resource = soln.getResource("property");
String uri = resource.getURI();
log.debug("Found populated object property " + uri);
ObjectProperty property = getObjectPropertyByURI(uri);
Resource objType = soln.getResource("objType");
String objTypeUri = objType.getURI();
log.debug("Found populated object property " + uri +
" with object type " + objType);
ObjectProperty property = null;
if (uri.equals(propRegister.getURI())) {
property = propRegister.clone();
} else {
property = getObjectPropertyByURI(uri);
if (property != null) {
propRegister = property;
// add canonical instance of the property first in the list
// before the range-changed versions
properties.add(property);
// isolate the canonical prop from what's about to happen next
property = property.clone();
}
}
if (property != null) {
property.setRangeVClassURI(objTypeUri);
properties.add(property);
}
}
@ -998,12 +1048,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
// Map key is inner pair of object property and range class URI,
// with first member of outer pair being a domain class URI.
// If domain or range is unspecified, OWL.Thing.getURI() is used in the key.
Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap = null;
Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap;
@Override
public String getCustomListViewConfigFileName(ObjectProperty op) {
if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
}
if (customListViewConfigFileMap.isEmpty()) {
long start = System.currentTimeMillis();
OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
@ -1036,10 +1089,19 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
domainUri, new Pair<ObjectProperty, String>(
prop, rangeUri)), filename);
}
}
}
// If there are no custom list views, put a bogus entry in the map
// to avoid further recomputation
if (customListViewConfigFileMap.isEmpty()) {
ObjectProperty bottom = new ObjectProperty();
bottom.setURI(OWL.NS + "bottomObjectProperty");
customListViewConfigFileMap.put(
new Pair<String,Pair<ObjectProperty,String>>(
null, new Pair<ObjectProperty, String>(
bottom, null)), "nothing");
}
qexec.close();
}
}
String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<String, Pair<ObjectProperty, String>>(op.getDomainVClassURI(), new Pair<ObjectProperty,String>(op, op.getRangeVClassURI())));
if (customListViewConfigFileName == null) {
log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI() + " and domain " + op.getDomainVClassURI());

View file

@ -11,7 +11,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -25,6 +24,7 @@ import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
@ -35,6 +35,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
@ -46,6 +47,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements ObjectPropertyStatementDao {
@ -92,7 +94,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
else {
Map<String, ObjectProperty> uriToObjectProperty = new HashMap<String,ObjectProperty>();
ObjectPropertyDaoJena opDaoJena = new ObjectPropertyDaoJena(dwf, getWebappDaoFactory());
ObjectPropertyDaoJena opDaoJena = (ObjectPropertyDaoJena) getWebappDaoFactory().getObjectPropertyDao();
//new ObjectPropertyDaoJena(rdfService, dwf, getWebappDaoFactory());
OntModel ontModel = getOntModelSelector().getABoxModel();
ontModel.enterCriticalSection(Lock.READ);
@ -278,26 +281,77 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Set<String> constructQueryStrings,
String sortDirection) {
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
long start = System.currentTimeMillis();
try {
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, rangeUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
}
if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC(");
}
ResultSet results = (constructedModel == null) ? selectFromRDFService(
queryString, subjectUri, propertyUri, domainUri, rangeUri) : selectFromConstructedModel(
queryString, subjectUri, propertyUri, domainUri, rangeUri, constructedModel);
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
RDFNode node = soln.get(objectKey);
if (node.isURIResource()) {
list.add(QueryUtils.querySolutionToStringValueMap(soln));
}
}
if(log.isDebugEnabled()) {
long duration = System.currentTimeMillis() - start;
log.debug(duration + " to do list view for " +
propertyUri + " / " + domainUri + " / " + rangeUri);
}
} catch (Exception e) {
log.error("Error getting object property values for subject " + subjectUri + " and property " + propertyUri, e);
return Collections.emptyList();
}
if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC(");
}
return list;
}
private ResultSet selectFromRDFService(String queryString, String subjectUri,
String propertyUri, String domainUri, String rangeUri) {
String[] part = queryString.split("[Ww][Hh][Ee][Rr][Ee]");
part[1] = part[1].replace("?subject", "<" + subjectUri + ">");
part[1] = part[1].replace("?property", "<" + propertyUri + ">");
if (domainUri != null && !domainUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
part[1] = part[1].replace("?subjectType", "<" + domainUri + ">");
}
if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
part[1] = part[1].replace("?objectType", "<" + rangeUri + ">");
}
queryString = part[0] + "WHERE" + part[1];
try {
return ResultSetFactory.fromJSON(
rdfService.sparqlSelectQuery(queryString, RDFService.ResultFormat.JSON));
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
}
private ResultSet selectFromConstructedModel(String queryString,
String subjectUri, String propertyUri, String domainUri, String rangeUri,
Model constructedModel) {
Query query = null;
try {
query = QueryFactory.create(queryString, Syntax.syntaxARQ);
} catch(Throwable th){
log.error("Could not create SPARQL query for query string. " + th.getMessage());
log.error(queryString);
return Collections.emptyList();
throw new RuntimeException(th);
}
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
initialBindings.add("property", ResourceFactory.createResource(propertyUri));
@ -307,52 +361,31 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
initialBindings.add("objectType", ResourceFactory.createResource(rangeUri));
}
log.debug("Query string for object property " + propertyUri + ": " + queryString);
if(log.isDebugEnabled()) {
log.debug("Query string for object property " + propertyUri + ": " + queryString);
}
// Run the SPARQL query to get the properties
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
QueryExecution qexec = null;
try {
qexec = (constructedModel == null)
? QueryExecutionFactory.create(
query, dataset, initialBindings)
: QueryExecutionFactory.create(
query, constructedModel, initialBindings);
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
RDFNode node = soln.get(objectKey);
if (node.isURIResource()) {
list.add(QueryUtils.querySolutionToStringValueMap(soln));
}
}
return list;
} catch (Exception e) {
log.error("Error getting object property values for subject " + subjectUri + " and property " + propertyUri);
return Collections.emptyList();
qexec = QueryExecutionFactory.create(
query, constructedModel, initialBindings);
return new ResultSetMem(qexec.execSelect());
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
if (qexec != null) {
qexec.close();
}
}
}
}
private Model constructModelForSelectQueries(String subjectUri,
String propertyUri,
String propertyUri,
String rangeUri,
Set<String> constructQueries) {
if (constructQueries == null) {
if (constructQueries.size() == 0 || constructQueries == null) {
return null;
}
@ -362,24 +395,18 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
queryString = queryString.replace("?subject", "<" + subjectUri + ">");
queryString = queryString.replace("?property", "<" + propertyUri + ">");
if (rangeUri != null) {
queryString = queryString.replace("?objectType", "<" + rangeUri + ">");
}
log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
if (log.isDebugEnabled()) {
log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
}
// we no longer need this query object, but we might want to do this
// query parse step to improve debugging, depending on the error returned
// through the RDF API
// try {
// QueryFactory.create(queryString, Syntax.syntaxARQ);
// } catch(Throwable th){
// log.error("Could not create CONSTRUCT SPARQL query for query " +
// "string. " + th.getMessage());
// log.error(queryString);
// return constructedModel;
// }
try {
//If RDFService is null, will do what code used to do before, otherwise employ rdfservice
//If RDFService is null, will do what code used to do before,
//otherwise employ rdfservice
if(rdfService == null) {
log.debug("RDF Service null, Using CONSTRUCT query string for object property " +
propertyUri + ": " + queryString);
@ -402,7 +429,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
query, dataset);
qe.execConstruct(constructedModel);
} catch (Exception e) {
log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri);
log.error("Error getting constructed model for subject "
+ subjectUri + " and property " + propertyUri);
} finally {
if (qe != null) {
qe.close();
@ -412,28 +440,31 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
}
} else {
String parseFormat = "N3";
RDFService.ModelSerializationFormat resultFormat = RDFService.ModelSerializationFormat.N3;
RDFService.ModelSerializationFormat resultFormat = RDFService
.ModelSerializationFormat.N3;
/* If the test ObjectPropertyStatementDaoJenaTest.testN3WithSameAs() fails
* this code can be removed: */
/* If the test ObjectPropertyStatementDaoJenaTest.testN3WithSameAs()
* fails this code can be removed: */
if( OWL.sameAs.getURI().equals( propertyUri )){
// VIVO-111: owl:sameAs can be represented as = in n3 but Jena's parser does not recognize it.
// Switch to rdf/xml only for sameAs since it seems like n3 would be faster the rest of the time.
// VIVO-111: owl:sameAs can be represented as = in n3 but
// Jena's parser does not recognize it.
// Switch to rdf/xml only for sameAs since it seems like n3
// would be faster the rest of the time.
parseFormat = "RDF/XML";
resultFormat = RDFService.ModelSerializationFormat.RDFXML;
}
/* end of removal */
InputStream is = rdfService.sparqlConstructQuery(queryString, resultFormat);
InputStream is = rdfService.sparqlConstructQuery(
queryString, resultFormat);
constructedModel.read( is, null, parseFormat);
}
} catch (Exception e) {
log.error("Error getting constructed model for subject " + subjectUri + " and property " + propertyUri, e);
log.error("Error getting constructed model for subject "
+ subjectUri + " and property " + propertyUri, e);
}
}
return constructedModel;
return constructedModel;
}
protected static final String MOST_SPECIFIC_TYPE_QUERY = ""

View file

@ -21,13 +21,13 @@ import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.ontology.Restriction;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
@ -36,7 +36,6 @@ import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.sdb.util.Pair;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS;
@ -49,6 +48,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
@ -74,11 +75,14 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
log.debug("Query prefixes: " + PREFIXES);
}
protected RDFService rdfService;
protected DatasetWrapperFactory dwf;
public PropertyDaoJena(DatasetWrapperFactory dwf,
public PropertyDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(wadf);
this.rdfService = rdfService;
this.dwf = dwf;
}
@ -86,6 +90,10 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
protected OntModel getOntModel() {
return getOntModelSelector().getTBoxModel();
}
protected RDFService getRDFService() {
return this.rdfService;
}
public void addSuperproperty(ObjectProperty property, ObjectProperty superproperty) {
addSuperproperty(property.getURI(),superproperty.getURI());
@ -414,8 +422,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return classSet;
}
protected ResultSet getPropertyQueryResults(Query query) {
log.debug("SPARQL query:\n" + query.toString());
protected ResultSet getPropertyQueryResults(String queryString) {
log.debug("SPARQL query:\n" + queryString);
// RY Removing prebinding due to Jena bug: when isLiteral(?object) or
// isURI(?object) is added to the query as a filter, the query fails with prebinding
@ -424,23 +432,32 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
//subjectBinding.add("subject", ResourceFactory.createResource(subjectUri));
// Run the SPARQL query to get the properties
DatasetWrapper w = dwf.getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
ResultSet rs = null;
try {
QueryExecution qexec = QueryExecutionFactory.create(
query, dataset); //, subjectBinding);
try {
rs = new ResultSetMem(qexec.execSelect());
} finally {
qexec.close();
}
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
return ResultSetFactory.fromJSON(
getRDFService().sparqlSelectQuery(
queryString, RDFService.ResultFormat.JSON));
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
return rs;
// DatasetWrapper w = dwf.getDatasetWrapper();
// Dataset dataset = w.getDataset();
// dataset.getLock().enterCriticalSection(Lock.READ);
// ResultSet rs = null;
// try {
// QueryExecution qexec = QueryExecutionFactory.create(
// query, dataset); //, subjectBinding);
// try {
// rs = new ResultSetMem(qexec.execSelect());
// } finally {
// qexec.close();
// }
// } finally {
// dataset.getLock().leaveCriticalSection();
// w.close();
// }
// return rs;
}
/**
@ -865,20 +882,6 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
}
return domainAndRangeURIs;
}
private String getURIStr(Resource res) {
String URIStr;
if (res == null) {
URIStr = OWL.Thing.getURI(); // TODO: rdf:Resource if using RDF model; or option to turn off entirely
} else {
if (res.isAnon()) {
URIStr = PSEUDO_BNODE_NS+res.getId().toString();
} else {
URIStr = res.getURI();
}
}
return URIStr;
}
}

View file

@ -29,11 +29,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class PropertyInstanceDaoJena extends PropertyDaoJena implements
PropertyInstanceDao {
public PropertyInstanceDaoJena(DatasetWrapperFactory dwf, WebappDaoFactoryJena wadf) {
super(dwf, wadf);
public PropertyInstanceDaoJena(RDFService rdfService,
DatasetWrapperFactory dwf,
WebappDaoFactoryJena wadf) {
super(rdfService, dwf, wadf);
}
public void deleteObjectPropertyStatement(String subjectURI, String propertyURI, String objectURI) {

View file

@ -50,6 +50,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.utils.jena.URIUtils;
@ -109,6 +110,8 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
Dataset dataset = makeInMemoryDataset(assertions, inferences);
this.dwf = new StaticDatasetFactory(dataset);
this.rdfService = new RDFServiceModel(ontModelSelector.getFullModel());
}
public WebappDaoFactoryJena(OntModelSelector ontModelSelector,
@ -327,7 +330,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
DataPropertyDao dataPropertyDao = null;
public DataPropertyDao getDataPropertyDao() {
if( dataPropertyDao == null )
dataPropertyDao = new DataPropertyDaoJena(dwf, this);
dataPropertyDao = new DataPropertyDaoJena(rdfService, dwf, this);
return dataPropertyDao;
}
@ -358,14 +361,15 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
private ObjectPropertyDao objectPropertyDao = null;
public ObjectPropertyDao getObjectPropertyDao() {
if( objectPropertyDao == null )
objectPropertyDao = new ObjectPropertyDaoJena(dwf, this);
objectPropertyDao = new ObjectPropertyDaoJena(
rdfService, dwf, config.customListViewConfigFileMap, this);
return objectPropertyDao;
}
private PropertyInstanceDao propertyInstanceDao = null;
public PropertyInstanceDao getPropertyInstanceDao() {
if( propertyInstanceDao == null )
propertyInstanceDao = new PropertyInstanceDaoJena(dwf, this);
propertyInstanceDao = new PropertyInstanceDaoJena(rdfService, dwf, this);
return propertyInstanceDao;
}

View file

@ -39,7 +39,7 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
initBasics(conf, vreq);
initPropertyParameters(vreq, session, conf);
initObjectPropForm(conf, vreq);
initObjectPropForm(conf, vreq);
conf.setTemplate(this.getTemplate());
@ -126,6 +126,7 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();
formSpecificData.put("editMode", getEditMode(vreq).name().toLowerCase());
formSpecificData.put("domainUri", getDomainUri(vreq));
editConfiguration.setFormSpecificData(formSpecificData);
}
@ -140,4 +141,10 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
}
return editMode;
}
private String getDomainUri(VitroRequest vreq) {
String domainUri = vreq.getParameter("domainUri");
return domainUri;
}
}

View file

@ -145,16 +145,16 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext());
List<String> types = new ArrayList<String>();
for (VClass vclass : rangeTypes) {
if (vclass.getURI() != null) {
types.add(vclass.getURI());
}
}
//empty list means the range is not set to anything, force Thing
if(types.size() == 0 ){
types.add(VitroVocabulary.OWL_THING);
} else {
for (VClass vclass : rangeTypes) {
if (vclass.getURI() != null) {
types.add(vclass.getURI());
}
}
}
if(types.size() == 0 ){
types.add(VitroVocabulary.OWL_THING);
}
long count = 0;
for( String type:types){

View file

@ -1,6 +1,10 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_LITERAL;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_PREDICATE;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_URI;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
@ -24,14 +28,12 @@ import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
@ -271,11 +273,10 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
Individual individual = EditConfigurationUtils.getIndividual(vreq, config.getSubjectUri());
AddDataPropertyStatement adps = new AddDataPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI);
SOME_URI, SOME_LITERAL);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI);
SOME_PREDICATE, SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
}

View file

@ -164,7 +164,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
//edit key is set here, NOT in the generator class
EditConfigurationVTwo editConfig = null;
EditConfigurationVTwo existingConfig = EditConfigurationVTwo.getConfigFromSession(session, vreq);
if(existingConfig != null) {
//if delete form from the editing page, then edit configuration already exists and the
//delete generator wouldn't be used, we need to make sure that it is used if it's a delete option
if(existingConfig != null && !isDeleteForm(vreq)) {
editConfig = existingConfig;
} else {
editConfig =

View file

@ -10,6 +10,8 @@ import java.text.Collator;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import javax.servlet.Filter;
@ -24,6 +26,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openjena.atlas.lib.Pair;
import com.hp.hpl.jena.graph.BulkUpdateHandler;
import com.hp.hpl.jena.graph.Graph;
@ -35,6 +38,7 @@ import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -311,6 +315,8 @@ public class RequestModelsPrep implements Filter {
config.setDefaultNamespace(defaultNamespace);
config.setPreferredLanguages(langs);
config.setUnderlyingStoreReasoned(isStoreReasoned(req));
config.setCustomListViewConfigFileMap(getCustomListViewConfigFileMap(
req.getSession().getServletContext()));
return config;
}
@ -365,6 +371,18 @@ public class RequestModelsPrep implements Filter {
"VitroConnection.DataSource.isStoreReasoned", "true");
return ("true".equals(isStoreReasoned));
}
private Map<Pair<String,Pair<ObjectProperty, String>>, String>
getCustomListViewConfigFileMap(ServletContext ctx) {
Map<Pair<String,Pair<ObjectProperty, String>>, String> map =
(Map<Pair<String,Pair<ObjectProperty, String>>, String>)
ctx.getAttribute("customListViewConfigFileMap");
if (map == null) {
map = new ConcurrentHashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
ctx.setAttribute("customListViewConfigFileMap", map);
}
return map;
}
@Override
public void destroy() {

View file

@ -31,6 +31,8 @@ import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
/**
* Performs knowledge base updates to the abox to align with a new ontology version
@ -594,9 +596,11 @@ public class ABoxUpdater {
return;
}
long start = System.currentTimeMillis();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
//log.info(System.currentTimeMillis() - start + " to get graph");
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
@ -604,11 +608,23 @@ public class ABoxUpdater {
Model renamePropAddModel = ModelFactory.createDefaultModel();
Model renamePropRetractModel = ModelFactory.createDefaultModel();
log.info("renaming " + oldProperty.getURI() + " in graph " + graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
start = System.currentTimeMillis();
// String queryStr = "CONSTRUCT { ?s <" + oldProperty.getURI() + "> ?o } WHERE { GRAPH<" + graph + "> { ?s <" + oldProperty.getURI() + "> ?o } } ";
// try {
// renamePropRetractModel = RDFServiceUtils.parseModel(rdfService.sparqlConstructQuery(queryStr, RDFService.ModelSerializationFormat.NTRIPLE), RDFService.ModelSerializationFormat.NTRIPLE);
// } catch (RDFServiceException e) {
// log.error(e,e);
// }
// log.info(System.currentTimeMillis() - start + " to run sparql construct for " + renamePropRetractModel.size() + " statements" );
start = System.currentTimeMillis();
renamePropRetractModel.add( aboxModel.listStatements(
(Resource) null, oldProperty, (RDFNode) null));
log.info(System.currentTimeMillis() - start + " to list " + renamePropRetractModel.size() + " old statements");
start = System.currentTimeMillis();
StmtIterator stmItr = renamePropRetractModel.listStatements();
while(stmItr.hasNext()) {
Statement tempStatement = stmItr.nextStatement();
@ -616,8 +632,13 @@ public class ABoxUpdater {
newProperty,
tempStatement.getObject() );
}
log.info(System.currentTimeMillis() - start + " to make new statements");
start = System.currentTimeMillis();
aboxModel.remove(renamePropRetractModel);
log.info(System.currentTimeMillis() - start + " to retract old statements");
start = System.currentTimeMillis();
aboxModel.add(renamePropAddModel);
log.info(System.currentTimeMillis() - start + " to add new statements");
} finally {
aboxModel.leaveCriticalSection();
}

View file

@ -96,10 +96,10 @@ public class KnowledgeBaseUpdater {
// update ABox data any time
log.info("performing SPARQL CONSTRUCT additions");
performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
//performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
log.info("performing SPARQL CONSTRUCT retractions");
performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
//performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
log.info("\tupdating the abox");
updateABox(changes);
@ -207,9 +207,11 @@ public class KnowledgeBaseUpdater {
StmtIterator sit = anonModel.listStatements();
while (sit.hasNext()) {
Statement stmt = sit.nextStatement();
long start = System.currentTimeMillis();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
log.info(System.currentTimeMillis() - start + " to get graph");
if(!isUpdatableABoxGraph(graph)) {
continue;
}

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerialization
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
public class RDFServiceUtils {
@ -34,7 +35,18 @@ public class RDFServiceUtils {
public static RDFServiceFactory getRDFServiceFactory(ServletContext context) {
Object o = context.getAttribute(RDFSERVICEFACTORY_ATTR);
return (o instanceof RDFServiceFactory) ? (RDFServiceFactory) o : null;
if (o instanceof RDFServiceFactory) {
RDFServiceFactory factory = (RDFServiceFactory) o;
/*
* Every factory is wrapped in a logger, so we can dynamically
* enable or disable logging.
*/
return new LoggingRDFServiceFactory(context, factory);
} else {
log.error("Expecting an RDFServiceFactory on the context, but found " + o);
return null;
}
}
public static void setRDFServiceFactory(ServletContext context,

View file

@ -0,0 +1,125 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
/**
* This RDFService wrapper adds instrumentation to the time-consuming methods of
* the inner RDFService.
*
* For the other methods, it just delegates to the inner RDFService.
*/
public class LoggingRDFService implements RDFService {
private final ServletContext ctx;
private final RDFService innerService;
LoggingRDFService(ServletContext ctx, RDFService innerService) {
this.ctx = ctx;
this.innerService = innerService;
}
// ----------------------------------------------------------------------
// Timed methods
// ----------------------------------------------------------------------
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, changeSet)) {
return innerService.changeSetUpdate(changeSet);
}
}
@Override
public InputStream sparqlConstructQuery(String query,
ModelSerializationFormat resultFormat) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlConstructQuery(query, resultFormat);
}
}
@Override
public InputStream sparqlDescribeQuery(String query,
ModelSerializationFormat resultFormat) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlDescribeQuery(query, resultFormat);
}
}
@Override
public InputStream sparqlSelectQuery(String query, ResultFormat resultFormat)
throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, resultFormat, query)) {
return innerService.sparqlSelectQuery(query, resultFormat);
}
}
@Override
public boolean sparqlAskQuery(String query) throws RDFServiceException {
try (RDFServiceLogger l = new RDFServiceLogger(ctx, query)) {
return innerService.sparqlAskQuery(query);
}
}
// ----------------------------------------------------------------------
// Untimed methods
// ----------------------------------------------------------------------
@Override
public void newIndividual(String individualURI, String individualTypeURI)
throws RDFServiceException {
innerService.newIndividual(individualURI, individualTypeURI);
}
@Override
public void newIndividual(String individualURI, String individualTypeURI,
String graphURI) throws RDFServiceException {
innerService.newIndividual(individualURI, individualTypeURI, graphURI);
}
@Override
public List<String> getGraphURIs() throws RDFServiceException {
return innerService.getGraphURIs();
}
@Override
public void getGraphMetadata() throws RDFServiceException {
innerService.getGraphMetadata();
}
@Override
public String getDefaultWriteGraphURI() throws RDFServiceException {
return innerService.getDefaultWriteGraphURI();
}
@Override
public void registerListener(ChangeListener changeListener)
throws RDFServiceException {
innerService.registerListener(changeListener);
}
@Override
public void unregisterListener(ChangeListener changeListener)
throws RDFServiceException {
innerService.unregisterListener(changeListener);
}
@Override
public ChangeSet manufactureChangeSet() {
return innerService.manufactureChangeSet();
}
@Override
public void close() {
innerService.close();
}
}

View file

@ -0,0 +1,48 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
/**
* If the RDFServiceFactory is wrapped in this, then all RDFServices will be
* wrapped in a LoggingRDFService.
*/
public class LoggingRDFServiceFactory implements RDFServiceFactory {
private final ServletContext ctx;
private final RDFServiceFactory factory;
public LoggingRDFServiceFactory(ServletContext ctx,
RDFServiceFactory factory) {
this.ctx = ctx;
this.factory = factory;
}
@Override
public RDFService getRDFService() {
return new LoggingRDFService(ctx, factory.getRDFService());
}
@Override
public RDFService getShortTermRDFService() {
return new LoggingRDFService(ctx, factory.getShortTermRDFService());
}
@Override
public void registerListener(ChangeListener changeListener)
throws RDFServiceException {
factory.registerListener(changeListener);
}
@Override
public void unregisterListener(ChangeListener changeListener)
throws RDFServiceException {
factory.unregisterListener(changeListener);
}
}

View file

@ -0,0 +1,175 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
/**
* Writes the log message for the LoggingRDFService.
*
* If not enabled, or if the logging level is insufficient, this does nothing.
*
* If enabled, it checks for restrictions. If there is a restriction pattern
* (regular expression), the a log message will only be printed if one of the
* fully-qualified class names in the stack trace matches that pattern.
*
* If everything passes muster, the constructor will record the time that the
* instance was created.
*
* When close() is called, if a start time was recorded, then a log record is
* produced. This contains the elapsed time, the name of the method, and any
* arguments passed to the constructor. It may also include a stack trace, if
* requested.
*
* The stack trace is abbreviated. It will reach into this class, and will not
* extend past the first reference to the ApplicationFilterChain. Perhaps it
* should be abbreviated further?
*/
public class RDFServiceLogger implements AutoCloseable {
private static final Log log = LogFactory.getLog(RDFServiceLogger.class);
private static final String PROPERTY_ENABLED = "developer.loggingRDFService.enable";
private static final String PROPERTY_STACK_TRACE = "developer.loggingRDFService.stackTrace";
private static final String PROPERTY_RESTRICTION = "developer.loggingRDFService.restriction";
private final ServletContext ctx;
private final Object[] args;
private boolean isEnabled;
private boolean traceRequested;
private Pattern restriction;
private String methodName;
private List<StackTraceElement> trace = Collections.emptyList();
private long startTime;
public RDFServiceLogger(ServletContext ctx, Object... args) {
this.ctx = ctx;
this.args = args;
getProperties();
if (isEnabled && log.isInfoEnabled()) {
loadStackTrace();
if (passesRestrictions()) {
this.startTime = System.currentTimeMillis();
}
}
}
private void getProperties() {
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
isEnabled = Boolean.valueOf(props.getProperty(PROPERTY_ENABLED));
traceRequested = Boolean.valueOf(props
.getProperty(PROPERTY_STACK_TRACE));
String restrictionString = props.getProperty(PROPERTY_RESTRICTION);
if (StringUtils.isNotBlank(restrictionString)) {
try {
restriction = Pattern.compile(restrictionString);
} catch (Exception e) {
log.error("Failed to compile the pattern for "
+ PROPERTY_RESTRICTION + " = " + restriction + " " + e);
isEnabled = false;
}
}
}
private void loadStackTrace() {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
List<StackTraceElement> list = new ArrayList<StackTraceElement>(
Arrays.asList(stack));
trimStackTraceAtBeginning(list);
trimStackTraceAtEnd(list);
if (list.isEmpty()) {
this.methodName = "UNKNOWN";
} else {
this.methodName = list.get(0).getMethodName();
}
this.trace = list;
}
private void trimStackTraceAtBeginning(List<StackTraceElement> list) {
ListIterator<StackTraceElement> iter = list.listIterator();
while (iter.hasNext()) {
StackTraceElement ste = iter.next();
if (ste.getClassName().equals(LoggingRDFService.class.getName())) {
break;
} else {
iter.remove();
}
}
}
private void trimStackTraceAtEnd(List<StackTraceElement> list) {
ListIterator<StackTraceElement> iter = list.listIterator();
boolean trimming = false;
while (iter.hasNext()) {
StackTraceElement ste = iter.next();
if (trimming) {
iter.remove();
} else if (ste.getClassName().contains("ApplicationFilterChain")) {
trimming = true;
}
}
}
private boolean passesRestrictions() {
if (restriction == null) {
return true;
}
for (StackTraceElement ste : trace) {
if (restriction.matcher(ste.getClassName()).matches()) {
return true;
}
}
return false;
}
@Override
public void close() {
if (startTime != 0L) {
long endTime = System.currentTimeMillis();
float elapsedSeconds = (endTime - startTime) / 1000.0F;
String cleanArgs = Arrays.deepToString(args).replaceAll(
"[\\n\\r\\t]+", " ");
String formattedTrace = formatStackTrace();
log.info(String.format("%8.3f %s %s %s", elapsedSeconds,
methodName, cleanArgs, formattedTrace));
}
}
private String formatStackTrace() {
StringBuilder sb = new StringBuilder();
if (traceRequested) {
for (StackTraceElement ste : trace) {
sb.append(String.format("\n %d %s", ste.getLineNumber(),
ste.getClassName()));
}
sb.append("\n ...");
}
return sb.toString();
}
}

View file

@ -439,9 +439,13 @@ public class FakeApplicationOntologyService {
* "display model". The query finds a preferred title for the individual.
*/
private static class FakeVivoPeopleDataGetter extends SparqlQueryDataGetter {
private static final String QUERY_STRING = "SELECT ?uri ?pt WHERE {\n"
+ " ?uri <http://vivoweb.org/ontology/core#preferredTitle> ?pt\n"
+ "} LIMIT 1";
private static String QUERY_STRING = ""
+ "PREFIX obo: <http://purl.obolibrary.org/obo/> \n"
+ "PREFIX vcard: <http://www.w3.org/2006/vcard/ns#> \n"
+ "SELECT ?uri ?pt \n" + "WHERE { \n"
+ " ?uri obo:ARG_2000028 ?vIndividual . \n"
+ " ?vIndividual vcard:hasTitle ?vTitle . \n"
+ " ?vTitle vcard:title ?pt . \n" + "} LIMIT 1";
private static final String FAKE_VIVO_PEOPLE_DATA_GETTER_URI = "http://FakeVivoPeopleDataGetter";

View file

@ -79,7 +79,8 @@ public class FileGraphSetup implements ServletContextListener {
cleanupDB(dataset, pathsToURIs(paths, ABOX), ABOX);
OntModel aboxBaseModel = baseOms.getABoxModel();
aboxChanged = readGraphs(paths, maker, ABOX, aboxBaseModel);
// Just update the ABox filegraphs in the DB; don't attach them to a base model.
aboxChanged = readGraphs(paths, maker, ABOX, /* aboxBaseModel */ null);
// TBox files
paths = getFilegraphPaths(ctx, RDF, TBOX, FILEGRAPH);
@ -108,7 +109,7 @@ public class FileGraphSetup implements ServletContextListener {
if ( (aboxChanged || tboxChanged) && !isUpdateRequired(sce.getServletContext())) {
log.info("a full recompute of the Abox will be performed because" +
" the filegraph abox(s) and/or tbox(s) have changed or are being read for the first time." );
SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext());
SimpleReasonerSetup.setRecomputeRequired(sce.getServletContext(), SimpleReasonerSetup.RecomputeMode.BACKGROUND);
}
}
@ -140,6 +141,14 @@ public class FileGraphSetup implements ServletContextListener {
return paths;
}
/*
* Reads graphs without using submodels to separate filegraph content from the
* base model.
*/
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel) {
return readGraphs(pathSet, dataset, type, baseModel, false);
}
/*
* Reads the graphs stored as files in sub-directories of
* 1. updates the SDB store to reflect the current contents of the graph.
@ -148,7 +157,7 @@ public class FileGraphSetup implements ServletContextListener {
* Note: no connection needs to be maintained between the in-memory copy of the
* graph and the DB copy.
*/
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel) {
public boolean readGraphs(Set<Path> pathSet, RDFServiceModelMaker dataset, String type, OntModel baseModel, boolean useSubmodels) {
int count = 0;
@ -172,9 +181,14 @@ public class FileGraphSetup implements ServletContextListener {
log.warn("Ignoring " + type + " file graph " + p + " because the file extension is unrecognized.");
}
if ( !model.isEmpty() ) {
baseModel.addSubModel(model);
if ( !model.isEmpty() && baseModel != null ) {
if (useSubmodels) {
baseModel.addSubModel(model);
} else {
baseModel.add(model);
}
log.info("Attached file graph as " + type + " submodel " + p.getFileName());
}
modelChanged = modelChanged | updateGraphInDB(dataset, model, type, p);

View file

@ -87,14 +87,23 @@ public class RDFFilesLoader {
OntModel model) {
OntModel everytimeModel = ModelFactory
.createOntologyModel(OntModelSpec.OWL_MEM);
Set<Path> paths = getPaths(locateHomeDirectory(ctx), RDF, modelPath,
EVERY_TIME);
String home = locateHomeDirectory(ctx);
Set<Path> paths = getPaths(home, RDF, modelPath, EVERY_TIME);
for (Path p : paths) {
log.info("Loading " + relativePath(p, home));
readOntologyFileIntoModel(p, everytimeModel);
}
model.addSubModel(everytimeModel);
}
private static Path relativePath(Path p, String home) {
try {
return Paths.get(home).relativize(p);
} catch (Exception e) {
return p;
}
}
/**
* Create a model from all the RDF files in the specified directory.
*/
@ -148,7 +157,7 @@ public class RDFFilesLoader {
private static void readOntologyFileIntoModel(Path p, Model model) {
String format = getRdfFormat(p);
log.info("Loading "+ p);
log.debug("Loading "+ p);
try (InputStream stream = new FileInputStream(p.toFile())) {
model.read(stream, null, format);
log.debug("...successful");

View file

@ -12,7 +12,6 @@ import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -21,7 +20,6 @@ import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
@ -117,7 +115,16 @@ public class SimpleReasonerSetup implements ServletContextListener {
assertionsOms.getTBoxModel().register(simpleReasonerTBoxListener);
inferencesOms.getTBoxModel().register(simpleReasonerTBoxListener);
log.info("Simple reasoner connected for the ABox");
RecomputeMode mode = getRecomputeRequired(ctx);
if (RecomputeMode.FOREGROUND.equals(mode)) {
log.info("ABox inference recompute required.");
simpleReasoner.recompute();
} else if (RecomputeMode.BACKGROUND.equals(mode)) {
log.info("starting ABox inference recompute in a separate thread.");
new Thread(
new ABoxRecomputer(
simpleReasoner),"ABoxRecomputer").start();
}
} catch (Throwable t) {
t.printStackTrace();
@ -179,15 +186,19 @@ public class SimpleReasonerSetup implements ServletContextListener {
}
}
public enum RecomputeMode {
FOREGROUND, BACKGROUND
}
private static final String RECOMPUTE_REQUIRED_ATTR =
SimpleReasonerSetup.class.getName() + ".recomputeRequired";
public static void setRecomputeRequired(ServletContext ctx) {
ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, true);
public static void setRecomputeRequired(ServletContext ctx, RecomputeMode mode) {
ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, mode);
}
public static boolean isRecomputeRequired(ServletContext ctx) {
return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null);
public static RecomputeMode getRecomputeRequired(ServletContext ctx) {
return (RecomputeMode) ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR);
}
private static final String MSTCOMPUTE_REQUIRED_ATTR =
@ -249,6 +260,18 @@ public class SimpleReasonerSetup implements ServletContextListener {
log.debug("Classnames of reasoner plugins = " + list);
return list;
}
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
}

View file

@ -157,42 +157,24 @@ public class UpdateKnowledgeBase implements ServletContextListener {
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe);
}
}
SimpleReasoner simpleReasoner = (SimpleReasoner) sce.getServletContext()
.getAttribute(SimpleReasoner.class.getName());
if (simpleReasoner != null) {
if ( (requiredUpdate && migrationChangesMade)
|| JenaDataSourceSetupBase.isFirstStartup()) {
log.info("ABox inference recompute required.");
simpleReasoner.recompute();
} else if (SimpleReasonerSetup.isRecomputeRequired(sce.getServletContext()) || migrationChangesMade) {
log.info("starting ABox inference recompute in a separate thread.");
new Thread(
new ABoxRecomputer(
simpleReasoner),"ABoxRecomputer").start();
}
}
log.info("Simple reasoner connected for the ABox");
if(JenaDataSourceSetupBase.isFirstStartup()
|| (migrationChangesMade && requiredUpdate)) {
SimpleReasonerSetup.setRecomputeRequired(
ctx, SimpleReasonerSetup.RecomputeMode.FOREGROUND);
} else if (migrationChangesMade) {
SimpleReasonerSetup.setRecomputeRequired(
ctx, SimpleReasonerSetup.RecomputeMode.BACKGROUND);
}
} catch (Throwable t){
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
}
}
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
/**

View file

@ -83,7 +83,7 @@ public class ApplicationConfigurationOntologyUtils {
String rangeURI = qsoln.getResource("range").getURI();
if (appropriateDomain(domainRes, subject, tboxModel)) {
ObjectProperty faux = opDao.getObjectPropertyByURIs(
opURI, domainURI, rangeURI);
opURI, domainURI, rangeURI, (prop != null) ? prop.clone() : null);
if (faux != null) {
additionalProps.add(faux);
} else {

View file

@ -3,10 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -17,7 +14,6 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import com.hp.hpl.jena.query.Query;
@ -35,20 +31,13 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
@ -324,123 +313,6 @@ public class DataGetterUtils {
return classGroupUri;
}
/**
* Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent.
*/
public static JSONObject processVclassResultsJSON(Map<String, Object> map, VitroRequest vreq, boolean multipleVclasses) {
JSONObject rObj = new JSONObject();
VClass vclass=null;
try {
// Properties from ontologies used by VIVO - should not be in vitro
DataProperty fNameDp = (new DataProperty());
fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName");
DataProperty lNameDp = (new DataProperty());
lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName");
DataProperty preferredTitleDp = (new DataProperty());
preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle");
if( log.isDebugEnabled() ){
@SuppressWarnings("unchecked")
Enumeration<String> e = vreq.getParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
log.debug("parameter: " + name);
for( String value : vreq.getParameterValues(name) ){
log.debug("value for " + name + ": '" + value + "'");
}
}
}
//need an unfiltered dao to get firstnames and lastnames
WebappDaoFactory fullWdf = vreq.getUnfilteredWebappDaoFactory();
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception ("Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
//if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list
if(!multipleVclasses) {
//currently used for ClassGroupPage
rObj.put("vclass",
new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
} else {
//For now, utilize very last VClass (assume that that is the one to be employed)
//TODO: Find more general way of dealing with this
//put multiple ones in?
if(vclassIds.size() > 0) {
int numberVClasses = vclassIds.size();
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(numberVClasses - 1));
rObj.put("vclass", new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
}
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr)
// .put("name",vclass.getName()));
}
if (vclass != null) {
rObj.put("totalCount", map.get("totalCount"));
rObj.put("alpha", map.get("alpha"));
List<Individual> inds = (List<Individual>)map.get("entities");
log.debug("Number of individuals returned from request: " + inds.size());
JSONArray jInds = new JSONArray();
for(Individual ind : inds ){
JSONObject jo = new JSONObject();
jo.put("URI", ind.getURI());
jo.put("label",ind.getRdfsLabel());
jo.put("name",ind.getName());
jo.put("thumbUrl", ind.getThumbUrl());
jo.put("imageUrl", ind.getImageUrl());
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
jInds.put(jo);
}
rObj.put("individuals", jInds);
JSONArray wpages = new JSONArray();
//Made sure that PageRecord here is SolrIndividualListController not IndividualListController
List<PageRecord> pages = (List<PageRecord>)map.get("pages");
for( PageRecord pr: pages ){
JSONObject p = new JSONObject();
p.put("text", pr.text);
p.put("param", pr.param);
p.put("index", pr.index);
wpages.put( p );
}
rObj.put("pages",wpages);
JSONArray jletters = new JSONArray();
List<String> letters = Controllers.getLetters();
for( String s : letters){
JSONObject jo = new JSONObject();
jo.put("text", s);
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
jletters.put( jo );
}
rObj.put("letters", jletters);
}
} catch(Exception ex) {
log.error("Error occurred in processing JSON object", ex);
}
return rObj;
}
private static final String forClassGroupURI = "<" + DisplayVocabulary.FOR_CLASSGROUP + ">";
private static final String classGroupForDataGetterQuery =

View file

@ -353,14 +353,15 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D
public String getDataServiceUrl() {
return UrlBuilder.getUrl("/dataservice?getRenderedSolrIndividualsByVClass=1&vclassId=");
}
/**
* For processig of JSONObject
*/
public JSONObject convertToJSON(Map<String, Object> map, VitroRequest vreq) {
JSONObject rObj = DataGetterUtils.processVclassResultsJSON(map, vreq, true);
public JSONObject convertToJSON(Map<String, Object> dataMap, VitroRequest vreq) {
JSONObject rObj = null;
return rObj;
}
protected static void setAllClassCountsToZero(VClassGroup vcg){
for(VClass vc : vcg){
vc.setEntityCount(0);

View file

@ -3,9 +3,7 @@ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -23,7 +21,6 @@ import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.shared.Lock;
@ -33,8 +30,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.SearchException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.individuallist.IndividualListResults;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individuallist.ListedIndividual;
@ -174,16 +172,15 @@ public class SolrIndividualsDataGetter extends DataGetterBase implements DataGet
try {
String alpha = SolrQueryUtils.getAlphaParameter(vreq);
int page = SolrQueryUtils.getPageParameter(vreq);
Map<String,Object> map = IndividualListController.getResultsForVClass(
IndividualListResults vcResults = IndividualListController.getResultsForVClass(
vclass.getURI(),
page,
alpha,
vreq.getWebappDaoFactory().getIndividualDao(),
vreq.getSession().getServletContext());
body.putAll(map);
body.putAll(vcResults.asFreemarkerMap());
@SuppressWarnings("unchecked")
List<Individual> inds = (List<Individual>)map.get("entities");
List<Individual> inds = vcResults.getEntities();
List<ListedIndividual> indsTm = new ArrayList<ListedIndividual>();
if (inds != null) {
for ( Individual ind : inds ) {

View file

@ -4,8 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.utils.solr;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -20,9 +18,7 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListQueryResults;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.SearchException;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.search.VitroSearchTermNames;
import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;

View file

@ -2,6 +2,10 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_LITERAL;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_PREDICATE;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_URI;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -16,7 +20,6 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
@ -116,11 +119,10 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
public boolean isEditable() {
AddDataPropertyStatement adps = new AddDataPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI);
SOME_URI, SOME_LITERAL);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI);
SOME_PREDICATE, SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_LITERAL;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@ -118,7 +120,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
// Determine whether a new statement can be added
RequestedAction action = new AddDataPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri);
vreq.getJenaOntModel(), subjectUri, propertyUri, SOME_LITERAL);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return;
}

View file

@ -6,8 +6,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -73,13 +75,23 @@ public class GroupedPropertyList extends BaseTemplateModel {
// so we cannot just rely on getting that list.
List<ObjectProperty> populatedObjectPropertyList = subject
.getPopulatedObjectPropertyList();
Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap(
populatedObjectPropertyList);
// save applicable ranges before deduping to filter later
populatedObjectPropertyList = dedupe(populatedObjectPropertyList);
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, subject, vreq);
additions = filterAdditions(additions, populatedObjTypes);
if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) {
log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " + t.getDomainVClassURI());
log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " +
t.getDomainVClassURI());
}
log.debug("Added " + additions.size() +
" properties due to application configuration ontology");
@ -110,12 +122,15 @@ public class GroupedPropertyList extends BaseTemplateModel {
mergeAllPossibleDataProperties(propertyList);
}
propertyList = correctLanguageForProperties(propertyList);
if (editing) {
propertyList = correctLanguageForProperties(propertyList);
}
sort(propertyList);
// Put the list into groups
List<PropertyGroup> propertyGroupList = addPropertiesToGroups(propertyList);
// Build the template data model from the groupList
groups = new ArrayList<PropertyGroupTemplateModel>(
propertyGroupList.size());
@ -131,6 +146,34 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
private Map<String, List<String>> makePopulatedObjTypeMap(List<ObjectProperty> props) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (ObjectProperty prop : props) {
if(prop.getRangeVClassURI() != null) {
List<String> typeList = map.get(prop.getURI());
if(typeList == null) {
typeList = new ArrayList<String>();
map.put(prop.getURI(), typeList);
}
typeList.add(prop.getRangeVClassURI());
}
}
return map;
}
private List<ObjectProperty> filterAdditions(Collection<ObjectProperty> additions,
Map<String, List<String>> populatedObjTypes) {
List<ObjectProperty> filteredAdditions = new ArrayList<ObjectProperty>();
for (ObjectProperty prop : additions) {
List<String> allowedTypes = populatedObjTypes.get(prop.getURI());
if(allowedTypes != null && (allowedTypes.contains(prop.getRangeVClassURI())
|| allowedTypes.contains(prop.getRangeEntityURI()) ) ) {
filteredAdditions.add(prop);
}
}
return filteredAdditions;
}
// Use the language-filtering WebappDaoFactory to get the right version of
// each property. When editing, the methods that add to the property list
// are blissfully (and intentionally) language-unaware.
@ -187,6 +230,19 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
}
}
//assumes sorted list
protected List<ObjectProperty> dedupe(List<ObjectProperty> propList) {
List<ObjectProperty> dedupedList = new ArrayList<ObjectProperty>();
String uriRegister = "";
for (ObjectProperty prop : propList) {
if(!uriRegister.equals(prop.getURI())) {
uriRegister = prop.getURI();
dedupedList.add(prop);
}
}
return dedupedList;
}
protected void sort(List<Property> propertyList) {
try {
@ -325,10 +381,12 @@ public class GroupedPropertyList extends BaseTemplateModel {
// Get the property groups
PropertyGroupDao pgDao = wdf.getPropertyGroupDao();
long start = System.currentTimeMillis();
List<PropertyGroup> groupList = pgDao.getPublicGroups(false); // may be returned empty but not null
// To test no property groups defined, use:
// List<PropertyGroup> groupList = new ArrayList<PropertyGroup>();
start = System.currentTimeMillis();
int groupCount = groupList.size();
/*
@ -353,7 +411,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
*/
PropertyGroup groupForUnassignedProperties = pgDao
.createDummyPropertyGroup("", MAX_GROUP_DISPLAY_RANK);
if (groupCount > 1) {
try {
Collections.sort(groupList);
@ -377,6 +435,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
log.error("Exception on trying to prune unpopulated groups from group list: "
+ ex.getMessage());
}
log.debug(System.currentTimeMillis() - start + " to remove unpopulated groups");
// If the group for unassigned properties is populated, add it to the
// group list.

View file

@ -8,6 +8,9 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
@ -37,6 +40,10 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel {
for (Property p : propertyList) {
if (p instanceof ObjectProperty) {
ObjectProperty op = (ObjectProperty) p;
RequestedAction dop = new DisplayObjectProperty(op);
if (!PolicyHelper.isAuthorizedForActions(vreq, dop)) {
continue;
}
ObjectPropertyTemplateModel tm = ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(
op, subject, vreq, editing, populatedObjectPropertyList);
if (!tm.isEmpty() || (editing && !tm.getAddUrl().isEmpty())) {

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy;
import static edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization.AUTHORIZED;
import static edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization.INCONCLUSIVE;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_LITERAL;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@ -31,6 +32,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.RebuildTextIn
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.RemoveUser;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.ServerStatus;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin.UpdateTextIndex;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.CreateOwlClass;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology.DefineDataProperty;
@ -125,19 +127,19 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
// now with dataprop statements
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
"http://mannlib.cornell.edu/bad#prp234");
"http://mannlib.cornell.edu/bad#prp234", SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
"http://mannlib.cornell.edu/bad#prp999");
"http://mannlib.cornell.edu/bad#prp999", SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
SAFE_PREDICATE.getURI());
SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
UNSAFE_PREDICATE.getURI());
UNSAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
}
@ -219,16 +221,16 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
//
@Test
public void testVisitIdentifierBundleEditDataPropStmt() {
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
}
@ -288,7 +290,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsFindDataPropertySubject() {
setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
}
@ -296,7 +298,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsDontFindInDataProperty() {
setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI(), SOME_LITERAL);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
}

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.auth.policy;
import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActionConstants.SOME_LITERAL;
import java.io.InputStream;
import org.apache.commons.logging.Log;
@ -306,7 +308,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
private void assertEditDataPropStmt(String individualURI,
String datapropURI, String data, Authorization expectedAuthorization) {
EditDataPropertyStatement whatToAuth = new EditDataPropertyStatement(
ontModel, individualURI, datapropURI);
ontModel, individualURI, datapropURI, SOME_LITERAL);
PolicyDecision dec = policy.isAuthorized(ids, whatToAuth);
log.debug(dec);
Assert.assertNotNull(dec);

View file

@ -67,7 +67,14 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
}
@Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) {
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI) {
return getObjectPropertyByURI(objectPropertyURI);
}
@Override
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
String domainURI, String rangeURI, ObjectProperty base) {
return getObjectPropertyByURI(objectPropertyURI);
}

View file

@ -134,10 +134,6 @@ submit_add_new_account = Add new account
account_created = Your {0} account has been created.
account_created_subject = Your {0} account has been created.
account_created_email_html = @@file files/accountCreatedEmail.html
account_created_email_text = @@file files/accountCreatedEmail.txt
account_created_external_email_html = @@file files/accountCreatedExternalOnlyEmail.html
account_created_external_email_text = @@file files/accountCreatedExternalOnlyEmail.txt
confirm_delete_account_singular = Are you sure you want to delete this account?
confirm_delete_account_plural = Are you sure you want to delete these accounts?
@ -156,21 +152,11 @@ select_associated_profile = Select the associated profile
create_associated_profile = Create the associated profile
email_changed_subject = Your {0} email account has been changed.
email_changed_html = @@file files/accountEmailChanged.html
email_changed_text = @@file files/accountEmailChanged.txt
create_your_password = Create your Password
password_created_subject = Your {0} password has successfully been created.
password_created_email_html = @@file files/passwordCreatedEmail.html
password_created_email_text = @@file files/passwordCreatedEmail.txt
password_reset_pending_subject = {0} reset password request
password_reset_pending_email_html = @@file files/passwordResetPending.html
password_reset_pending_email_text = @@file files/passwordResetPending.txt
password_reset_complete_subject = Your {0} password changed.
password_reset_complete_email_html = @@file files/passwordResetComplete.html
password_reset_complete_email_text = @@file files/passwordResetComplete.txt
reset_your_password = Reset your Password
first_time_login = First time log in
@ -193,8 +179,6 @@ password_saved_please_login = Your password has been saved. Please log in.
please_provide_contact_information = Please provide your contact information to finish creating your account.
first_time_login_note = Note: An email will be sent to the address entered above notifying \
that an account has been created.
first_time_external_email_html = @@file files/accountFirstTimeExternal.html
first_time_external_email_text = @@file files/accountFirstTimeExternal.txt
myAccount_heading = My account
myAccount_confirm_changes = Your changes have been saved.

View file

@ -1,39 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
{2} {3}
</p>
<p>
<strong>Congratulations!</strong>
</p>
<p>
We have created your new account on {0}, associated with {4}.
</p>
<p>
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon for 30 days.
</p>
<p>
Click the link below to create your password for your new account using our secure server.
</p>
<p>
<a href="{5}" title="password">{5}</a>
</p>
<p>
If the link above doesn't work, you can copy and paste the link directly into your browser's address bar.
</p>
<p>
Thanks!
</p>
</body>
</html>

View file

@ -1,17 +0,0 @@
{2} {3}
Congratulations!
We have created your new account on {0},
associated with {4}.
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon for 30 days.
Paste the link below into your browser's address bar to create your password
for your new account using our secure server.
{5}
Thanks!

View file

@ -1,22 +0,0 @@
<html>
<head>
<title>${1}</title>
</head>
<body>
<p>
${2} ${3}
</p>
<p>
<strong>Congratulations!</strong>
</p>
<p>
We have created your new VIVO account associated with ${4}.
</p>
<p>
Thanks!
</p>
</body>
</html>

View file

@ -1,9 +0,0 @@
${2} ${3}
Congratulations!
We have created your new VIVO account associated with
${4}.
Thanks!

View file

@ -1,19 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
Hi, {2} ${3}
</p>
<p>
You recently changed the email address associated with
${2} ${3}
</p>
<p>
Thank you.
</p>
</body>
</html>

View file

@ -1,6 +0,0 @@
Hi, {2} {3}
You recently changed the email address associated with
{2} {3}
Thank you.

View file

@ -1,22 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
{2} {3}
</p>
<p>
<strong>Congratulations!</strong>
</p>
<p>
We have created your new {0} account associated with {4}.
</p>
<p>
Thanks!
</p>
</body>
</html>

View file

@ -1,8 +0,0 @@
{2} {3}
Congratulations!
We have created your new {0} account associated with
{4}
Thanks!

View file

@ -1,22 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
{2} {3}
</p>
<p>
<strong>Password successfully created.</strong>
</p>
<p>
Your new password associated with {4} has been created.
</p>
<p>
Thank you.
</p>
</body>
</html>

View file

@ -1,8 +0,0 @@
{2} {3}
Password successfully created.
Your new password associated with {4}
has been created.
Thank you.

View file

@ -1,34 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
Dear {2} {3}:
</p>
<p>
We have received a request to reset the password for your {0} account ({4}).
</p>
<p>
Please follow the instructions below to proceed with your password reset.
</p>
<p>
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
</p>
<p>
Click on the link below or paste it into your browser's address bar to reset your password
using our secure server.
</p>
<p>
<a href="{5}" title="password">{5}</a>
</p>
<p>Thank you!</p>
</body>
</html>

View file

@ -1,16 +0,0 @@
Dear {2} {3}:
We have received a request to reset the password for your {0} account
({4}).
Please follow the instructions below to proceed with your password reset.
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
Paste the link below into your browser's address bar to reset your password
using our secure server.
{5}
Thank you!

View file

@ -1,22 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
{2} {3}
</p>
<p>
<strong>Password successfully changed.</strong>
</p>
<p>
Your new password associated with {4} has been changed.
</p>
<p>
Thank you.
</p>
</body>
</html>

View file

@ -1,8 +0,0 @@
{2} {3}
Password successfully changed.
Your new password associated with {4}
has been changed.
Thank you.

View file

@ -1,34 +0,0 @@
<html>
<head>
<title>{1}</title>
</head>
<body>
<p>
Dear {2} {3}:
</p>
<p>
We have received a request to reset the password for your {0} account ({4}).
</p>
<p>
Please follow the instructions below to proceed with your password reset.
</p>
<p>
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
</p>
<p>
Click on the link below or paste it into your browser's address bar to reset your password
using our secure server.
</p>
<p>
<a href="{5}" title="password">{5}</a>
</p>
<p>Thank you!</p>
</body>
</html>

View file

@ -1,16 +0,0 @@
Dear {2} {3}:
We have received a request to reset the password for your {0} account
({4}).
Please follow the instructions below to proceed with your password reset.
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
Paste the link below into your browser's address bar to reset your password
using our secure server.
{5}
Thank you!

View file

@ -2,22 +2,67 @@
<#-- Confirmation that an account has been created. -->
<#assign strings = i18n() />
<#assign subject = "Your ${siteName} account has been created." />
<#assign subject = strings.account_created(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign html = strings.account_created_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress,
passwordLink) />
<p>
<strong>Congratulations!</strong>
</p>
<#assign text = strings.account_created_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress,
passwordLink) />
<p>
We have created your new account on ${siteName}, associated with ${userAccount.emailAddress}.
</p>
<@email subject=subject html=html text=text />
<p>
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon for 30 days.
</p>
<p>
Click the link below to create your password for your new account using our secure server.
</p>
<p>
<a href="${passwordLink}" title="password">${passwordLink}</a>
</p>
<p>
If the link above doesn't work, you can copy and paste the link directly into your browser's address bar.
</p>
<p>
Thanks!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Congratulations!
We have created your new account on ${siteName},
associated with ${userAccount.emailAddress}.
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon for 30 days.
Paste the link below into your browser's address bar to create your password
for your new account using our secure server.
${passwordLink}
Thanks!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,18 +2,42 @@
<#-- Confirmation that an account has been created. -->
<#assign subject = strings.account_created(siteName) />
<#assign subject = "Your ${siteName} account has been created." />
<#assign html = strings.account_created_external_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign text = string.account_created_external_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
<strong>Congratulations!</strong>
</p>
<@email subject=subject html=html text=text />
<p>
We have created your new VIVO account associated with ${userAccount.emailAddress}.
</p>
<p>
Thanks!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Congratulations!
We have created your new VIVO account associated with
${userAccount.emailAddress}.
Thanks!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,20 +2,37 @@
<#-- Confirmation that the user has changed his email account. -->
<#assign strings = i18n() />
<#assign subject = "Your ${siteName} email account has been changed." />
<#assign subject = strings.email_changed_subject(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
Hi, ${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign html = strings.email_changed_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
You recently changed the email address associated with
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign text = strings.email_changed_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
Thank you.
</p>
</body>
</html>
</#assign>
<#assign text>
Hi, ${userAccount.firstName} ${userAccount.lastName}
You recently changed the email address associated with
${userAccount.firstName} ${userAccount.lastName}
Thank you.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,20 +2,42 @@
<#-- Confirmation that an account has been created for an externally-authenticated user. -->
<#assign strings = i18n() />
<#assign subject = "Your ${siteName} account has been created." />
<#assign subject = strings.account_created(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign html = strings.first_time_external_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
<strong>Congratulations!</strong>
</p>
<#assign text = strings.first_time_external_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
We have created your new VIVO account associated with ${userAccount.emailAddress}.
</p>
<@email subject=subject html=html text=text />
<p>
Thanks!
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Congratulations!
We have created your new VIVO account associated with
${userAccount.emailAddress}.
Thanks!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,20 +2,42 @@
<#-- Confirmation that an password has been created. -->
<#assign strings = i18n() />
<#assign subject = "Your ${siteName} password has successfully been created." />
<#assign subject = strings.password_created_subject(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign html = strings.password_created_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
<strong>Password successfully created.</strong>
</p>
<#assign text = strings.password_created_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
Your new password associated with ${userAccount.emailAddress} has been created.
</p>
<@email subject=subject html=html text=text />
<p>
Thank you.
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Password successfully created.
Your new password associated with ${userAccount.emailAddress}
has been created.
Thank you.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,20 +2,43 @@
<#-- Confirmation that a password has been reset. -->
<#assign strings = i18n() />
<#assign subject = "Your ${siteName} password changed." />
<#assign subject = strings.password_reset_complete_subject(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<#assign html = strings.password_reset_complete_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<body>
<p>
${userAccount.firstName} ${userAccount.lastName}
</p>
<#assign text = strings.password_reset_complete_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress) />
<p>
<strong>Password successfully changed.</strong>
</p>
<@email subject=subject html=html text=text />
<p>
Your new password associated with ${userAccount.emailAddress} has been changed.
</p>
<p>
Thank you.
</p>
</body>
</html>
</#assign>
<#assign text>
${userAccount.firstName} ${userAccount.lastName}
Password successfully changed.
Your new password associated with ${userAccount.emailAddress}
has been changed.
Thank you.
</#assign>
<@email subject=subject html=html text=text />

View file

@ -2,22 +2,60 @@
<#-- Confirmation email for user account password reset -->
<#assign strings = i18n() />
<#assign subject = "${siteName} reset password request" />
<#assign subject = strings.password_reset_pending_subject(siteName) />
<#assign html>
<html>
<head>
<title>${subject}</title>
</head>
<body>
<p>
Dear ${userAccount.firstName} ${userAccount.lastName}:
</p>
<p>
We have received a request to reset the password for your ${siteName} account (${userAccount.emailAddress}).
</p>
<p>
Please follow the instructions below to proceed with your password reset.
</p>
<p>
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
</p>
<p>
Click on the link below or paste it into your browser's address bar to reset your password
using our secure server.
</p>
<p>${passwordLink}</p>
<p>Thank you!</p>
</body>
</html>
</#assign>
<#assign html = strings.password_reset_pending_email_html(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress,
passwordLink) />
<#assign text>
Dear ${userAccount.firstName} ${userAccount.lastName}:
We have received a request to reset the password for your ${siteName} account
(${userAccount.emailAddress}).
<#assign text = strings.password_reset_pending_email_text(siteName,
subject,
userAccount.firstName,
userAccount.lastName,
userAccount.emailAddress,
passwordLink) />
Please follow the instructions below to proceed with your password reset.
<@email subject=subject html=html text=text />
If you did not request this new account you can safely ignore this email.
This request will expire if not acted upon within 30 days.
Paste the link below into your browser's address bar to reset your password
using our secure server.
${passwordLink}
Thank you!
</#assign>
<@email subject=subject html=html text=text />

View file

@ -4,7 +4,6 @@
<#import "lib-properties.ftl" as p>
<#assign subjectUri = individual.controlPanelUrl()?split("=") >
<#assign nameForOtherGroup = nameForOtherGroup!"other">
<#if (propertyGroups.all)??>
<#assign groups = propertyGroups.all>
@ -13,6 +12,7 @@
<nav id="property-group-menu" role="navigation">
<ul role="list">
<#list groups as group>
<#if (group.properties?size > 0) >
<#assign groupname = group.getName(nameForOtherGroup)>
<#if groupname?has_content>
<#--create property group html id is the function that will replace all spaces with underscore to make a valid id-->
@ -21,13 +21,15 @@
function to capitalize all except function words. -->
<li role="listitem"><a href="#${groupnameHtmlId}" title="${i18n().group_name}">${groupname?capitalize}</a></li>
</#if>
</#if>
</#list>
</ul>
</nav>
</#if>
</#if>
</#if>
</#if>
</#if>
<#list propertyGroups.all as group>
<#if (group.properties?size > 0)>
<#assign groupName = group.getName(nameForOtherGroup)>
<#assign verbose = (verbosePropertySwitch.currentValue)!false>
@ -50,4 +52,5 @@
<#-- List the properties in the group -->
<#include "individual-properties.ftl">
</section> <!-- end property-group -->
</#if>
</#list>

View file

@ -11,14 +11,14 @@
<li class="groupTabSpacer">&nbsp;</li>
<#list propertyGroups.all as groupTabs>
<#if ( groupTabs.properties?size > 0 ) >
<#assign groupName = groupTabs.getName(nameForOtherGroup)>
<#if groupName?has_content>
<#--the function replaces spaces in the name with underscores, also called for the property group menu-->
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<#else>
<#assign groupName = "${i18n().properties_capitalized}">
<#assign groupNameHtmlId = "${i18n().properties}" >
</#if>
<#assign groupName = groupTabs.getName(nameForOtherGroup)>
<#if groupName?has_content>
<#--the function replaces spaces in the name with underscores, also called for the property group menu-->
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<#else>
<#assign groupName = "${i18n().properties_capitalized}">
<#assign groupNameHtmlId = "${i18n().properties}" >
</#if>
<#if tabCount = 1 >
<li class="selectedGroupTab clickable" groupName="${groupNameHtmlId}">${groupName?capitalize}</li>
<li class="groupTabSpacer">&nbsp;</li>
@ -35,30 +35,32 @@
</#if>
</ul>
<#list propertyGroups.all as group>
<#assign groupName = group.getName(nameForOtherGroup)>
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<#assign verbose = (verbosePropertySwitch.currentValue)!false>
<section id="${groupNameHtmlId}" class="property-group" role="region" style="<#if (sectionCount > 1) >display:none<#else>display:block</#if>">
<nav id="scroller" class="scroll-up hidden" role="navigation">
<a href="#branding" title="${i18n().scroll_to_menus}" >
<img src="${urls.images}/individual/scroll-up.gif" alt="${i18n().scroll_to_menus}" />
</a>
</nav>
<#if (group.properties?size > 0)>
<#assign groupName = group.getName(nameForOtherGroup)>
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<#assign verbose = (verbosePropertySwitch.currentValue)!false>
<section id="${groupNameHtmlId}" class="property-group" role="region" style="<#if (sectionCount > 1) >display:none<#else>display:block</#if>">
<nav id="scroller" class="scroll-up hidden" role="navigation">
<a href="#branding" title="${i18n().scroll_to_menus}" >
<img src="${urls.images}/individual/scroll-up.gif" alt="${i18n().scroll_to_menus}" />
</a>
</nav>
<#-- Display the group heading -->
<#if groupName?has_content>
<#--the function replaces spaces in the name with underscores, also called for the property group menu-->
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<h2 id="${groupNameHtmlId}" pgroup="tabs" class="hidden">${groupName?capitalize}</h2>
<#else>
<h2 id="properties" pgroup="tabs" class="hidden">${i18n().properties_capitalized}</h2>
</#if>
<#-- Display the group heading -->
<#if groupName?has_content>
<#--the function replaces spaces in the name with underscores, also called for the property group menu-->
<#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >
<h2 id="${groupNameHtmlId}" pgroup="tabs" class="hidden">${groupName?capitalize}</h2>
<#else>
<h2 id="properties" pgroup="tabs" class="hidden">${i18n().properties_capitalized}</h2>
</#if>
<div id="${groupNameHtmlId}Group" >
<#-- List the properties in the group -->
<#include "individual-properties.ftl">
</div>
</section> <!-- end property-group -->
<#assign sectionCount = 2 >
</section> <!-- end property-group -->
<#assign sectionCount = 2 >
</#if>
</#list>
<script>
var individualLocalName = "${individual.localName}";