commit
48c88d3d3e
110 changed files with 52884 additions and 1421 deletions
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
|
@ -14,12 +14,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
path: Vitro
|
path: Vitro
|
||||||
|
|
||||||
- name: Checkout vitro languages
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
repository: vivo-project/Vitro-languages
|
|
||||||
path: Vitro-languages
|
|
||||||
|
|
||||||
- name: Maven Cache
|
- name: Maven Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
|
@ -34,7 +28,5 @@ jobs:
|
||||||
|
|
||||||
- name: Maven Build
|
- name: Maven Build
|
||||||
run: |
|
run: |
|
||||||
cd ./Vitro-languages
|
cd ./Vitro
|
||||||
mvn clean install
|
|
||||||
cd ../Vitro
|
|
||||||
mvn clean install
|
mvn clean install
|
||||||
|
|
|
@ -6,8 +6,6 @@ import java.lang.reflect.Method;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -17,6 +15,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -272,6 +271,37 @@ public class FormUtils {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Option> makeOptionListOfNotDisjointClasses(WebappDaoFactory wadf, String baseVclassUri, String selectedUri) {
|
||||||
|
VClassDao vClassDao = wadf.getVClassDao();
|
||||||
|
Set<String> uris = getNotDisjointClassUris(wadf, baseVclassUri, vClassDao);
|
||||||
|
uris.add(baseVclassUri);
|
||||||
|
|
||||||
|
List<Option> options = new LinkedList<>();
|
||||||
|
for (String vclassUri : uris) {
|
||||||
|
VClass vclass = vClassDao.getVClassByURI(vclassUri);
|
||||||
|
Option option = new Option();
|
||||||
|
option.setValue(vclass.getURI());
|
||||||
|
option.setBody(vclass.getPickListName());
|
||||||
|
options.add(option);
|
||||||
|
if (Objects.equals(selectedUri, vclass.getURI())) {
|
||||||
|
option.setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options.sort((o1, o2) -> o1.getBody().compareTo(o2.getBody()));
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> getNotDisjointClassUris(WebappDaoFactory wadf, String classUri, VClassDao vClassDao) {
|
||||||
|
Set<String> allClasses = wadf.getVClassDao()
|
||||||
|
.getAllVclasses()
|
||||||
|
.stream()
|
||||||
|
.map(vclass -> vclass.getURI())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Set<String> disjointClasses = new HashSet<>(vClassDao.getDisjointWithClassURIs(classUri));
|
||||||
|
allClasses.removeAll(disjointClasses);
|
||||||
|
return allClasses;
|
||||||
|
}
|
||||||
|
|
||||||
public static void beanSet(Object newObj, String field, String value) {
|
public static void beanSet(Object newObj, String field, String value) {
|
||||||
beanSet (newObj, field, value, null);
|
beanSet (newObj, field, value, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,11 @@ public class DataProperty extends Property implements Comparable<DataProperty>,
|
||||||
return rangeDatatypeURI;
|
return rangeDatatypeURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRangeVClassURI() {
|
||||||
|
return rangeDatatypeURI;
|
||||||
|
}
|
||||||
|
|
||||||
public void setRangeDatatypeURI(String rangeDatatypeURI) {
|
public void setRangeDatatypeURI(String rangeDatatypeURI) {
|
||||||
this.rangeDatatypeURI = rangeDatatypeURI;
|
this.rangeDatatypeURI = rangeDatatypeURI;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import static org.apache.jena.rdf.model.ResourceFactory.createResource;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +22,9 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||||
private String configUri;
|
private String configUri;
|
||||||
|
|
||||||
// Must not be null on insert or update. Partial identifier on delete.
|
// Must not be null on insert or update. Partial identifier on delete.
|
||||||
private String rangeURI;
|
private String rangeURI = "";
|
||||||
|
|
||||||
|
private String rootRangeURI;
|
||||||
// May be null. Partial identifier on delete.
|
// May be null. Partial identifier on delete.
|
||||||
private String domainURI;
|
private String domainURI;
|
||||||
|
|
||||||
|
@ -55,7 +59,7 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||||
*/
|
*/
|
||||||
public FauxProperty(String domainURI, String baseURI, String rangeURI) {
|
public FauxProperty(String domainURI, String baseURI, String rangeURI) {
|
||||||
super(Objects.requireNonNull(baseURI, "baseURI may not be null"));
|
super(Objects.requireNonNull(baseURI, "baseURI may not be null"));
|
||||||
this.rangeURI = rangeURI;
|
this.setRangeURI(rangeURI);
|
||||||
this.domainURI = domainURI;
|
this.domainURI = domainURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +97,11 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRangeURI(String rangeURI) {
|
public void setRangeURI(String rangeURI) {
|
||||||
this.rangeURI = rangeURI;
|
if (StringUtils.isEmpty(rangeURI)) {
|
||||||
|
this.rangeURI = "";
|
||||||
|
} else {
|
||||||
|
this.rangeURI = rangeURI;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBaseLabel() {
|
public String getBaseLabel() {
|
||||||
|
@ -105,7 +113,14 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRangeLabel() {
|
public String getRangeLabel() {
|
||||||
return (rangeLabel == null) ? localName(rangeURI) : rangeLabel;
|
if (StringUtils.isEmpty(rangeLabel)) {
|
||||||
|
if (StringUtils.isEmpty(rangeURI)) {
|
||||||
|
return "untyped";
|
||||||
|
}
|
||||||
|
return localName(rangeURI);
|
||||||
|
} else {
|
||||||
|
return rangeLabel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRangeLabel(String rangeLabel) {
|
public void setRangeLabel(String rangeLabel) {
|
||||||
|
@ -247,4 +262,12 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||||
public String getRangeVClassURI() {
|
public String getRangeVClassURI() {
|
||||||
return getRangeURI();
|
return getRangeURI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRootRangeUri(String rootRangeUri) {
|
||||||
|
this.rootRangeURI = rootRangeUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRootRangeUri() {
|
||||||
|
return rootRangeURI;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.beans;
|
||||||
|
|
||||||
import java.beans.XMLEncoder;
|
import java.beans.XMLEncoder;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class ConfigurationPropertiesSmokeTests implements
|
||||||
String vivoBundle = VIVO_BUNDLE_PREFIX + language + ".properties";
|
String vivoBundle = VIVO_BUNDLE_PREFIX + language + ".properties";
|
||||||
String vitroBundle = VITRO_BUNDLE_PREFIX + language + ".properties";
|
String vitroBundle = VITRO_BUNDLE_PREFIX + language + ".properties";
|
||||||
if (!i18nNames.contains(vivoBundle) && !i18nNames.contains(vitroBundle)) {
|
if (!i18nNames.contains(vivoBundle) && !i18nNames.contains(vitroBundle)) {
|
||||||
ss.warning(this, language + " was found in the value for "
|
ss.info(this, language + " was found in the value for "
|
||||||
+ PROPERTY_LANGUAGE_SELECTABLE + " but no corresponding "
|
+ PROPERTY_LANGUAGE_SELECTABLE + " but no corresponding "
|
||||||
+ "language file was found.");
|
+ "language file was found.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class RevisionInfoBean {
|
||||||
new Date(0), Collections.singleton(LevelRevisionInfo.DUMMY_LEVEL));
|
new Date(0), Collections.singleton(LevelRevisionInfo.DUMMY_LEVEL));
|
||||||
|
|
||||||
/** The bean is attached to the session by this name. */
|
/** The bean is attached to the session by this name. */
|
||||||
static final String ATTRIBUTE_NAME = RevisionInfoBean.class.getName();
|
public static final String ATTRIBUTE_NAME = RevisionInfoBean.class.getName();
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// static methods
|
// static methods
|
||||||
|
|
|
@ -21,7 +21,6 @@ public class Controllers {
|
||||||
|
|
||||||
public static final String ABOUT = "/about";
|
public static final String ABOUT = "/about";
|
||||||
public static final String CONTACT_URL = "/comments";
|
public static final String CONTACT_URL = "/comments";
|
||||||
public static final String TERMS_OF_USE_URL = "/termsOfUse";
|
|
||||||
public static final String SEARCH_URL = "/search";
|
public static final String SEARCH_URL = "/search";
|
||||||
public static final String ENTITY = "/entity";
|
public static final String ENTITY = "/entity";
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,6 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
||||||
|
|
||||||
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
private static class EmailStrategy extends UserAccountsAddPageStrategy {
|
||||||
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
public static final String CREATE_PASSWORD_URL = "/accounts/createPassword";
|
||||||
private static final String EMAIL_TEMPLATE_WITH_PASSWORD = "userAccounts-acctCreatedEmail.ftl";
|
|
||||||
private static final String EMAIL_TEMPLATE_NO_PASSWORD = "userAccounts-acctCreatedExternalOnlyEmail.ftl";
|
|
||||||
|
|
||||||
private boolean sentEmail;
|
private boolean sentEmail;
|
||||||
|
|
||||||
|
@ -100,15 +98,19 @@ public abstract class UserAccountsAddPageStrategy extends UserAccountsPage {
|
||||||
body.put("userAccount", page.getAddedAccount());
|
body.put("userAccount", page.getAddedAccount());
|
||||||
body.put("passwordLink", buildCreatePasswordLink());
|
body.put("passwordLink", buildCreatePasswordLink());
|
||||||
body.put("siteName", getSiteName());
|
body.put("siteName", getSiteName());
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
|
email.addRecipient(TO, page.getAddedAccount().getEmailAddress());
|
||||||
email.setSubject(i18n.text("account_created_subject", getSiteName()));
|
String subject = i18n.text("account_created_subject", getSiteName());
|
||||||
|
email.setSubject(subject);
|
||||||
if (page.isExternalAuthOnly()) {
|
if (page.isExternalAuthOnly()) {
|
||||||
email.setTemplate(EMAIL_TEMPLATE_NO_PASSWORD);
|
body.put("subject", subject);
|
||||||
|
body.put("textMessage", i18n.text("acct_created_external_only_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("acct_created_external_only_email_html_text"));
|
||||||
} else {
|
} else {
|
||||||
email.setTemplate(EMAIL_TEMPLATE_WITH_PASSWORD);
|
body.put("subject", subject);
|
||||||
|
body.put("textMessage", i18n.text("acct_created_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("acct_created_email_html_text"));
|
||||||
}
|
}
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
|
|
|
@ -56,8 +56,6 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
||||||
|
|
||||||
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
private static class EmailStrategy extends UserAccountsEditPageStrategy {
|
||||||
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
private static final String PARAMETER_RESET_PASSWORD = "resetPassword";
|
||||||
private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetPendingEmail.ftl";
|
|
||||||
|
|
||||||
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
public static final String RESET_PASSWORD_URL = "/accounts/resetPassword";
|
||||||
|
|
||||||
private boolean resetPassword;
|
private boolean resetPassword;
|
||||||
|
@ -107,11 +105,13 @@ public abstract class UserAccountsEditPageStrategy extends UserAccountsPage {
|
||||||
body.put("userAccount", page.getUpdatedAccount());
|
body.put("userAccount", page.getUpdatedAccount());
|
||||||
body.put("passwordLink", buildResetPasswordLink());
|
body.put("passwordLink", buildResetPasswordLink());
|
||||||
body.put("siteName", getSiteName());
|
body.put("siteName", getSiteName());
|
||||||
|
body.put("subject", i18n.text("password_reset_pending_email_subject"));
|
||||||
|
body.put("textMessage",i18n.text("password_reset_pending_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("password_reset_pending_email_html_text"));
|
||||||
|
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
email.addRecipient(TO, page.getUpdatedAccount().getEmailAddress());
|
||||||
email.setTemplate(EMAIL_TEMPLATE);
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
|
@ -26,8 +26,6 @@ public class UserAccountsCreatePasswordPage extends
|
||||||
.getLog(UserAccountsCreatePasswordPage.class);
|
.getLog(UserAccountsCreatePasswordPage.class);
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
private static final String TEMPLATE_NAME = "userAccounts-createPassword.ftl";
|
||||||
private static final String EMAIL_TEMPLATE = "userAccounts-passwordCreatedEmail.ftl";
|
|
||||||
|
|
||||||
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
public UserAccountsCreatePasswordPage(VitroRequest vreq) {
|
||||||
super(vreq);
|
super(vreq);
|
||||||
}
|
}
|
||||||
|
@ -73,8 +71,11 @@ public class UserAccountsCreatePasswordPage extends
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||||
email.setSubject(i18n.text("password_created_subject", getSiteName()));
|
final String subject = i18n.text("password_created_subject", getSiteName());
|
||||||
email.setTemplate(EMAIL_TEMPLATE);
|
email.setSubject(subject);
|
||||||
|
body.put("subject", subject);
|
||||||
|
body.put("textMessage", i18n.text("password_created_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("password_created_email_html_text"));
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
|
@ -52,8 +52,6 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
||||||
public static class EmailStrategy extends
|
public static class EmailStrategy extends
|
||||||
UserAccountsFirstTimeExternalPageStrategy {
|
UserAccountsFirstTimeExternalPageStrategy {
|
||||||
|
|
||||||
private static final String EMAIL_TEMPLATE = "userAccounts-firstTimeExternalEmail.ftl";
|
|
||||||
|
|
||||||
public EmailStrategy(VitroRequest vreq,
|
public EmailStrategy(VitroRequest vreq,
|
||||||
UserAccountsFirstTimeExternalPage page) {
|
UserAccountsFirstTimeExternalPage page) {
|
||||||
super(vreq, page);
|
super(vreq, page);
|
||||||
|
@ -73,8 +71,11 @@ public abstract class UserAccountsFirstTimeExternalPageStrategy extends
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, ua.getEmailAddress());
|
email.addRecipient(TO, ua.getEmailAddress());
|
||||||
email.setSubject(i18n.text("account_created_subject", getSiteName()));
|
final String subject = i18n.text("account_created_subject", getSiteName());
|
||||||
email.setTemplate(EMAIL_TEMPLATE);
|
email.setSubject(subject);
|
||||||
|
body.put("subject", subject);
|
||||||
|
body.put("textMessage", i18n.text("first_time_external_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("first_time_external_email_html_text"));
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
|
@ -108,8 +108,6 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
||||||
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
private static final String ERROR_WRONG_PASSWORD_LENGTH = "errorPasswordIsWrongLength";
|
||||||
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
private static final String ERROR_PASSWORDS_DONT_MATCH = "errorPasswordsDontMatch";
|
||||||
|
|
||||||
private static final String EMAIL_TEMPLATE = "userAccounts-confirmEmailChangedEmail.ftl";
|
|
||||||
|
|
||||||
private final String originalEmail;
|
private final String originalEmail;
|
||||||
|
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
|
@ -179,8 +177,11 @@ public abstract class UserAccountsMyAccountPageStrategy extends
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
||||||
.createNewMessage(vreq);
|
.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
email.addRecipient(TO, page.getUserAccount().getEmailAddress());
|
||||||
email.setSubject(i18n.text("email_changed_subject", getSiteName()));
|
final String subject = i18n.text("email_changed_subject", getSiteName());
|
||||||
email.setTemplate(EMAIL_TEMPLATE);
|
email.setSubject(subject);
|
||||||
|
body.put("subject", subject);
|
||||||
|
body.put("textMessage", i18n.text("confirm_email_changed_email_plain_text"));
|
||||||
|
body.put("htmlMessage", i18n.text("confirm_email_changed_email_html_text"));
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
|
@ -26,8 +26,6 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
private static final String TEMPLATE_NAME = "userAccounts-resetPassword.ftl";
|
||||||
|
|
||||||
private static final String EMAIL_TEMPLATE = "userAccounts-passwordResetCompleteEmail.ftl";
|
|
||||||
|
|
||||||
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
protected UserAccountsResetPasswordPage(VitroRequest vreq) {
|
||||||
super(vreq);
|
super(vreq);
|
||||||
}
|
}
|
||||||
|
@ -68,14 +66,16 @@ public class UserAccountsResetPasswordPage extends UserAccountsPasswordBasePage
|
||||||
|
|
||||||
private void notifyUser() {
|
private void notifyUser() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
FreemarkerEmailMessage email = FreemarkerEmailFactory.createNewMessage(vreq);
|
||||||
|
final String subject = i18n.text("password_changed_subject");
|
||||||
|
email.setSubject(subject);
|
||||||
|
|
||||||
body.put("userAccount", userAccount);
|
body.put("userAccount", userAccount);
|
||||||
body.put("siteName", getSiteName());
|
body.put("siteName", getSiteName());
|
||||||
|
body.put("subject", subject);
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory
|
body.put("textMessage", i18n.text("password_reset_complete_email_plain_text"));
|
||||||
.createNewMessage(vreq);
|
body.put("htmlMessage", i18n.text("password_reset_complete_email_html_text"));
|
||||||
email.addRecipient(TO, userAccount.getEmailAddress());
|
email.addRecipient(TO, userAccount.getEmailAddress());
|
||||||
email.setSubject(i18n.text("password_changed_subject"));
|
|
||||||
email.setTemplate(EMAIL_TEMPLATE);
|
|
||||||
email.setBodyMap(body);
|
email.setBodyMap(body);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
email.send();
|
email.send();
|
||||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
|
@ -177,6 +178,11 @@ public class DatapropEditController extends BaseEditController {
|
||||||
sortForPickList(eqProps, vreq);
|
sortForPickList(eqProps, vreq);
|
||||||
request.setAttribute("equivalentProperties", eqProps);
|
request.setAttribute("equivalentProperties", eqProps);
|
||||||
|
|
||||||
|
List<FauxProperty> fauxProps = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao().
|
||||||
|
getFauxPropertiesForBaseUri(dp.getURI());
|
||||||
|
sortForPickList(fauxProps, vreq);
|
||||||
|
request.setAttribute("fauxproperties", fauxProps);
|
||||||
|
|
||||||
ApplicationBean appBean = vreq.getAppBean();
|
ApplicationBean appBean = vreq.getAppBean();
|
||||||
|
|
||||||
request.setAttribute("epoKey",epo.getKey());
|
request.setAttribute("epoKey",epo.getKey());
|
||||||
|
|
|
@ -32,12 +32,14 @@ import edu.cornell.mannlib.vedit.validator.Validator;
|
||||||
import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator;
|
import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Datatype;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
|
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
@ -88,6 +90,8 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EpoPopulator {
|
private static class EpoPopulator {
|
||||||
|
private static final String LITERAL = "http://www.w3.org/2000/01/rdf-schema#Literal";
|
||||||
|
private static final String XML_LITERAL = "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral";
|
||||||
private final VitroRequest req;
|
private final VitroRequest req;
|
||||||
private final ServletContext ctx;
|
private final ServletContext ctx;
|
||||||
private final WebappDaoFactory wadf;
|
private final WebappDaoFactory wadf;
|
||||||
|
@ -99,6 +103,8 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
private FauxProperty beanForEditing;
|
private FauxProperty beanForEditing;
|
||||||
private Property baseProperty;
|
private Property baseProperty;
|
||||||
|
|
||||||
|
private boolean isFauxDataProperty = false;
|
||||||
|
|
||||||
EpoPopulator(HttpServletRequest req, EditProcessObject epo) {
|
EpoPopulator(HttpServletRequest req, EditProcessObject epo) {
|
||||||
this.req = new VitroRequest(req);
|
this.req = new VitroRequest(req);
|
||||||
this.ctx = req.getSession().getServletContext();
|
this.ctx = req.getSession().getServletContext();
|
||||||
|
@ -127,10 +133,19 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
this.baseProperty = req.getUnfilteredWebappDaoFactory()
|
this.baseProperty = req.getUnfilteredWebappDaoFactory()
|
||||||
.getObjectPropertyDao()
|
.getObjectPropertyDao()
|
||||||
.getObjectPropertyByURI(beanForEditing.getURI());
|
.getObjectPropertyByURI(beanForEditing.getURI());
|
||||||
|
if (this.baseProperty == null) {
|
||||||
|
this.baseProperty = req.getUnfilteredWebappDaoFactory()
|
||||||
|
.getDataPropertyDao()
|
||||||
|
.getDataPropertyByURI(beanForEditing.getURI());
|
||||||
|
isFauxDataProperty = true;
|
||||||
|
}
|
||||||
|
|
||||||
addCheckboxValuesToTheRequest();
|
addCheckboxValuesToTheRequest();
|
||||||
|
|
||||||
setFieldValidators();
|
if (!isFauxDataProperty) {
|
||||||
|
setFieldValidators();
|
||||||
|
}
|
||||||
|
|
||||||
setListeners();
|
setListeners();
|
||||||
setForwarders();
|
setForwarders();
|
||||||
|
|
||||||
|
@ -150,8 +165,7 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
return newFauxProperty(baseUri);
|
return newFauxProperty(baseUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri,
|
FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri, rangeUri);
|
||||||
rangeUri);
|
|
||||||
if (bean == null) {
|
if (bean == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"FauxProperty does not exist for <" + domainUri
|
"FauxProperty does not exist for <" + domainUri
|
||||||
|
@ -168,7 +182,11 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
private FauxProperty newFauxProperty(String baseUri) {
|
private FauxProperty newFauxProperty(String baseUri) {
|
||||||
FauxProperty fp = new FauxProperty(null, baseUri, null);
|
FauxProperty fp = new FauxProperty(null, baseUri, null);
|
||||||
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
||||||
ObjectProperty base = opDao.getObjectPropertyByURI(baseUri);
|
DataPropertyDao dpDao = wadf.getDataPropertyDao();
|
||||||
|
Property base = opDao.getObjectPropertyByURI(baseUri);
|
||||||
|
if (base == null) {
|
||||||
|
base = dpDao.getDataPropertyByURI(baseUri);
|
||||||
|
}
|
||||||
fp.setGroupURI(base.getGroupURI());
|
fp.setGroupURI(base.getGroupURI());
|
||||||
fp.setRangeURI(base.getRangeVClassURI());
|
fp.setRangeURI(base.getRangeVClassURI());
|
||||||
fp.setDomainURI(base.getDomainVClassURI());
|
fp.setDomainURI(base.getDomainVClassURI());
|
||||||
|
@ -270,7 +288,7 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
list.addAll(FormUtils.makeVClassOptionList(wadf,
|
list.addAll(FormUtils.makeVClassOptionList(wadf,
|
||||||
beanForEditing.getDomainURI()));
|
beanForEditing.getDomainURI()));
|
||||||
} else {
|
} else {
|
||||||
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf,
|
list.addAll(FormUtils.makeOptionListOfNotDisjointClasses(wadf,
|
||||||
baseProperty.getDomainVClassURI(),
|
baseProperty.getDomainVClassURI(),
|
||||||
beanForEditing.getDomainURI()));
|
beanForEditing.getDomainURI()));
|
||||||
}
|
}
|
||||||
|
@ -279,12 +297,20 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Option> buildRangeOptionList() {
|
private List<Option> buildRangeOptionList() {
|
||||||
|
if (isFauxDataProperty) {
|
||||||
|
return buildDataPropOptionList();
|
||||||
|
} else {
|
||||||
|
return buildObjectPropOptionList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Option> buildObjectPropOptionList() {
|
||||||
List<Option> list = new ArrayList<>();
|
List<Option> list = new ArrayList<>();
|
||||||
if (baseProperty.getRangeVClassURI() == null) {
|
if (baseProperty.getRangeVClassURI() == null) {
|
||||||
list.addAll(FormUtils.makeVClassOptionList(wadf,
|
list.addAll(FormUtils.makeVClassOptionList(wadf,
|
||||||
beanForEditing.getRangeURI()));
|
beanForEditing.getRangeURI()));
|
||||||
} else {
|
} else {
|
||||||
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf,
|
list.addAll(FormUtils.makeOptionListOfNotDisjointClasses(wadf,
|
||||||
baseProperty.getRangeVClassURI(),
|
baseProperty.getRangeVClassURI(),
|
||||||
beanForEditing.getRangeURI()));
|
beanForEditing.getRangeURI()));
|
||||||
if (containsVCardKind(list)) {
|
if (containsVCardKind(list)) {
|
||||||
|
@ -295,6 +321,43 @@ public class FauxPropertyRetryController extends BaseEditController {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Option> buildDataPropOptionList() {
|
||||||
|
List<Option> list = new ArrayList<>();
|
||||||
|
String rangeUri = baseProperty.getRangeVClassURI();
|
||||||
|
if (rangeUri == null) {
|
||||||
|
Option option = new Option();
|
||||||
|
option.setValue("");
|
||||||
|
option.setBody("Untyped");
|
||||||
|
option.setSelected(true);
|
||||||
|
list.add(option);
|
||||||
|
} else if (rangeUri.equals(LITERAL)) {
|
||||||
|
Option option = new Option();
|
||||||
|
option.setValue(rangeUri);
|
||||||
|
option.setBody("Literal");
|
||||||
|
option.setSelected(true);
|
||||||
|
list.add(option);
|
||||||
|
} else if (rangeUri.equals(XML_LITERAL)) {
|
||||||
|
Option option = new Option();
|
||||||
|
option.setValue(rangeUri);
|
||||||
|
option.setBody("XML Literal");
|
||||||
|
option.setSelected(true);
|
||||||
|
list.add(option);
|
||||||
|
} else {
|
||||||
|
Datatype dataType = wadf.getDatatypeDao().getDatatypeByURI(rangeUri);
|
||||||
|
Option option = new Option();
|
||||||
|
if (dataType != null) {
|
||||||
|
option.setValue(dataType.getUri());
|
||||||
|
option.setBody(dataType.getName());
|
||||||
|
} else {
|
||||||
|
option.setValue(rangeUri);
|
||||||
|
option.setBody(rangeUri);
|
||||||
|
}
|
||||||
|
option.setSelected(true);
|
||||||
|
list.add(option);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
private static final String VCARD_KIND_URI = "http://www.w3.org/2006/vcard/ns#Kind";
|
private static final String VCARD_KIND_URI = "http://www.w3.org/2006/vcard/ns#Kind";
|
||||||
private static final String VCARD_NAMESPACE = "http://www.w3.org/2006/vcard/ns#";
|
private static final String VCARD_NAMESPACE = "http://www.w3.org/2006/vcard/ns#";
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import static javax.mail.Message.RecipientType.TO;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.nio.charset.Charset;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -41,6 +41,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
||||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
|
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
|
||||||
|
@ -67,7 +69,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
|
|
||||||
// error templates
|
// error templates
|
||||||
ERROR_DISPLAY("error-display.ftl"),
|
ERROR_DISPLAY("error-display.ftl"),
|
||||||
ERROR_EMAIL("error-email.ftl"),
|
|
||||||
ERROR_MESSAGE("error-message.ftl"),
|
ERROR_MESSAGE("error-message.ftl"),
|
||||||
STANDARD_ERROR("error-standard.ftl"),
|
STANDARD_ERROR("error-standard.ftl"),
|
||||||
TITLED_ERROR_MESSAGE("error-titled.ftl"),
|
TITLED_ERROR_MESSAGE("error-titled.ftl"),
|
||||||
|
@ -161,7 +162,8 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
adminErrorData.put("cause", cause);
|
adminErrorData.put("cause", cause);
|
||||||
|
|
||||||
adminErrorData.put("datetime", new Date());
|
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
|
||||||
|
adminErrorData.put("datetime", dateformat.format(new Date()));
|
||||||
|
|
||||||
templateMap.put("errorOnHomePage", this instanceof HomePageController);
|
templateMap.put("errorOnHomePage", this instanceof HomePageController);
|
||||||
|
|
||||||
|
@ -175,7 +177,11 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
} else if (FreemarkerEmailFactory.isConfigured(vreq)) {
|
} else if (FreemarkerEmailFactory.isConfigured(vreq)) {
|
||||||
FreemarkerEmailMessage email = FreemarkerEmailFactory.createNewMessage(vreq);
|
FreemarkerEmailMessage email = FreemarkerEmailFactory.createNewMessage(vreq);
|
||||||
email.addRecipient(TO, email.getReplyToAddress());
|
email.addRecipient(TO, email.getReplyToAddress());
|
||||||
email.setTemplate(Template.ERROR_EMAIL.toString());
|
I18nBundle i18n = I18n.bundle(vreq);
|
||||||
|
addSiteName(vreq, adminErrorData);
|
||||||
|
adminErrorData.put("subject", i18n.text("application_error_email_subject"));
|
||||||
|
adminErrorData.put("textMessage", i18n.text("application_error_email_plain_text"));
|
||||||
|
adminErrorData.put("htmlMessage", i18n.text("application_error_email_html_text"));
|
||||||
email.setBodyMap(adminErrorData);
|
email.setBodyMap(adminErrorData);
|
||||||
email.processTemplate();
|
email.processTemplate();
|
||||||
sentEmail = email.send();
|
sentEmail = email.send();
|
||||||
|
@ -193,6 +199,16 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSiteName(VitroRequest vreq, Map<String, Object> adminErrorData) {
|
||||||
|
try {
|
||||||
|
ApplicationBean appBean = vreq.getAppBean();
|
||||||
|
String appName = appBean.getApplicationName();
|
||||||
|
adminErrorData.put("siteName", appName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
|
@ -8,39 +8,40 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
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.freemarker.responsevalues.TemplateResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
|
||||||
@WebServlet(name = "ListFauxPropertiesController", urlPatterns = {"/listFauxProperties"} )
|
@WebServlet(name = "ListFauxPropertiesController", urlPatterns = { "/listFauxProperties" })
|
||||||
public class ListFauxPropertiesController extends FreemarkerHttpServlet {
|
public class ListFauxPropertiesController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ListFauxPropertiesController.class.getName());
|
private static final Log log = LogFactory.getLog(ListFauxPropertiesController.class.getName());
|
||||||
|
|
||||||
private static final String TEMPLATE_NAME = "siteAdmin-fauxPropertiesList.ftl";
|
private static final String TEMPLATE_NAME = "siteAdmin-fauxPropertiesList.ftl";
|
||||||
|
|
||||||
private ObjectPropertyDao opDao = null;
|
private String notFoundMessage = "";
|
||||||
private PropertyGroupDao pgDao = null;
|
|
||||||
private FauxPropertyDao fpDao = null;
|
|
||||||
private String notFoundMessage = "";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AuthorizationRequest requiredActions(VitroRequest vreq) {
|
protected AuthorizationRequest requiredActions(VitroRequest vreq) {
|
||||||
return SimplePermission.EDIT_ONTOLOGY.ACTION;
|
return SimplePermission.EDIT_ONTOLOGY.ACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||||
|
@ -50,176 +51,303 @@ public class ListFauxPropertiesController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
String displayOption = "";
|
String displayOption = "";
|
||||||
|
|
||||||
if ( vreq.getParameter("displayOption") != null ) {
|
if (vreq.getParameter("displayOption") != null) {
|
||||||
displayOption = vreq.getParameter("displayOption");
|
displayOption = vreq.getParameter("displayOption");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
displayOption = "listing";
|
displayOption = "listing";
|
||||||
}
|
}
|
||||||
body.put("displayOption", displayOption);
|
body.put("displayOption", displayOption);
|
||||||
|
|
||||||
if ( displayOption.equals("listing") ) {
|
if (displayOption.equals("listing")) {
|
||||||
body.put("pageTitle", "Faux Property Listing");
|
body.put("pageTitle", "Faux Property Listing");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
body.put("pageTitle", "Faux Properties by Base Property");
|
body.put("pageTitle", "Faux Properties by Base Property");
|
||||||
}
|
}
|
||||||
|
List<ObjectProperty> objectProps = getOPDao(vreq).getRootObjectProperties();
|
||||||
|
List<DataProperty> dataProps = getDPDao(vreq).getRootDataProperties();
|
||||||
|
Map<String, Object> allFauxProps = new TreeMap<String, Object>();
|
||||||
|
|
||||||
opDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao();
|
// get the faux depending on the display option
|
||||||
fpDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao();
|
if (displayOption.equals("listing")) {
|
||||||
pgDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao();
|
allFauxProps.putAll(getFauxPropertyList(objectProps, vreq));
|
||||||
|
allFauxProps.putAll(getFauxDataPropertyList(dataProps, vreq));
|
||||||
List<ObjectProperty> objectProps = null;
|
} else {
|
||||||
objectProps = opDao.getRootObjectProperties();
|
allFauxProps.putAll(getFauxByBaseList(objectProps, vreq));
|
||||||
|
allFauxProps.putAll(getFauxDataPropsByBaseList(dataProps, vreq));
|
||||||
Map<String, Object> allFauxProps = new TreeMap<String, Object>();
|
|
||||||
// get the faux depending on the display option
|
|
||||||
if ( displayOption.equals("listing") ) {
|
|
||||||
allFauxProps = getFauxPropertyList(objectProps);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
allFauxProps = getFauxByBaseList(objectProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug(allFauxProps.toString());
|
log.debug(allFauxProps.toString());
|
||||||
|
|
||||||
if ( notFoundMessage.length() == 0 ) {
|
if (notFoundMessage.length() == 0) {
|
||||||
body.put("message", notFoundMessage);
|
body.put("message", notFoundMessage);
|
||||||
}
|
} else {
|
||||||
else {
|
body.put("fauxProps", allFauxProps);
|
||||||
body.put("fauxProps", allFauxProps);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
log.error(t, t);
|
||||||
}
|
}
|
||||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeMap<String, Object> getFauxPropertyList(List<ObjectProperty> objectProps) {
|
private PropertyGroupDao getPGDao(VitroRequest vreq) {
|
||||||
List<FauxProperty> fauxProps = null;
|
return vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao();
|
||||||
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
|
}
|
||||||
if ( objectProps != null ) {
|
|
||||||
|
private FauxPropertyDao getFPDao(VitroRequest vreq) {
|
||||||
|
return vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao();
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataPropertyDao getDPDao(VitroRequest vreq) {
|
||||||
|
return vreq.getUnfilteredAssertionsWebappDaoFactory().getDataPropertyDao();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectPropertyDao getOPDao(VitroRequest vreq) {
|
||||||
|
return vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeMap<String, Object> getFauxPropertyList(List<ObjectProperty> objectProps, VitroRequest vreq) {
|
||||||
|
List<FauxProperty> fauxProps = null;
|
||||||
|
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
|
||||||
|
if (objectProps != null) {
|
||||||
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
||||||
if ( !opIt.hasNext()) {
|
if (!opIt.hasNext()) {
|
||||||
notFoundMessage = "No object properties found.";
|
notFoundMessage = "No object properties found.";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
while (opIt.hasNext()) {
|
while (opIt.hasNext()) {
|
||||||
|
|
||||||
ObjectProperty op = opIt.next();
|
ObjectProperty op = opIt.next();
|
||||||
String baseURI = op.getURI();
|
String baseURI = op.getURI();
|
||||||
fauxProps = fpDao.getFauxPropertiesForBaseUri(baseURI);
|
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
|
||||||
if ( fauxProps != null ) {
|
if (fauxProps != null) {
|
||||||
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
||||||
if ( !fpIt.hasNext()) {
|
if (!fpIt.hasNext()) {
|
||||||
notFoundMessage = "No faux properties found.";
|
notFoundMessage = "No faux properties found.";
|
||||||
}
|
} else {
|
||||||
else {
|
while (fpIt.hasNext()) {
|
||||||
while (fpIt.hasNext()) {
|
// No point in getting these unless we have a
|
||||||
// No point in getting these unless we have a faux property
|
// faux property
|
||||||
String baseLabel = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op);
|
String baseLabel = getBaseLabel(op, false);
|
||||||
String baseLocalName = op.getLocalNameWithPrefix();
|
// get the info we need from the faux property
|
||||||
baseLabel = baseLabel.substring(0,baseLabel.indexOf("("));
|
FauxProperty fp = fpIt.next();
|
||||||
baseLabel += "(" + baseLocalName + ")";
|
String fauxLabel = fp.getDisplayName();
|
||||||
// get the info we need from the faux property
|
String rangeLabel = fp.getRangeLabel();
|
||||||
FauxProperty fp = fpIt.next();
|
String rangeURI = fp.getRangeURI();
|
||||||
String fauxLabel = fp.getDisplayName();
|
String domainLabel = fp.getDomainLabel();
|
||||||
String rangeLabel = fp.getRangeLabel();
|
String domainURI = fp.getDomainURI();
|
||||||
String rangeURI = fp.getRangeURI();
|
String groupURI = fp.getGroupURI();
|
||||||
String domainLabel = fp.getDomainLabel();
|
// FauxProperty only gets groupURI but we want
|
||||||
String domainURI = fp.getDomainURI();
|
// the label
|
||||||
String groupURI = fp.getGroupURI();
|
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
|
||||||
// FauxProperty only gets groupURI but we want the label
|
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
|
||||||
PropertyGroup pGroup = pgDao.getGroupByURI(groupURI);
|
// store all the strings in a hash with the faux
|
||||||
String groupLabel = ( pGroup == null ) ? "unspecified" : pGroup.getName();
|
// property label as the key
|
||||||
// store all the strings in a hash with the faux property label as the key
|
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
||||||
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
tmpHash.put("base", baseLabel);
|
||||||
tmpHash.put("base", baseLabel);
|
tmpHash.put("baseURI", baseURI);
|
||||||
tmpHash.put("baseURI", baseURI);
|
tmpHash.put("group", groupLabel);
|
||||||
tmpHash.put("group", groupLabel);
|
tmpHash.put("range", rangeLabel);
|
||||||
tmpHash.put("range", rangeLabel);
|
tmpHash.put("rangeURI", rangeURI);
|
||||||
tmpHash.put("rangeURI", rangeURI);
|
tmpHash.put("domain", domainLabel);
|
||||||
tmpHash.put("domain", domainLabel);
|
tmpHash.put("domainURI", domainURI);
|
||||||
tmpHash.put("domainURI", domainURI);
|
tmpHash.put("editUrl", "propertyEdit");
|
||||||
// add the faux and its details to the treemap
|
|
||||||
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
// add the faux and its details to the treemap
|
||||||
}
|
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return theFauxProps;
|
return theFauxProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeMap<String, Object> getFauxByBaseList(List<ObjectProperty> objectProps) {
|
private TreeMap<String, Object> getFauxByBaseList(List<ObjectProperty> objectProps, VitroRequest vreq) {
|
||||||
List<FauxProperty> fauxProps = null;
|
List<FauxProperty> fauxProps = null;
|
||||||
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
|
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
|
||||||
if ( objectProps != null ) {
|
if (objectProps != null) {
|
||||||
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
||||||
if ( !opIt.hasNext()) {
|
if (!opIt.hasNext()) {
|
||||||
notFoundMessage = "No object properties found.";
|
notFoundMessage = "No object properties found.";
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
while (opIt.hasNext()) {
|
while (opIt.hasNext()) {
|
||||||
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
|
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
|
||||||
ObjectProperty op = opIt.next();
|
ObjectProperty op = opIt.next();
|
||||||
String baseURI = op.getURI();
|
String baseURI = op.getURI();
|
||||||
fauxProps = fpDao.getFauxPropertiesForBaseUri(baseURI);
|
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
|
||||||
|
|
||||||
if ( fauxProps != null ) {
|
if (fauxProps != null) {
|
||||||
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
||||||
if ( !fpIt.hasNext()) {
|
if (!fpIt.hasNext()) {
|
||||||
notFoundMessage = "No faux properties found.";
|
notFoundMessage = "No faux properties found.";
|
||||||
}
|
} else {
|
||||||
else {
|
String baseLabel = getBaseLabel(op, true);
|
||||||
String baseLabel = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op);
|
while (fpIt.hasNext()) {
|
||||||
String baseLocalName = op.getLocalNameWithPrefix();
|
// get the info we need from the faux property
|
||||||
baseLabel = baseLabel.substring(0,baseLabel.indexOf("("));
|
FauxProperty fp = fpIt.next();
|
||||||
baseLabel += "(" + baseLocalName + ")" + "|" + baseURI;
|
String fauxLabel = fp.getDisplayName();
|
||||||
while (fpIt.hasNext()) {
|
String rangeLabel = fp.getRangeLabel();
|
||||||
// get the info we need from the faux property
|
String rangeURI = fp.getRangeURI();
|
||||||
FauxProperty fp = fpIt.next();
|
String domainLabel = fp.getDomainLabel();
|
||||||
String fauxLabel = fp.getDisplayName();
|
String domainURI = fp.getDomainURI();
|
||||||
String rangeLabel = fp.getRangeLabel();
|
String groupURI = fp.getGroupURI();
|
||||||
String rangeURI = fp.getRangeURI();
|
// FauxProperty only gets groupURI but we want
|
||||||
String domainLabel = fp.getDomainLabel();
|
// the label
|
||||||
String domainURI = fp.getDomainURI();
|
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
|
||||||
String groupURI = fp.getGroupURI();
|
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
|
||||||
// FauxProperty only gets groupURI but we want the label
|
// store all the strings in a hash with the faux
|
||||||
PropertyGroup pGroup = pgDao.getGroupByURI(groupURI);
|
// property label as the key
|
||||||
String groupLabel = ( pGroup == null ) ? "unspecified" : pGroup.getName();
|
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
||||||
// store all the strings in a hash with the faux property label as the key
|
tmpHash.put("baseURI", baseURI);
|
||||||
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
tmpHash.put("group", groupLabel);
|
||||||
tmpHash.put("baseURI", baseURI);
|
tmpHash.put("range", rangeLabel);
|
||||||
tmpHash.put("group", groupLabel);
|
tmpHash.put("rangeURI", rangeURI);
|
||||||
tmpHash.put("range", rangeLabel);
|
tmpHash.put("domain", domainLabel);
|
||||||
tmpHash.put("rangeURI", rangeURI);
|
tmpHash.put("domainURI", domainURI);
|
||||||
tmpHash.put("domain", domainLabel);
|
|
||||||
tmpHash.put("domainURI", domainURI);
|
// add the faux and its details to the treemap
|
||||||
// add the faux and its details to the treemap
|
fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
||||||
fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
fauxForGivenBase.put("editUrl", "propertyEdit");
|
||||||
}
|
}
|
||||||
fauxByBaseProps.put(baseLabel, fauxForGivenBase);
|
fauxByBaseProps.put(baseLabel, fauxForGivenBase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fauxByBaseProps;
|
return fauxByBaseProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private TreeMap<String, Object> getFauxDataPropertyList(List<DataProperty> dataProps, VitroRequest vreq) {
|
||||||
* should never be null
|
List<FauxProperty> fauxProps = null;
|
||||||
*/
|
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
|
||||||
public static String getDisplayLabel(ObjectProperty op) {
|
if (dataProps != null) {
|
||||||
String displayLabel = op.getPickListName();
|
Iterator<DataProperty> opIt = dataProps.iterator();
|
||||||
displayLabel = (displayLabel != null && displayLabel.length() > 0)
|
if (!opIt.hasNext()) {
|
||||||
? displayLabel
|
notFoundMessage = "No data properties found.";
|
||||||
: op.getLocalName();
|
} else {
|
||||||
return (displayLabel != null) ? displayLabel : "[object property]" ;
|
while (opIt.hasNext()) {
|
||||||
|
DataProperty dp = opIt.next();
|
||||||
|
String baseURI = dp.getURI();
|
||||||
|
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
|
||||||
|
if (fauxProps != null) {
|
||||||
|
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
||||||
|
if (!fpIt.hasNext()) {
|
||||||
|
notFoundMessage = "No faux properties found.";
|
||||||
|
} else {
|
||||||
|
while (fpIt.hasNext()) {
|
||||||
|
// No point in getting these unless we have a
|
||||||
|
// faux property
|
||||||
|
String baseLabel = getBaseLabel(dp, false);
|
||||||
|
// get the info we need from the faux property
|
||||||
|
FauxProperty fp = fpIt.next();
|
||||||
|
String fauxLabel = fp.getDisplayName();
|
||||||
|
String rangeLabel = fp.getRangeLabel();
|
||||||
|
String rangeURI = fp.getRangeURI();
|
||||||
|
String domainLabel = fp.getDomainLabel();
|
||||||
|
String domainURI = fp.getDomainURI();
|
||||||
|
String groupURI = fp.getGroupURI();
|
||||||
|
// FauxProperty only gets groupURI but we want
|
||||||
|
// the label
|
||||||
|
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
|
||||||
|
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
|
||||||
|
// store all the strings in a hash with the faux
|
||||||
|
// property label as the key
|
||||||
|
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
||||||
|
tmpHash.put("base", baseLabel);
|
||||||
|
tmpHash.put("baseURI", baseURI);
|
||||||
|
tmpHash.put("group", groupLabel);
|
||||||
|
tmpHash.put("range", rangeLabel);
|
||||||
|
tmpHash.put("rangeURI", rangeURI);
|
||||||
|
tmpHash.put("domain", domainLabel);
|
||||||
|
tmpHash.put("domainURI", domainURI);
|
||||||
|
tmpHash.put("editUrl", "datapropEdit");
|
||||||
|
// add the faux and its details to the treemap
|
||||||
|
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return theFauxProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeMap<String, Object> getFauxDataPropsByBaseList(List<DataProperty> dataProps, VitroRequest vreq) {
|
||||||
|
List<FauxProperty> fauxProps = null;
|
||||||
|
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
|
||||||
|
if (dataProps != null) {
|
||||||
|
Iterator<DataProperty> opIt = dataProps.iterator();
|
||||||
|
if (!opIt.hasNext()) {
|
||||||
|
notFoundMessage = "No data properties found.";
|
||||||
|
} else {
|
||||||
|
while (opIt.hasNext()) {
|
||||||
|
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
|
||||||
|
DataProperty dp = opIt.next();
|
||||||
|
String baseURI = dp.getURI();
|
||||||
|
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
|
||||||
|
|
||||||
|
if (fauxProps != null) {
|
||||||
|
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
||||||
|
if (!fpIt.hasNext()) {
|
||||||
|
notFoundMessage = "No faux properties found.";
|
||||||
|
} else {
|
||||||
|
String baseLabel = getBaseLabel(dp, true);
|
||||||
|
while (fpIt.hasNext()) {
|
||||||
|
// get the info we need from the faux property
|
||||||
|
FauxProperty fp = fpIt.next();
|
||||||
|
String fauxLabel = fp.getDisplayName();
|
||||||
|
String rangeLabel = fp.getRangeLabel();
|
||||||
|
String rangeURI = fp.getRangeURI();
|
||||||
|
String domainLabel = fp.getDomainLabel();
|
||||||
|
String domainURI = fp.getDomainURI();
|
||||||
|
String groupURI = fp.getGroupURI();
|
||||||
|
// FauxProperty only gets groupURI but we want
|
||||||
|
// the label
|
||||||
|
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
|
||||||
|
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
|
||||||
|
// store all the strings in a hash with the faux
|
||||||
|
// property label as the key
|
||||||
|
Map<String, Object> tmpHash = new HashMap<String, Object>();
|
||||||
|
tmpHash.put("baseURI", baseURI);
|
||||||
|
tmpHash.put("group", groupLabel);
|
||||||
|
tmpHash.put("range", rangeLabel);
|
||||||
|
tmpHash.put("rangeURI", rangeURI);
|
||||||
|
tmpHash.put("domain", domainLabel);
|
||||||
|
tmpHash.put("domainURI", domainURI);
|
||||||
|
// add the faux and its details to the treemap
|
||||||
|
fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
||||||
|
fauxForGivenBase.put("editUrl", "datapropEdit");
|
||||||
|
}
|
||||||
|
fauxByBaseProps.put(baseLabel, fauxForGivenBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fauxByBaseProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBaseLabel(Property property, boolean addUri) {
|
||||||
|
String baseLabel = property.getPickListName();
|
||||||
|
if (StringUtils.isEmpty(baseLabel)) {
|
||||||
|
baseLabel = property.getLocalName();
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(baseLabel)) {
|
||||||
|
baseLabel = "[property]";
|
||||||
|
}
|
||||||
|
String baseLocalName = property.getLocalNameWithPrefix();
|
||||||
|
int indexOf = baseLabel.indexOf("(");
|
||||||
|
if (indexOf > 0) {
|
||||||
|
baseLabel = baseLabel.substring(0, indexOf);
|
||||||
|
}
|
||||||
|
baseLabel += "(" + baseLocalName + ")";
|
||||||
|
if (addUri) {
|
||||||
|
baseLabel += "|" + property.getURI();
|
||||||
|
}
|
||||||
|
return baseLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
|
||||||
|
|
||||||
@WebServlet(name = "TermsOfUseController", urlPatterns = {"/termsOfUse"} )
|
|
||||||
public class TermsOfUseController extends FreemarkerHttpServlet {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private static final Log log = LogFactory.getLog(TermsOfUseController.class);
|
|
||||||
private static final String TEMPLATE_DEFAULT = "termsOfUse.ftl";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
|
||||||
|
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
|
||||||
Map<String, String> termsOfUse = new HashMap<String, String>();
|
|
||||||
|
|
||||||
ApplicationBean appBean = vreq.getAppBean();
|
|
||||||
|
|
||||||
termsOfUse.put("siteName", appBean.getApplicationName());
|
|
||||||
|
|
||||||
String siteHost = appBean.getCopyrightAnchor();
|
|
||||||
if (siteHost == null) {
|
|
||||||
siteHost = "the hosting institution";
|
|
||||||
}
|
|
||||||
termsOfUse.put("siteHost", siteHost);
|
|
||||||
|
|
||||||
map.put("termsOfUse", termsOfUse);
|
|
||||||
return new TemplateResponseValues(TEMPLATE_DEFAULT, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTitle(String siteName, VitroRequest vreq) {
|
|
||||||
return siteName + " Terms of Use";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -170,7 +170,7 @@ public class ViewLabelsServlet extends FreemarkerHttpServlet{
|
||||||
Locale currentLocale) throws FileNotFoundException {
|
Locale currentLocale) throws FileNotFoundException {
|
||||||
HashMap<String, String> map = new HashMap<String, String>();
|
HashMap<String, String> map = new HashMap<String, String>();
|
||||||
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
|
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
|
||||||
map.put("code", locale.toString().replace("_", "-"));
|
map.put("code", locale.toLanguageTag().replace("_", "-"));
|
||||||
map.put("label", locale.getDisplayName(currentLocale));
|
map.put("label", locale.getDisplayName(currentLocale));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.jena.ontology.ObjectProperty;
|
import org.apache.jena.ontology.ObjectProperty;
|
||||||
|
@ -152,20 +153,22 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
||||||
|
|
||||||
Collection<String> rangeUris = getPropertyResourceURIValues(
|
Collection<String> rangeUris = getPropertyResourceURIValues(
|
||||||
context, QUALIFIED_BY_RANGE);
|
context, QUALIFIED_BY_RANGE);
|
||||||
if (rangeUris.isEmpty()) {
|
String rangeUri = null;
|
||||||
log.debug("'" + contextUri + "' has no value for '"
|
if (!rangeUris.isEmpty()) {
|
||||||
+ QUALIFIED_BY_RANGE + "'");
|
rangeUri = rangeUris.iterator().next();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
String rangeUri = rangeUris.iterator().next();
|
|
||||||
|
|
||||||
// domainURI is optional.
|
// domainURI is optional.
|
||||||
Collection<String> domainUris = getPropertyResourceURIValues(
|
Collection<String> domainUris = getPropertyResourceURIValues(
|
||||||
context, QUALIFIED_BY_DOMAIN);
|
context, QUALIFIED_BY_DOMAIN);
|
||||||
String domainUri = domainUris.isEmpty() ? null : domainUris
|
String domainUri = domainUris.isEmpty() ? null : domainUris
|
||||||
.iterator().next();
|
.iterator().next();
|
||||||
|
|
||||||
|
Collection<String> rootRangeUris = getPropertyResourceURIValues(context, QUALIFIED_BY_ROOT);
|
||||||
|
|
||||||
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
||||||
|
if (!rootRangeUris.isEmpty()) {
|
||||||
|
fp.setRootRangeUri(rootRangeUris.iterator().next());
|
||||||
|
}
|
||||||
fp.setContextUri(contextUri);
|
fp.setContextUri(contextUri);
|
||||||
populateInstance(fp);
|
populateInstance(fp);
|
||||||
log.debug("Loaded FauxProperty: " + fp);
|
log.debug("Loaded FauxProperty: " + fp);
|
||||||
|
@ -214,7 +217,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
||||||
addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT);
|
addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT);
|
||||||
addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR,
|
addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR,
|
||||||
fp.getBaseURI());
|
fp.getBaseURI());
|
||||||
addPropertyResourceURIValue(context, QUALIFIED_BY_RANGE,
|
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_RANGE,
|
||||||
fp.getRangeURI());
|
fp.getRangeURI());
|
||||||
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN,
|
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN,
|
||||||
fp.getDomainURI());
|
fp.getDomainURI());
|
||||||
|
@ -493,31 +496,22 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
||||||
// ConfigContext
|
// ConfigContext
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN = "" //
|
private static String queryLocateConfigContext(boolean hasDomain, boolean hasRange) {
|
||||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
return "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n"
|
||||||
+ "\n" //
|
+ "SELECT DISTINCT ?context ?config \n"
|
||||||
+ "SELECT DISTINCT ?context ?config \n" //
|
+ "WHERE { \n"
|
||||||
+ "WHERE { \n" //
|
+ " ?context a :ConfigContext . \n"
|
||||||
+ " ?context a :ConfigContext ; \n" //
|
+ " ?context :configContextFor ?baseUri . \n"
|
||||||
+ " :configContextFor ?baseUri ; \n" //
|
+ ( hasDomain ? "" : " FILTER NOT EXISTS { \n " )
|
||||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
+ " ?context :qualifiedByDomain ?domainUri . \n"
|
||||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
+ ( hasDomain ? "" : "} \n" )
|
||||||
+ " :hasConfiguration ?config . \n" //
|
+ ( hasRange ? "" : " FILTER NOT EXISTS { \n " )
|
||||||
+ "} \n"; //
|
+ " ?context :qualifiedBy ?rangeUri . \n"
|
||||||
|
+ ( hasRange ? "" : "} \n" )
|
||||||
|
+ " ?context :hasConfiguration ?config . \n"
|
||||||
|
+ "} \n";
|
||||||
|
|
||||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN = "" //
|
}
|
||||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
|
||||||
+ "\n" //
|
|
||||||
+ "SELECT DISTINCT ?context ?config \n" //
|
|
||||||
+ "WHERE { \n" //
|
|
||||||
+ " ?context a :ConfigContext ; \n" //
|
|
||||||
+ " :configContextFor ?baseUri ; \n" //
|
|
||||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
|
||||||
+ " :hasConfiguration ?config . \n" //
|
|
||||||
+ " FILTER NOT EXISTS { \n" //
|
|
||||||
+ " ?context :qualifiedByDomain ?domainUri \n" //
|
|
||||||
+ " } \n" //
|
|
||||||
+ "} \n"; //
|
|
||||||
|
|
||||||
private static class ParserLocateConfigContext extends
|
private static class ParserLocateConfigContext extends
|
||||||
ResultSetParser<Set<ConfigContext>> {
|
ResultSetParser<Set<ConfigContext>> {
|
||||||
|
@ -556,22 +550,16 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
|
||||||
|
|
||||||
private static class ConfigContext {
|
private static class ConfigContext {
|
||||||
public static Set<ConfigContext> findByQualifiers(
|
public static Set<ConfigContext> findByQualifiers(
|
||||||
LockableOntModel lockableDisplayModel, String domainUri,
|
LockableOntModel lockableDisplayModel, String domainUri, String baseUri, String rangeUri) {
|
||||||
String baseUri, String rangeUri) {
|
|
||||||
try (LockedOntModel displayModel = lockableDisplayModel.read()) {
|
try (LockedOntModel displayModel = lockableDisplayModel.read()) {
|
||||||
QueryHolder qHolder;
|
boolean hasDomain = !StringUtils.isEmpty(domainUri) && !domainUri.equals(OWL.Thing.getURI());
|
||||||
if (domainUri == null || domainUri.trim().isEmpty()
|
boolean hasRange = !StringUtils.isEmpty(rangeUri);
|
||||||
|| domainUri.equals(OWL.Thing.getURI())) {
|
QueryHolder qHolder = queryHolder(queryLocateConfigContext(hasDomain, hasRange)).bindToUri("baseUri", baseUri);
|
||||||
qHolder = queryHolder(
|
if (hasDomain) {
|
||||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN)
|
qHolder = qHolder.bindToUri("domainUri", domainUri);
|
||||||
.bindToUri("baseUri", baseUri).bindToUri(
|
}
|
||||||
"rangeUri", rangeUri);
|
if (hasRange) {
|
||||||
} else {
|
qHolder = qHolder.bindToUri("rangeUri", rangeUri);
|
||||||
qHolder = queryHolder(
|
|
||||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN)
|
|
||||||
.bindToUri("baseUri", baseUri)
|
|
||||||
.bindToUri("rangeUri", rangeUri)
|
|
||||||
.bindToUri("domainUri", domainUri);
|
|
||||||
}
|
}
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri
|
log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri
|
||||||
|
|
|
@ -813,7 +813,9 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
||||||
List<ObjectProperty> stragglers = getAdditionalFauxSubpropertiesForVClasses(
|
List<ObjectProperty> stragglers = getAdditionalFauxSubpropertiesForVClasses(
|
||||||
vclasses, propInsts);
|
vclasses, propInsts);
|
||||||
for (ObjectProperty op : stragglers) {
|
for (ObjectProperty op : stragglers) {
|
||||||
propInsts.add(makePropInst(op));
|
if (op != null) {
|
||||||
|
propInsts.add(makePropInst(op));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return propInsts;
|
return propInsts;
|
||||||
|
|
|
@ -264,6 +264,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
|
||||||
} catch (ProfileException pe) {
|
} catch (ProfileException pe) {
|
||||||
// Current language profile does not support disjointWith axioms.
|
// Current language profile does not support disjointWith axioms.
|
||||||
// We'd prefer to return an empty list instead of throwing an exception.
|
// We'd prefer to return an empty list instead of throwing an exception.
|
||||||
|
log.error(pe, pe);
|
||||||
} finally {
|
} finally {
|
||||||
getOntModel().leaveCriticalSection();
|
getOntModel().leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class ProcessRdfForm {
|
||||||
private EditN3GeneratorVTwo populator;
|
private EditN3GeneratorVTwo populator;
|
||||||
|
|
||||||
private Map<String,String> urisForNewResources = null;
|
private Map<String,String> urisForNewResources = null;
|
||||||
|
private static final String langStringDatatypeUri = RDF.dtLangString.getURI();
|
||||||
// private VitroRequest _vreq;
|
// private VitroRequest _vreq;
|
||||||
/**
|
/**
|
||||||
* Construct the ProcessRdfForm object.
|
* Construct the ProcessRdfForm object.
|
||||||
|
@ -368,7 +369,8 @@ public class ProcessRdfForm {
|
||||||
if (obj.isLiteral()) {
|
if (obj.isLiteral()) {
|
||||||
Literal lit = obj.asLiteral();
|
Literal lit = obj.asLiteral();
|
||||||
String lang = lit.getLanguage();
|
String lang = lit.getLanguage();
|
||||||
if (! linguisticContext.equals(lang)) {
|
if (langStringDatatypeUri.equals(lit.getDatatypeURI()) &&
|
||||||
|
! linguisticContext.equals(lang)) {
|
||||||
//UQAM Remove if linguisticContext != lang of the Literal
|
//UQAM Remove if linguisticContext != lang of the Literal
|
||||||
model.remove(subj, pred, obj);
|
model.remove(subj, pred, obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,6 @@ public class ChildVClassesWithParent implements FieldOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* UQAM-Linguistic-Management
|
|
||||||
* This method is polymorphism of getOptions(EditConfigurationVTwo editConfig,String fieldName, WebappDaoFactory wDaoFact)
|
|
||||||
* for the internationalization of word "other" in the scroling list of personHasAdvisorRelationship.ftl
|
|
||||||
*/
|
|
||||||
public Map<String, String> getOptions(
|
public Map<String, String> getOptions(
|
||||||
EditConfigurationVTwo editConfig,
|
EditConfigurationVTwo editConfig,
|
||||||
String fieldName,
|
String fieldName,
|
||||||
|
@ -53,16 +48,17 @@ public class ChildVClassesWithParent implements FieldOptions {
|
||||||
if ( ! StringUtils.isEmpty( defaultOptionLabel ) ){
|
if ( ! StringUtils.isEmpty( defaultOptionLabel ) ){
|
||||||
optionsMap.put(LEFT_BLANK, defaultOptionLabel);
|
optionsMap.put(LEFT_BLANK, defaultOptionLabel);
|
||||||
}
|
}
|
||||||
String other_i18n = i18n.text("other");
|
|
||||||
// first character in capital
|
|
||||||
optionsMap.put(classUri, other_i18n.substring(0, 1).toUpperCase() + other_i18n.substring(1));
|
|
||||||
VClassDao vclassDao = wDaoFact.getVClassDao();
|
VClassDao vclassDao = wDaoFact.getVClassDao();
|
||||||
|
VClass rdfClass = vclassDao.getVClassByURI(classUri);
|
||||||
|
if (rdfClass != null && !OWL.Nothing.getURI().equals(classUri)) {
|
||||||
|
optionsMap.put(classUri, rdfClass.getName().trim());
|
||||||
|
}
|
||||||
List<String> subClassList = vclassDao.getAllSubClassURIs(classUri);
|
List<String> subClassList = vclassDao.getAllSubClassURIs(classUri);
|
||||||
if (subClassList != null && subClassList.size() > 0) {
|
if (subClassList != null && subClassList.size() > 0) {
|
||||||
for (String subClassUri : subClassList) {
|
for (String subClassUri : subClassList) {
|
||||||
VClass subClass = vclassDao.getVClassByURI(subClassUri);
|
rdfClass = vclassDao.getVClassByURI(subClassUri);
|
||||||
if (subClass != null && !OWL.Nothing.getURI().equals(subClassUri)) {
|
if (rdfClass != null && !OWL.Nothing.getURI().equals(subClassUri)) {
|
||||||
optionsMap.put(subClassUri, subClass.getName().trim());
|
optionsMap.put(subClassUri, rdfClass.getName().trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,7 +464,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
|
||||||
Locale currentLocale) throws FileNotFoundException {
|
Locale currentLocale) throws FileNotFoundException {
|
||||||
HashMap<String, String> map = new HashMap<String, String>();
|
HashMap<String, String> map = new HashMap<String, String>();
|
||||||
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
|
//Replacing the underscore with a hyphen because that is what is represented in the actual literals
|
||||||
map.put("code", locale.toString().replace("_", "-"));
|
map.put("code", locale.toLanguageTag().replace("_", "-"));
|
||||||
map.put("label", locale.getDisplayName(currentLocale));
|
map.put("label", locale.getDisplayName(currentLocale));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,24 +24,19 @@ import javax.mail.internet.MimeBodyPart;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
import javax.mail.internet.MimeMultipart;
|
import javax.mail.internet.MimeMultipart;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective;
|
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A framework that makes it simpler to send email messages with a body built
|
* A framework that makes it simpler to send email messages with a body built
|
||||||
* from a Freemarker template.
|
* from a Freemarker template.
|
||||||
*
|
*
|
||||||
* The template must call the @email directive, which may provide the subject
|
|
||||||
* line, the HTML content, and the plain text content. If these values are not
|
|
||||||
* provided by the directive, they default to empty strings, or to values that
|
|
||||||
* were set by the controller.
|
|
||||||
*
|
|
||||||
* @see EmailDirective
|
|
||||||
*/
|
*/
|
||||||
public class FreemarkerEmailMessage {
|
public class FreemarkerEmailMessage {
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory
|
||||||
|
@ -56,7 +51,6 @@ public class FreemarkerEmailMessage {
|
||||||
|
|
||||||
private InternetAddress fromAddress = null;
|
private InternetAddress fromAddress = null;
|
||||||
private String subject = "";
|
private String subject = "";
|
||||||
private String templateName = "";
|
|
||||||
private String htmlContent = "";
|
private String htmlContent = "";
|
||||||
private String textContent = "";
|
private String textContent = "";
|
||||||
private Map<String, Object> bodyMap = Collections.emptyMap();
|
private Map<String, Object> bodyMap = Collections.emptyMap();
|
||||||
|
@ -124,10 +118,6 @@ public class FreemarkerEmailMessage {
|
||||||
this.textContent = nonNull(textContent, "");
|
this.textContent = nonNull(textContent, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTemplate(String templateName) {
|
|
||||||
this.templateName = nonNull(templateName, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBodyMap(Map<String, Object> body) {
|
public void setBodyMap(Map<String, Object> body) {
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
this.bodyMap = Collections.emptyMap();
|
this.bodyMap = Collections.emptyMap();
|
||||||
|
@ -137,16 +127,52 @@ public class FreemarkerEmailMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processTemplate() {
|
public void processTemplate() {
|
||||||
bodyMap.put("email", new EmailDirective(this));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config.getTemplate(templateName).process(bodyMap,
|
addDefaultBodyMapValues();
|
||||||
new StringWriter());
|
StringWriter writer = new StringWriter();
|
||||||
|
new Template(null, getInlineVariable("subject"), config).process(bodyMap, writer);
|
||||||
|
subject = writer.toString();
|
||||||
|
writer.getBuffer().setLength(0);
|
||||||
|
new Template(null, getEmailTemplate(), config).process(bodyMap, writer);
|
||||||
|
htmlContent = writer.toString();
|
||||||
|
writer.getBuffer().setLength(0);
|
||||||
|
new Template(null, getInlineVariable("textMessage"), config).process(bodyMap, writer);
|
||||||
|
textContent = writer.toString();
|
||||||
} catch (TemplateException | IOException e) {
|
} catch (TemplateException | IOException e) {
|
||||||
log.error(e, e);
|
log.error(e, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addDefaultBodyMapValues() {
|
||||||
|
if (!bodyMap.containsKey("subject")) {
|
||||||
|
if (StringUtils.isBlank(subject)) {
|
||||||
|
bodyMap.put("subject", "No subject defined");
|
||||||
|
}
|
||||||
|
bodyMap.put("subject", subject);
|
||||||
|
}
|
||||||
|
if (!bodyMap.containsKey("textMessage")) {
|
||||||
|
bodyMap.put("textMessage", "No text message defined");
|
||||||
|
}
|
||||||
|
if (!bodyMap.containsKey("htmlMessage")) {
|
||||||
|
bodyMap.put("htmlMessage", "No html message defined");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInlineVariable(String name) {
|
||||||
|
return "<@" + name + "?interpret />";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEmailTemplate() {
|
||||||
|
return "<html>\n"
|
||||||
|
+ " <head>\n"
|
||||||
|
+ " <title><@subject?interpret /></title>\n"
|
||||||
|
+ " </head>\n"
|
||||||
|
+ " <body>\n"
|
||||||
|
+ " <@htmlMessage?interpret />\n"
|
||||||
|
+ " </body>\n"
|
||||||
|
+ "</html>";
|
||||||
|
}
|
||||||
|
|
||||||
public boolean send() {
|
public boolean send() {
|
||||||
try {
|
try {
|
||||||
MimeMessage msg = new MimeMessage(mailSession);
|
MimeMessage msg = new MimeMessage(mailSession);
|
||||||
|
@ -182,8 +208,7 @@ public class FreemarkerEmailMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.setSentDate(new Date());
|
msg.setSentDate(new Date());
|
||||||
|
sendMessage(msg);
|
||||||
Transport.send(msg);
|
|
||||||
return true;
|
return true;
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
log.error("Failed to send message.", e);
|
log.error("Failed to send message.", e);
|
||||||
|
@ -191,6 +216,19 @@ public class FreemarkerEmailMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendMessage(MimeMessage msg) {
|
||||||
|
Thread thread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Transport.send(msg);
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
log.error(e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
private void addBodyPart(MimeMultipart content, String textBody, String type)
|
private void addBodyPart(MimeMultipart content, String textBody, String type)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
MimeBodyPart bodyPart = new MimeBodyPart();
|
MimeBodyPart bodyPart = new MimeBodyPart();
|
||||||
|
|
|
@ -284,7 +284,7 @@ public class CachingResponseFilter implements Filter {
|
||||||
|
|
||||||
StringBuilder buffer = new StringBuilder("\"").append(rawEtag);
|
StringBuilder buffer = new StringBuilder("\"").append(rawEtag);
|
||||||
for (Locale locale : locales) {
|
for (Locale locale : locales) {
|
||||||
buffer.append(locale.toString());
|
buffer.append(locale.toLanguageTag());
|
||||||
}
|
}
|
||||||
buffer.append("\"");
|
buffer.append("\"");
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,10 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.i18n;
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.MissingResourceException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -39,8 +33,6 @@ import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||||
public class I18n {
|
public class I18n {
|
||||||
private static final Log log = LogFactory.getLog(I18n.class);
|
private static final Log log = LogFactory.getLog(I18n.class);
|
||||||
|
|
||||||
public static final String DEFAULT_BUNDLE_NAME = "all";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this attribute is present on the request, then the cache has already
|
* If this attribute is present on the request, then the cache has already
|
||||||
* been cleared.
|
* been cleared.
|
||||||
|
@ -73,14 +65,6 @@ public class I18n {
|
||||||
I18n.instance = new I18n(ctx);
|
I18n.instance = new I18n(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A convenience method to get a bundle and format the text.
|
|
||||||
*/
|
|
||||||
public static String text(String bundleName, HttpServletRequest req,
|
|
||||||
String key, Object... parameters) {
|
|
||||||
return bundle(bundleName, req).text(key, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A convenience method to get the default bundle and format the text.
|
* A convenience method to get the default bundle and format the text.
|
||||||
*/
|
*/
|
||||||
|
@ -89,25 +73,18 @@ public class I18n {
|
||||||
return bundle(req).text(key, parameters);
|
return bundle(req).text(key, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a request I18nBundle by this name.
|
|
||||||
*/
|
|
||||||
public static I18nBundle bundle(String bundleName, HttpServletRequest req) {
|
|
||||||
return instance.getBundle(bundleName, req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default request I18nBundle.
|
* Get the default request I18nBundle.
|
||||||
*/
|
*/
|
||||||
public static I18nBundle bundle(HttpServletRequest req) {
|
public static I18nBundle bundle(HttpServletRequest req) {
|
||||||
return instance.getBundle(DEFAULT_BUNDLE_NAME, req);
|
return instance.getBundle(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default context I18nBundle for preferred locales.
|
* Get the default context I18nBundle for preferred locales.
|
||||||
*/
|
*/
|
||||||
public static I18nBundle bundle(List<Locale> preferredLocales) {
|
public static I18nBundle bundle(List<Locale> preferredLocales) {
|
||||||
return instance.getBundle(DEFAULT_BUNDLE_NAME, preferredLocales);
|
return instance.getBundle(preferredLocales);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -130,15 +107,11 @@ public class I18n {
|
||||||
*
|
*
|
||||||
* Declared 'protected' so it can be overridden in unit tests.
|
* Declared 'protected' so it can be overridden in unit tests.
|
||||||
*/
|
*/
|
||||||
protected I18nBundle getBundle(String bundleName, HttpServletRequest req) {
|
protected I18nBundle getBundle(HttpServletRequest req) {
|
||||||
log.debug("Getting request bundle '" + bundleName + "'");
|
|
||||||
|
|
||||||
checkDevelopmentMode(req);
|
checkDevelopmentMode(req);
|
||||||
checkForChangeInThemeDirectory(req);
|
checkForChangeInThemeDirectory(req);
|
||||||
|
|
||||||
Locale locale = req.getLocale();
|
Locale locale = req.getLocale();
|
||||||
|
return new I18nSemanticBundle(Collections.singletonList(locale));
|
||||||
return getBundle(bundleName, locale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,38 +127,11 @@ public class I18n {
|
||||||
*
|
*
|
||||||
* Declared 'protected' so it can be overridden in unit tests.
|
* Declared 'protected' so it can be overridden in unit tests.
|
||||||
*/
|
*/
|
||||||
protected I18nBundle getBundle(String bundleName, List<Locale> preferredLocales) {
|
protected I18nBundle getBundle( List<Locale> preferredLocales) {
|
||||||
log.debug("Getting context bundle '" + bundleName + "'");
|
|
||||||
|
|
||||||
checkDevelopmentMode();
|
checkDevelopmentMode();
|
||||||
checkForChangeInThemeDirectory(ctx);
|
checkForChangeInThemeDirectory(ctx);
|
||||||
|
|
||||||
Locale locale = SelectedLocale.getPreferredLocale(ctx, preferredLocales);
|
Locale locale = SelectedLocale.getPreferredLocale(ctx, preferredLocales);
|
||||||
|
return new I18nSemanticBundle(Collections.singletonList(locale));
|
||||||
return getBundle(bundleName, locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an I18nBundle by this name, context, and locale.
|
|
||||||
*/
|
|
||||||
private I18nBundle getBundle(String bundleName, Locale locale) {
|
|
||||||
I18nLogger i18nLogger = new I18nLogger();
|
|
||||||
try {
|
|
||||||
String dir = themeDirectory.get();
|
|
||||||
ResourceBundle.Control control = new ThemeBasedControl(ctx, dir);
|
|
||||||
ResourceBundle rb = ResourceBundle.getBundle(bundleName,
|
|
||||||
locale, control);
|
|
||||||
|
|
||||||
return new I18nBundle(bundleName, rb, i18nLogger);
|
|
||||||
} catch (MissingResourceException e) {
|
|
||||||
log.warn("Didn't find text bundle '" + bundleName + "'");
|
|
||||||
|
|
||||||
return I18nBundle.emptyBundle(bundleName, i18nLogger);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to create text bundle '" + bundleName + "'", e);
|
|
||||||
|
|
||||||
return I18nBundle.emptyBundle(bundleName, i18nLogger);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,7 +150,7 @@ public class I18n {
|
||||||
private void checkDevelopmentMode() {
|
private void checkDevelopmentMode() {
|
||||||
if (DeveloperSettings.getInstance().getBoolean(Key.I18N_DEFEAT_CACHE)) {
|
if (DeveloperSettings.getInstance().getBoolean(Key.I18N_DEFEAT_CACHE)) {
|
||||||
log.debug("In development mode - clearing the cache.");
|
log.debug("In development mode - clearing the cache.");
|
||||||
ResourceBundle.clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,158 +187,24 @@ public class I18n {
|
||||||
if (!currentDir.equals(previousDir)) {
|
if (!currentDir.equals(previousDir)) {
|
||||||
log.debug("Theme directory changed from '" + previousDir + "' to '"
|
log.debug("Theme directory changed from '" + previousDir + "' to '"
|
||||||
+ currentDir + "' - clearing the cache.");
|
+ currentDir + "' - clearing the cache.");
|
||||||
ResourceBundle.clearCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearCache() {
|
||||||
|
TranslationProvider.getInstance().clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
/** Only clear the cache one time per request. */
|
/** Only clear the cache one time per request. */
|
||||||
private void clearCacheOnRequest(HttpServletRequest req) {
|
private void clearCacheOnRequest(HttpServletRequest req) {
|
||||||
if (req.getAttribute(ATTRIBUTE_CACHE_CLEARED) != null) {
|
if (req.getAttribute(ATTRIBUTE_CACHE_CLEARED) != null) {
|
||||||
log.debug("Cache was already cleared on this request.");
|
log.debug("Cache was already cleared on this request.");
|
||||||
} else {
|
} else {
|
||||||
ResourceBundle.clearCache();
|
clearCache();
|
||||||
log.debug("Cache cleared.");
|
log.debug("Cache cleared.");
|
||||||
req.setAttribute(ATTRIBUTE_CACHE_CLEARED, Boolean.TRUE);
|
req.setAttribute(ATTRIBUTE_CACHE_CLEARED, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Control classes for instantiating ResourceBundles
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instead of looking in the classpath, look in the theme i18n directory and
|
|
||||||
* the application i18n directory.
|
|
||||||
*/
|
|
||||||
static class ThemeBasedControl extends ResourceBundle.Control {
|
|
||||||
private static final String BUNDLE_DIRECTORY = "i18n/";
|
|
||||||
private final ServletContext ctx;
|
|
||||||
private final String themeDirectory;
|
|
||||||
|
|
||||||
public ThemeBasedControl(ServletContext ctx, String themeDirectory) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.themeDirectory = themeDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't look for classes to satisfy the request, just property files.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<String> getFormats(String baseName) {
|
|
||||||
return FORMAT_PROPERTIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't look in the class path, look in the current servlet context, in
|
|
||||||
* the bundle directory under the theme directory and in the bundle
|
|
||||||
* directory under the application directory.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ResourceBundle newBundle(String baseName, Locale locale,
|
|
||||||
String format, ClassLoader loader, boolean reload)
|
|
||||||
throws IllegalAccessException, InstantiationException,
|
|
||||||
IOException {
|
|
||||||
checkArguments(baseName, locale, format);
|
|
||||||
|
|
||||||
log.debug("Creating bundle for '" + baseName + "', " + locale
|
|
||||||
+ ", '" + format + "', " + reload);
|
|
||||||
|
|
||||||
String bundleName = toBundleName(baseName, locale);
|
|
||||||
if (bundleName == null) {
|
|
||||||
throw new NullPointerException("bundleName may not be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
String themeI18nPath = "/" + themeDirectory + BUNDLE_DIRECTORY;
|
|
||||||
String appI18nPath = "/" + BUNDLE_DIRECTORY;
|
|
||||||
|
|
||||||
log.debug("Paths are '" + themeI18nPath + "' and '" + appI18nPath
|
|
||||||
+ "'");
|
|
||||||
|
|
||||||
return VitroResourceBundle.getBundle(bundleName, ctx, appI18nPath,
|
|
||||||
themeI18nPath, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When creating the chain of acceptable Locales, include approximate
|
|
||||||
* matches before giving up and using the root Locale.
|
|
||||||
*
|
|
||||||
* Check the list of supported Locales to see if any have the same
|
|
||||||
* language but different region. If we find any, sort them and insert
|
|
||||||
* them into the usual result list, just before the root Locale.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<Locale> getCandidateLocales(String baseName, Locale locale) {
|
|
||||||
// Find the list of Locales that would normally be returned.
|
|
||||||
List<Locale> usualList = super
|
|
||||||
.getCandidateLocales(baseName, locale);
|
|
||||||
|
|
||||||
// If our "selectable locales" include no approximate matches that
|
|
||||||
// are not already in the list, we're done.
|
|
||||||
SortedSet<Locale> approximateMatches = findApproximateMatches(locale);
|
|
||||||
approximateMatches.removeAll(usualList);
|
|
||||||
if (approximateMatches.isEmpty()) {
|
|
||||||
return usualList;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, insert those approximate matches into the list just
|
|
||||||
// before the ROOT locale.
|
|
||||||
List<Locale> mergedList = new LinkedList<>(usualList);
|
|
||||||
int rootLocaleHere = mergedList.indexOf(Locale.ROOT);
|
|
||||||
if (rootLocaleHere == -1) {
|
|
||||||
mergedList.addAll(approximateMatches);
|
|
||||||
} else {
|
|
||||||
mergedList.addAll(rootLocaleHere, approximateMatches);
|
|
||||||
}
|
|
||||||
return mergedList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SortedSet<Locale> findApproximateMatches(Locale locale) {
|
|
||||||
SortedSet<Locale> set = new TreeSet<>(new LocaleComparator());
|
|
||||||
|
|
||||||
for (Locale l : SelectedLocale.getSelectableLocales(ctx)) {
|
|
||||||
if (locale.getLanguage().equals(l.getLanguage())) {
|
|
||||||
set.add(l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The documentation for ResourceBundle.Control.newBundle() says I
|
|
||||||
* should throw these exceptions.
|
|
||||||
*/
|
|
||||||
private void checkArguments(String baseName, Locale locale,
|
|
||||||
String format) {
|
|
||||||
if (baseName == null) {
|
|
||||||
throw new NullPointerException("baseName may not be null.");
|
|
||||||
}
|
|
||||||
if (locale == null) {
|
|
||||||
throw new NullPointerException("locale may not be null.");
|
|
||||||
}
|
|
||||||
if (format == null) {
|
|
||||||
throw new NullPointerException("format may not be null.");
|
|
||||||
}
|
|
||||||
if (!FORMAT_DEFAULT.contains(format)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"format must be one of these: " + FORMAT_DEFAULT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class LocaleComparator implements Comparator<Locale> {
|
|
||||||
@Override
|
|
||||||
public int compare(Locale o1, Locale o2) {
|
|
||||||
int c = o1.getLanguage().compareTo(o2.getLanguage());
|
|
||||||
if (c == 0) {
|
|
||||||
c = o1.getCountry().compareTo(o2.getCountry());
|
|
||||||
if (c == 0) {
|
|
||||||
c = o1.getVariant().compareTo(o2.getVariant());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,133 +1,10 @@
|
||||||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.i18n;
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
public interface I18nBundle {
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
public static final String START_SEP = "\u25a4";
|
||||||
import org.apache.commons.logging.LogFactory;
|
public static final String END_SEP = "\u25a5";
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper for a ResourceBundle that will not throw an exception, no matter
|
|
||||||
* what string you request.
|
|
||||||
*
|
|
||||||
* If the ResourceBundle was not found, or if it doesn't contain the requested
|
|
||||||
* key, an error message string is returned, to help the developer diagnose the
|
|
||||||
* problem.
|
|
||||||
*/
|
|
||||||
public class I18nBundle {
|
|
||||||
private static final Log log = LogFactory.getLog(I18nBundle.class);
|
|
||||||
private static final String START_SEP = "\u25a4";
|
|
||||||
private static final String END_SEP = "\u25a5";
|
|
||||||
public static final String INT_SEP = "\u25a6";
|
public static final String INT_SEP = "\u25a6";
|
||||||
private static final String MESSAGE_BUNDLE_NOT_FOUND = "Text bundle ''{0}'' not found.";
|
public String text(String key, Object... parameters);
|
||||||
private static final String MESSAGE_KEY_NOT_FOUND = "Text bundle ''{0}'' has no text for ''{1}''";
|
|
||||||
|
|
||||||
public static I18nBundle emptyBundle(String bundleName,
|
|
||||||
I18nLogger i18nLogger) {
|
|
||||||
return new I18nBundle(bundleName, i18nLogger);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String bundleName;
|
|
||||||
private final ResourceBundle resources;
|
|
||||||
private final String notFoundMessage;
|
|
||||||
private final I18nLogger i18nLogger;
|
|
||||||
|
|
||||||
private I18nBundle(String bundleName, I18nLogger i18nLogger) {
|
|
||||||
this(bundleName, new EmptyResourceBundle(), MESSAGE_BUNDLE_NOT_FOUND,
|
|
||||||
i18nLogger);
|
|
||||||
}
|
|
||||||
|
|
||||||
public I18nBundle(String bundleName, ResourceBundle resources,
|
|
||||||
I18nLogger i18nLogger) {
|
|
||||||
this(bundleName, resources, MESSAGE_KEY_NOT_FOUND, i18nLogger);
|
|
||||||
}
|
|
||||||
|
|
||||||
private I18nBundle(String bundleName, ResourceBundle resources,
|
|
||||||
String notFoundMessage, I18nLogger i18nLogger) {
|
|
||||||
if (bundleName == null) {
|
|
||||||
throw new IllegalArgumentException("bundleName may not be null");
|
|
||||||
}
|
|
||||||
if (bundleName.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("bundleName may not be empty");
|
|
||||||
}
|
|
||||||
if (resources == null) {
|
|
||||||
throw new NullPointerException("resources may not be null.");
|
|
||||||
}
|
|
||||||
if (notFoundMessage == null) {
|
|
||||||
throw new NullPointerException("notFoundMessage may not be null.");
|
|
||||||
}
|
|
||||||
this.bundleName = bundleName;
|
|
||||||
this.resources = resources;
|
|
||||||
this.notFoundMessage = notFoundMessage;
|
|
||||||
this.i18nLogger = i18nLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String text(String key, Object... parameters) {
|
|
||||||
String textString;
|
|
||||||
if (resources.containsKey(key)) {
|
|
||||||
textString = resources.getString(key);
|
|
||||||
log.debug("In '" + bundleName + "', " + key + "='" + textString
|
|
||||||
+ "')");
|
|
||||||
} else {
|
|
||||||
String message = MessageFormat.format(notFoundMessage, bundleName,
|
|
||||||
key);
|
|
||||||
log.warn(message);
|
|
||||||
textString = "ERROR: " + message;
|
|
||||||
}
|
|
||||||
String message = formatString(textString, parameters);
|
|
||||||
|
|
||||||
if (i18nLogger != null) {
|
|
||||||
i18nLogger.log(bundleName, key, parameters, textString, message);
|
|
||||||
}
|
|
||||||
if (isNeedExportInfo()) {
|
|
||||||
String separatedArgs = "";
|
|
||||||
for (int i = 0; i < parameters.length; i++) {
|
|
||||||
separatedArgs += parameters[i] + INT_SEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return START_SEP + key + INT_SEP + textString + INT_SEP + separatedArgs + message + END_SEP;
|
|
||||||
} else {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isNeedExportInfo() {
|
|
||||||
return DeveloperSettings.getInstance().getBoolean(Key.I18N_ONLINE_TRANSLATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String formatString(String textString, Object... parameters) {
|
|
||||||
if (parameters.length == 0) {
|
|
||||||
return textString;
|
|
||||||
} else {
|
|
||||||
return MessageFormat.format(textString, parameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A resource bundle that contains no strings.
|
|
||||||
*/
|
|
||||||
public static class EmptyResourceBundle extends ResourceBundle {
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getKeys() {
|
|
||||||
return Collections.enumeration(Collections.<String> emptySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object handleGetObject(String key) {
|
|
||||||
if (key == null) {
|
|
||||||
throw new NullPointerException("key may not be null.");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
public class I18nContextListener implements ServletContextListener{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
initializeTranslationProvider(sce);
|
||||||
|
initializeTranslationConverter(sce);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeTranslationConverter(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
TranslationConverter.getInstance().initialize(ctx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeTranslationProvider(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
TranslationProvider.getInstance().initialize(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,32 +13,29 @@ import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||||
/**
|
/**
|
||||||
* If enabled in developer mode, write a message to the log each time someone
|
* If enabled in developer mode, write a message to the log each time someone
|
||||||
* asks for a language string.
|
* asks for a language string.
|
||||||
*
|
|
||||||
* The I18nBundle has a life span of one HTTP request, and so does this.
|
|
||||||
*/
|
*/
|
||||||
public class I18nLogger {
|
public class I18nLogger {
|
||||||
private static final Log log = LogFactory.getLog(I18nLogger.class);
|
private static final Log log = LogFactory.getLog(I18nLogger.class);
|
||||||
|
private DeveloperSettings settings;
|
||||||
private final boolean isLogging;
|
|
||||||
|
|
||||||
public I18nLogger() {
|
public I18nLogger() {
|
||||||
DeveloperSettings settings = DeveloperSettings.getInstance();
|
settings = DeveloperSettings.getInstance();
|
||||||
this.isLogging = settings.getBoolean(Key.I18N_LOG_STRINGS)
|
|
||||||
&& log.isInfoEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(String bundleName, String key, Object[] parameters,
|
public void log(String key, Object[] parameters, String rawText, String formattedText) {
|
||||||
String rawText, String formattedText) {
|
if (isI18nLoggingTurnedOn()) {
|
||||||
if (isLogging) {
|
|
||||||
String message = String.format(
|
String message = String.format(
|
||||||
"Retrieved from %s.%s with %s: '%s'", bundleName, key,
|
"Retrieved from %s with %s: '%s'", key,
|
||||||
Arrays.toString(parameters), rawText);
|
Arrays.toString(parameters), rawText);
|
||||||
|
|
||||||
if (!rawText.equals(formattedText)) {
|
if (!rawText.equals(formattedText)) {
|
||||||
message += String.format(" --> '%s'", formattedText);
|
message += String.format(" --> '%s'", formattedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(message);
|
log.info(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isI18nLoggingTurnedOn() {
|
||||||
|
return settings.getBoolean(Key.I18N_LOG_STRINGS) && log.isInfoEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class I18nSemanticBundle implements I18nBundle {
|
||||||
|
|
||||||
|
private List<String> preferredLocales = Collections.emptyList();
|
||||||
|
|
||||||
|
public I18nSemanticBundle(List<Locale> preferredLocales){
|
||||||
|
this.preferredLocales = convertToStrings(preferredLocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> convertToStrings(List<Locale> preferredLocales) {
|
||||||
|
return preferredLocales.stream().map(Locale::toLanguageTag).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String text(String key, Object... parameters) {
|
||||||
|
final TranslationProvider provider = TranslationProvider.getInstance();
|
||||||
|
return provider.getTranslation(preferredLocales, key, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||||
|
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.jena.ontology.OntModel;
|
||||||
|
import org.apache.jena.ontology.OntModelSpec;
|
||||||
|
import org.apache.jena.query.ParameterizedSparqlString;
|
||||||
|
import org.apache.jena.query.Query;
|
||||||
|
import org.apache.jena.query.QueryExecution;
|
||||||
|
import org.apache.jena.query.QueryExecutionFactory;
|
||||||
|
import org.apache.jena.query.QueryFactory;
|
||||||
|
import org.apache.jena.query.QuerySolution;
|
||||||
|
import org.apache.jena.query.QuerySolutionMap;
|
||||||
|
import org.apache.jena.query.ResultSet;
|
||||||
|
import org.apache.jena.rdf.model.ModelFactory;
|
||||||
|
import org.apache.jena.rdf.model.RDFNode;
|
||||||
|
import org.apache.jena.rdf.model.Literal;
|
||||||
|
import org.apache.jena.rdf.model.ResourceFactory;
|
||||||
|
import org.apache.jena.shared.Lock;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION;
|
||||||
|
|
||||||
|
|
||||||
|
public class TranslationConverter {
|
||||||
|
|
||||||
|
protected OntModel memModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
protected ServletContext ctx;
|
||||||
|
private static final boolean BEGIN = true;
|
||||||
|
private static final boolean END = !BEGIN;
|
||||||
|
private static final int SUFFIX_LENGTH = ".properties".length();
|
||||||
|
private static final Log log = LogFactory.getLog(TranslationConverter.class);
|
||||||
|
private static final TranslationConverter INSTANCE = new TranslationConverter();
|
||||||
|
private static final String THEMES = "themes";
|
||||||
|
private static final String ALL = "all";
|
||||||
|
protected static final String APP_I18N_PATH = "/i18n/";
|
||||||
|
protected static final String LOCAL_I18N_PATH = "/local/i18n/";
|
||||||
|
protected static final String THEMES_PATH = "/themes/";
|
||||||
|
private static final String TEMPLATE_BODY = ""
|
||||||
|
+ "?uri <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#NamedIndividual> .\n"
|
||||||
|
+ "?uri <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> .\n"
|
||||||
|
+ "?uri <http://vivoweb.org/ontology/core/properties/vocabulary#hasApp> ?application .\n"
|
||||||
|
+ "?uri <http://vivoweb.org/ontology/core/properties/vocabulary#hasKey> ?key .\n";
|
||||||
|
private static final String TEMPLATE_LABEL = ""
|
||||||
|
+ "?uri <http://www.w3.org/2000/01/rdf-schema#label> ?label .\n";
|
||||||
|
private static final String TEMPLATE_THEME = ""
|
||||||
|
+ "?uri <http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme> ?theme .\n";
|
||||||
|
|
||||||
|
private static final String queryWithTheme(String langTag) {
|
||||||
|
return
|
||||||
|
"SELECT ?uri ?label WHERE {"
|
||||||
|
+ TEMPLATE_BODY
|
||||||
|
+ optionalLabel(langTag)
|
||||||
|
+ TEMPLATE_THEME
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String queryNoTheme(String langTag) {
|
||||||
|
return
|
||||||
|
"SELECT ?uri ?label WHERE {"
|
||||||
|
+ TEMPLATE_BODY
|
||||||
|
+ optionalLabel(langTag)
|
||||||
|
+ "FILTER NOT EXISTS {"
|
||||||
|
+ TEMPLATE_THEME
|
||||||
|
+ "}"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String optionalLabel(String langTag) {
|
||||||
|
return
|
||||||
|
"OPTIONAL {"
|
||||||
|
+ "?uri <http://www.w3.org/2000/01/rdf-schema#label> ?label .\n "
|
||||||
|
+ "FILTER (LANG(?label)=\"" + langTag + "\")"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TranslationConverter getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(ServletContext ctx) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
OntModel tdbModel = ModelAccess.on(ctx).getOntModel(ModelNames.INTERFACE_I18N);
|
||||||
|
RDFService rdfService = ModelAccess.on(ctx).getRDFService(CONFIGURATION);
|
||||||
|
memModel.add(tdbModel);
|
||||||
|
convertAll();
|
||||||
|
cleanTdbModel(tdbModel, rdfService);
|
||||||
|
updateTDBModel(rdfService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanTdbModel(OntModel storedModel, RDFService rdfService) {
|
||||||
|
ChangeSet cs = makeChangeSet(rdfService);
|
||||||
|
ByteArrayOutputStream removeOS = new ByteArrayOutputStream();
|
||||||
|
storedModel.write(removeOS, "N3");
|
||||||
|
InputStream removeIS = new ByteArrayInputStream(removeOS.toByteArray());
|
||||||
|
cs.addRemoval(removeIS, RDFServiceUtils.getSerializationFormatFromJenaString("N3"), ModelNames.INTERFACE_I18N);
|
||||||
|
try {
|
||||||
|
rdfService.changeSetUpdate(cs);
|
||||||
|
} catch (RDFServiceException e) {
|
||||||
|
log.error(e,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTDBModel(RDFService rdfService) {
|
||||||
|
ChangeSet cs = makeChangeSet(rdfService);
|
||||||
|
ByteArrayOutputStream addOS = new ByteArrayOutputStream();
|
||||||
|
memModel.write(addOS, "N3");
|
||||||
|
InputStream addIS = new ByteArrayInputStream(addOS.toByteArray());
|
||||||
|
cs.addAddition(addIS, RDFServiceUtils.getSerializationFormatFromJenaString("N3"), ModelNames.INTERFACE_I18N);
|
||||||
|
try {
|
||||||
|
rdfService.changeSetUpdate(cs);
|
||||||
|
} catch (RDFServiceException e) {
|
||||||
|
log.error(e,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void convertAll() {
|
||||||
|
List<String> i18nDirs = new LinkedList<>(Arrays.asList(APP_I18N_PATH, LOCAL_I18N_PATH, THEMES_PATH));
|
||||||
|
List<String> prefixes = VitroResourceBundle.getAppPrefixes();
|
||||||
|
prefixes.add("");
|
||||||
|
String prefixesRegex = "(" + StringUtils.join(prefixes, ALL + "|") + ALL + ")";
|
||||||
|
log.debug("prefixesRegex " + prefixesRegex);
|
||||||
|
for (String dir : i18nDirs) {
|
||||||
|
File realDir = new File(ctx.getRealPath(dir));
|
||||||
|
Collection<File> files = FileUtils.listFiles(realDir, new RegexFileFilter(prefixesRegex + ".*\\.properties"), DirectoryFileFilter.DIRECTORY);
|
||||||
|
for (File file : files) {
|
||||||
|
convert(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convert(File file) {
|
||||||
|
Properties props = new Properties();
|
||||||
|
try (Reader reader = new InputStreamReader( new FileInputStream(file), "UTF-8")) {
|
||||||
|
props.load(reader);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e,e);
|
||||||
|
}
|
||||||
|
if (props == null || props.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("Converting properties " + file.getAbsolutePath());
|
||||||
|
String theme = getTheme(file);
|
||||||
|
String application = getApplication(file);
|
||||||
|
String language = getLanguage(file);
|
||||||
|
String langTag = getLanguageTag(language);
|
||||||
|
StringWriter additions = new StringWriter();
|
||||||
|
StringWriter retractionsN3 = new StringWriter();
|
||||||
|
for (Object key : props.keySet()) {
|
||||||
|
Object value = props.get(key);
|
||||||
|
QueryExecution queryExecution = getQueryExecution(key.toString(), theme, application, langTag);
|
||||||
|
ResultSet results = queryExecution.execSelect();
|
||||||
|
String uri = null;
|
||||||
|
if (results.hasNext()) {
|
||||||
|
QuerySolution solution = results.nextSolution();
|
||||||
|
uri = solution.get("uri").toString();
|
||||||
|
String label = getLabel(solution);
|
||||||
|
if (labelAreadyExists(value, label)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!StringUtils.isBlank(label)) {
|
||||||
|
String retraction = fillOutLabelTemplate(uri, label, langTag);
|
||||||
|
retractionsN3.append(retraction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String addition = fillOutTemplate(uri, key.toString(), value.toString(), theme, application, langTag);
|
||||||
|
additions.append(addition);
|
||||||
|
}
|
||||||
|
log.debug("Remove from model" + retractionsN3.toString());
|
||||||
|
log.debug("Add to model" + additions.toString());
|
||||||
|
OntModel addModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
OntModel removeModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
|
addModel.read(new StringReader(additions.toString()), null, "n3");
|
||||||
|
removeModel.read(new StringReader(retractionsN3.toString()), null, "n3");
|
||||||
|
memModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
try {
|
||||||
|
memModel.remove(removeModel);
|
||||||
|
memModel.add(addModel);
|
||||||
|
} finally {
|
||||||
|
memModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
log.info("Conversion finished for properties " + file.getAbsolutePath());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLanguageTag(String language) {
|
||||||
|
return language.replaceAll("_","-");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLabel(QuerySolution solution) {
|
||||||
|
final RDFNode label = solution.get("label");
|
||||||
|
if (label == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return ((Literal)label).getLexicalForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean labelAreadyExists(Object value, String label) {
|
||||||
|
return label.equals(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fillOutTemplate(String uri, String key, String newLabel, String theme, String application, String langTag) {
|
||||||
|
if (StringUtils.isBlank(uri)) {
|
||||||
|
return fillOutFullTemplate(key, newLabel, theme, application, langTag);
|
||||||
|
} else {
|
||||||
|
return fillOutLabelTemplate(uri, newLabel, langTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fillOutLabelTemplate(String uri, String label, String langTag) {
|
||||||
|
ParameterizedSparqlString pss = new ParameterizedSparqlString();
|
||||||
|
pss.setCommandText(TEMPLATE_LABEL);
|
||||||
|
pss.setIri("uri", uri);
|
||||||
|
pss.setLiteral("label", label, langTag);
|
||||||
|
return pss.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fillOutFullTemplate(String key, String label, String theme, String application, String langTag) {
|
||||||
|
String template = getBodyTemplate(theme);
|
||||||
|
ParameterizedSparqlString pss = new ParameterizedSparqlString();
|
||||||
|
pss.setCommandText(template);
|
||||||
|
pss.setIri("uri", createUUID());
|
||||||
|
pss.setLiteral("label", label, langTag);
|
||||||
|
pss.setLiteral("key", key);
|
||||||
|
pss.setLiteral("application", application);
|
||||||
|
if (!StringUtils.isBlank(theme)) {
|
||||||
|
pss.setLiteral("theme", theme);
|
||||||
|
}
|
||||||
|
return pss.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryExecution getQueryExecution(String key, String theme, String application, String langTag) {
|
||||||
|
Query query;
|
||||||
|
QuerySolutionMap bindings = new QuerySolutionMap();
|
||||||
|
bindings.add("application", ResourceFactory.createStringLiteral(application));
|
||||||
|
bindings.add("key", ResourceFactory.createStringLiteral(key));
|
||||||
|
if (StringUtils.isBlank(theme)) {
|
||||||
|
query = QueryFactory.create(queryNoTheme(langTag));
|
||||||
|
} else {
|
||||||
|
query = QueryFactory.create(queryWithTheme(langTag));
|
||||||
|
bindings.add("theme", ResourceFactory.createStringLiteral(theme));
|
||||||
|
}
|
||||||
|
QueryExecution qexec = QueryExecutionFactory.create(query, memModel, bindings);
|
||||||
|
return qexec;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createUUID() {
|
||||||
|
return "urn:uuid:" + UUID.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBodyTemplate(String theme) {
|
||||||
|
if (StringUtils.isBlank(theme)) {
|
||||||
|
return TEMPLATE_BODY + TEMPLATE_LABEL;
|
||||||
|
}
|
||||||
|
return TEMPLATE_BODY + TEMPLATE_LABEL + TEMPLATE_THEME;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLanguage(File file) {
|
||||||
|
String name = file.getName();
|
||||||
|
if (!name.contains("_")) {
|
||||||
|
return "en_US";
|
||||||
|
}
|
||||||
|
int startIndex;
|
||||||
|
if (name.contains("_all")) {
|
||||||
|
startIndex = name.indexOf("_all_") + 5;
|
||||||
|
} else {
|
||||||
|
startIndex = name.indexOf("_") + 1;
|
||||||
|
}
|
||||||
|
int endIndex = name.length() - SUFFIX_LENGTH;
|
||||||
|
|
||||||
|
return name.substring(startIndex,endIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getApplication(File file) {
|
||||||
|
String name = file.getName();
|
||||||
|
if (name.toLowerCase().contains("vivo")) {
|
||||||
|
return "VIVO";
|
||||||
|
}
|
||||||
|
return "Vitro";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTheme(File file) {
|
||||||
|
File parent = file.getParentFile();
|
||||||
|
if (parent == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (THEMES.equals(parent.getName())) {
|
||||||
|
return file.getName();
|
||||||
|
}
|
||||||
|
return getTheme(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChangeSet makeChangeSet(RDFService rdfService) {
|
||||||
|
ChangeSet cs = rdfService.manufactureChangeSet();
|
||||||
|
cs.addPreChangeEvent(new BulkUpdateEvent(null, BEGIN));
|
||||||
|
cs.addPostChangeEvent(new BulkUpdateEvent(null, END));
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,235 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.jena.query.QuerySolution;
|
||||||
|
import org.apache.jena.rdf.model.Literal;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.LevelRevisionInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.ResultSetConsumer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.sparqlrunner.QueryHolder;
|
||||||
|
|
||||||
|
public class TranslationProvider {
|
||||||
|
|
||||||
|
private static final String MESSAGE_KEY_NOT_FOUND = "ERROR: Translation not found ''{0}''";
|
||||||
|
private static final TranslationProvider INSTANCE = new TranslationProvider();
|
||||||
|
private static final Log log = LogFactory.getLog(TranslationProvider.class);
|
||||||
|
private static final I18nLogger i18nLogger = new I18nLogger();
|
||||||
|
private static final String QUERY = ""
|
||||||
|
+ "PREFIX : <http://vivoweb.org/ontology/core/properties/vocabulary#>\n"
|
||||||
|
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
|
||||||
|
+ "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n"
|
||||||
|
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> \n"
|
||||||
|
+ "SELECT ?translation \n" + "WHERE {\n"
|
||||||
|
+ " GRAPH <http://vitro.mannlib.cornell.edu/default/interface-i18n> {\n"
|
||||||
|
+ " ?uri :hasKey ?key .\n"
|
||||||
|
+ " ?uri rdfs:label ?translation .\n"
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " ?uri :hasTheme ?found_theme .\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " ?uri :hasApp ?found_application .\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " BIND(COALESCE(?found_theme, \"none\") as ?theme ) .\n"
|
||||||
|
+ " FILTER(?theme = \"none\" || ?theme = ?current_theme) . "
|
||||||
|
+ " BIND(COALESCE(?found_application, \"none\") as ?application ) .\n"
|
||||||
|
+ " BIND(IF(?current_application = ?application && ?current_theme = ?theme, 3, "
|
||||||
|
+ " IF(?current_theme = ?theme, 2, "
|
||||||
|
+ " IF(?current_application = ?application, 1, 0)) ) AS ?order ) .\n"
|
||||||
|
+ " }\n" + "} \n"
|
||||||
|
+ "ORDER by DESC(?order)";
|
||||||
|
|
||||||
|
protected RDFService rdfService;
|
||||||
|
protected String application = "Vitro";
|
||||||
|
private Map<TranslationKey, String> cache = new ConcurrentHashMap<>();
|
||||||
|
private String theme = "vitro";
|
||||||
|
private int prefixLen = "themes/".length();
|
||||||
|
private int suffixLen = "/".length();
|
||||||
|
private WebappDaoFactory wdf;
|
||||||
|
|
||||||
|
public static TranslationProvider getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(ServletContext ctx) {
|
||||||
|
RevisionInfoBean info = (RevisionInfoBean) ctx.getAttribute(RevisionInfoBean.ATTRIBUTE_NAME);
|
||||||
|
List<LevelRevisionInfo> levelInfos = info.getLevelInfos();
|
||||||
|
setApplication(levelInfos);
|
||||||
|
rdfService = ModelAccess.on(ctx).getRDFService(CONFIGURATION);
|
||||||
|
wdf = ModelAccess.on(ctx).getWebappDaoFactory();
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTheme() {
|
||||||
|
final String themeDir = wdf.getApplicationDao().getApplicationBean().getThemeDir();
|
||||||
|
final int length = themeDir.length();
|
||||||
|
theme = themeDir.substring(prefixLen, length - suffixLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheme(String theme) {
|
||||||
|
this.theme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setApplication(List<LevelRevisionInfo> levelInfos) {
|
||||||
|
if (levelInfos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
application = levelInfos.get(0).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTranslation(List<String> preferredLocales, String key, Object[] parameters) {
|
||||||
|
TranslationKey tk = new TranslationKey(preferredLocales, key, parameters);
|
||||||
|
if (cache.containsKey(tk) && !needExportInfo()) {
|
||||||
|
log.debug("Returned value from cache for " + key);
|
||||||
|
return cache.get(tk);
|
||||||
|
}
|
||||||
|
String text = getText(preferredLocales, key);
|
||||||
|
String formattedText = formatString(text, parameters);
|
||||||
|
i18nLogger.log(key, parameters, text, formattedText);
|
||||||
|
if (needExportInfo()) {
|
||||||
|
return prepareExportInfo(key, parameters, text, formattedText);
|
||||||
|
} else {
|
||||||
|
cache.put(tk, formattedText);
|
||||||
|
log.debug("Added to cache " + key);
|
||||||
|
log.debug("Returned value from request for " + key);
|
||||||
|
return formattedText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String prepareExportInfo(String key, Object[] parameters, String text, String message) {
|
||||||
|
String separatedArgs = "";
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
separatedArgs += parameters[i] + I18nBundle.INT_SEP;
|
||||||
|
}
|
||||||
|
log.debug("Returned value with export info for " + key );
|
||||||
|
return I18nBundle.START_SEP + key + I18nBundle.INT_SEP + text + I18nBundle.INT_SEP + separatedArgs
|
||||||
|
+ message + I18nBundle.END_SEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getText(List<String> preferredLocales, String key) {
|
||||||
|
String textString;
|
||||||
|
QueryHolder queryHolder = new QueryHolder(QUERY)
|
||||||
|
.bindToPlainLiteral("current_application", application)
|
||||||
|
.bindToPlainLiteral("key", key)
|
||||||
|
.bindToPlainLiteral("current_theme", theme)
|
||||||
|
.bindToPlainLiteral("locale", preferredLocales.get(0));
|
||||||
|
|
||||||
|
LanguageFilteringRDFService lfrs = new LanguageFilteringRDFService(rdfService, preferredLocales);
|
||||||
|
List<String> list = new LinkedList<>();
|
||||||
|
try {
|
||||||
|
lfrs.sparqlSelectQuery(queryHolder.getQueryString(), new ResultSetConsumer() {
|
||||||
|
@Override
|
||||||
|
protected void processQuerySolution(QuerySolution qs) {
|
||||||
|
Literal translation = qs.getLiteral("translation");
|
||||||
|
if (translation != null) {
|
||||||
|
list.add(translation.getLexicalForm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (RDFServiceException e) {
|
||||||
|
log.error(e,e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
textString = notFound(key);
|
||||||
|
} else {
|
||||||
|
textString = list.get(0);
|
||||||
|
}
|
||||||
|
return textString;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean needExportInfo() {
|
||||||
|
return DeveloperSettings.getInstance().getBoolean(Key.I18N_ONLINE_TRANSLATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatString(String textString, Object... parameters) {
|
||||||
|
if (parameters.length == 0) {
|
||||||
|
return textString;
|
||||||
|
} else {
|
||||||
|
return MessageFormat.format(TranslationProvider.preprocessForFormating(textString), parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should prepare the inputText for MessageFormat.format method. At the moment it is replacing single
|
||||||
|
* apostrophe with double, it might be extented in the future with some additional preprocessing.
|
||||||
|
* @param inputText - string which should be preprocessed
|
||||||
|
* @return preprocessed input string, i.e. string with replaced single apostrophe with double
|
||||||
|
*/
|
||||||
|
public static String preprocessForFormating(String inputText){
|
||||||
|
if (inputText != null) {
|
||||||
|
return inputText.replace("''", "'").replace("'", "''");
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String notFound(String key) {
|
||||||
|
return MessageFormat.format(MESSAGE_KEY_NOT_FOUND, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearCache() {
|
||||||
|
if (wdf != null) {
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
cache.clear();
|
||||||
|
log.info("Translation cache cleared");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TranslationKey {
|
||||||
|
|
||||||
|
private List<String> preferredLocales;
|
||||||
|
private String key;
|
||||||
|
private Object[] parameters;
|
||||||
|
|
||||||
|
public TranslationKey(List<String> preferredLocales, String key, Object[] parameters) {
|
||||||
|
this.preferredLocales = preferredLocales;
|
||||||
|
this.key = key;
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (! (obj instanceof TranslationKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TranslationKey other = (TranslationKey) obj;
|
||||||
|
return new EqualsBuilder()
|
||||||
|
.append(preferredLocales, other.preferredLocales)
|
||||||
|
.append(key, other.key)
|
||||||
|
.append(parameters, other.parameters)
|
||||||
|
.isEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(){
|
||||||
|
return new HashCodeBuilder()
|
||||||
|
.append(preferredLocales)
|
||||||
|
.append(key)
|
||||||
|
.append(parameters)
|
||||||
|
.toHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,54 +2,15 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.i18n;
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.text.MessageFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works like a PropertyResourceBundle with two exceptions:
|
* If you use 3 tier architecture with custom prefix for properties files
|
||||||
|
* you can add it with {@link #addAppPrefix(String)}
|
||||||
*
|
*
|
||||||
* It looks for the file in both the i18n directory of the theme and in the i18n
|
|
||||||
* directory of the application. Properties found in the theme override those
|
|
||||||
* found in the application.
|
|
||||||
*
|
|
||||||
* It allows a property to take its contents from a file. File paths are
|
|
||||||
* relative to the i18n directory. Again, a file in the theme will override one
|
|
||||||
* in the application.
|
|
||||||
*
|
|
||||||
* If a property has a value (after overriding) of "@@file <filepath>", the
|
|
||||||
* bundle looks for the file relative to the i18n directory of the theme, then
|
|
||||||
* relative to the i18n directory of the application. If the file is not found
|
|
||||||
* in either location, a warning is written to the log and the property will
|
|
||||||
* contain an error message for displayed.
|
|
||||||
*
|
|
||||||
* Note that the filename is not manipulated for Locale, so the author of the
|
|
||||||
* properties files must do it explicitly. For example:
|
|
||||||
*
|
|
||||||
* In all.properties: account_email_html = @@file accountEmail.html
|
|
||||||
*
|
|
||||||
* In all_es.properties: account_email_html = @@file accountEmail_es.html
|
|
||||||
*/
|
*/
|
||||||
public class VitroResourceBundle extends ResourceBundle {
|
public class VitroResourceBundle {
|
||||||
private static final Log log = LogFactory.getLog(VitroResourceBundle.class);
|
|
||||||
|
|
||||||
private static final String FILE_FLAG = "@@file ";
|
|
||||||
private static final String MESSAGE_FILE_NOT_FOUND = "File {1} not found for property {0}.";
|
|
||||||
|
|
||||||
private static final List<String> appPrefixes = new ArrayList<>();
|
private static final List<String> appPrefixes = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -57,6 +18,10 @@ public class VitroResourceBundle extends ResourceBundle {
|
||||||
addAppPrefix("vitro");
|
addAppPrefix("vitro");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getAppPrefixes(){
|
||||||
|
return appPrefixes;
|
||||||
|
}
|
||||||
|
|
||||||
public static void addAppPrefix(String prefix) {
|
public static void addAppPrefix(String prefix) {
|
||||||
if (!prefix.endsWith("-") && !prefix.endsWith("_")) {
|
if (!prefix.endsWith("-") && !prefix.endsWith("_")) {
|
||||||
prefix = prefix + "_";
|
prefix = prefix + "_";
|
||||||
|
@ -67,188 +32,4 @@ public class VitroResourceBundle extends ResourceBundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Factory method
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the bundle for the for foo_ba_RR, providing that
|
|
||||||
* foo_ba_RR.properties exists in the I18n area of either the theme or the
|
|
||||||
* application.
|
|
||||||
*
|
|
||||||
* If the desired file doesn't exist in either location, return null.
|
|
||||||
* Usually, this does not indicate a problem but only that we were looking
|
|
||||||
* for too specific a bundle. For example, if the base name of the bundle is
|
|
||||||
* "all" and the locale is "en_US", we will likely return null on the search
|
|
||||||
* for all_en_US.properties, and all_en.properties, but will return a full
|
|
||||||
* bundle for all.properties.
|
|
||||||
*
|
|
||||||
* Of course, if all.properties doesn't exist either, then we have a
|
|
||||||
* problem, but that will be reported elsewhere.
|
|
||||||
*
|
|
||||||
* @return the populated bundle or null.
|
|
||||||
*/
|
|
||||||
public static VitroResourceBundle getBundle(String bundleName,
|
|
||||||
ServletContext ctx, String appI18nPath, String themeI18nPath,
|
|
||||||
Control control) {
|
|
||||||
try {
|
|
||||||
return new VitroResourceBundle(bundleName, ctx, appI18nPath,
|
|
||||||
themeI18nPath, control);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
log.debug(e.getMessage());
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn(e, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// The instance
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private final String bundleName;
|
|
||||||
private final ServletContext ctx;
|
|
||||||
private final String appI18nPath;
|
|
||||||
private final String themeI18nPath;
|
|
||||||
private final Control control;
|
|
||||||
private final Properties properties;
|
|
||||||
|
|
||||||
private VitroResourceBundle(String bundleName, ServletContext ctx,
|
|
||||||
String appI18nPath, String themeI18nPath, Control control)
|
|
||||||
throws IOException {
|
|
||||||
this.bundleName = bundleName;
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.appI18nPath = appI18nPath;
|
|
||||||
this.themeI18nPath = themeI18nPath;
|
|
||||||
this.control = control;
|
|
||||||
this.properties = loadProperties();
|
|
||||||
loadReferencedFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Properties loadProperties() throws IOException {
|
|
||||||
String resourceName = control.toResourceName(bundleName, "properties");
|
|
||||||
Properties props = null;
|
|
||||||
|
|
||||||
File defaultsPath = locateFile(joinPath(appI18nPath, resourceName));
|
|
||||||
File propertiesPath = locateFile(joinPath(themeI18nPath, resourceName));
|
|
||||||
|
|
||||||
props = loadProperties(props, defaultsPath);
|
|
||||||
if (appPrefixes != null && appPrefixes.size() > 0) {
|
|
||||||
for (String appPrefix : appPrefixes) {
|
|
||||||
props = loadProperties(props, locateFile(joinPath(appI18nPath, (appPrefix + resourceName))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
props = loadProperties(props, propertiesPath);
|
|
||||||
if (props == null) {
|
|
||||||
throw new FileNotFoundException("Property file not found at '" + defaultsPath + "' or '" + propertiesPath + "'");
|
|
||||||
}
|
|
||||||
props = loadProperties(props, locateFile(joinPath("/local/i18n/", resourceName)));
|
|
||||||
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Properties loadProperties(Properties defProps, File file) throws IOException {
|
|
||||||
if (file == null || !file.isFile()) {
|
|
||||||
return defProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties props = null;
|
|
||||||
if (defProps != null) {
|
|
||||||
props = new Properties(defProps);
|
|
||||||
} else {
|
|
||||||
props = new Properties();
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("Loading bundle '" + bundleName + "' defaults from '" + file + "'");
|
|
||||||
FileInputStream stream = new FileInputStream(file);
|
|
||||||
Reader reader = new InputStreamReader(stream, "UTF-8");
|
|
||||||
try {
|
|
||||||
props.load(reader);
|
|
||||||
} finally {
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.size() > 0) {
|
|
||||||
return props;
|
|
||||||
}
|
|
||||||
|
|
||||||
return defProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadReferencedFiles() throws IOException {
|
|
||||||
for (String key : this.properties.stringPropertyNames()) {
|
|
||||||
String value = this.properties.getProperty(key);
|
|
||||||
if (value.startsWith(FILE_FLAG)) {
|
|
||||||
String filepath = value.substring(FILE_FLAG.length()).trim();
|
|
||||||
loadReferencedFile(key, filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadReferencedFile(String key, String filepath)
|
|
||||||
throws IOException {
|
|
||||||
String appFilePath = joinPath(appI18nPath, filepath);
|
|
||||||
String themeFilePath = joinPath(themeI18nPath, filepath);
|
|
||||||
File appFile = locateFile(appFilePath);
|
|
||||||
File themeFile = locateFile(themeFilePath);
|
|
||||||
|
|
||||||
if (themeFile != null) {
|
|
||||||
this.properties.setProperty(key,
|
|
||||||
FileUtils.readFileToString(themeFile, "UTF-8"));
|
|
||||||
} else if (appFile != null) {
|
|
||||||
this.properties.setProperty(key,
|
|
||||||
FileUtils.readFileToString(appFile, "UTF-8"));
|
|
||||||
} else {
|
|
||||||
String message = MessageFormat.format(MESSAGE_FILE_NOT_FOUND, key,
|
|
||||||
themeFilePath, appFilePath);
|
|
||||||
this.properties.setProperty(key, message);
|
|
||||||
log.warn(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String joinPath(String root, String twig) {
|
|
||||||
if ((root.charAt(root.length() - 1) == File.separatorChar)
|
|
||||||
|| (twig.charAt(0) == File.separatorChar)) {
|
|
||||||
return root + twig;
|
|
||||||
} else {
|
|
||||||
return root + File.separatorChar + twig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File locateFile(String path) {
|
|
||||||
String realPath = ctx.getRealPath(path);
|
|
||||||
if (realPath == null) {
|
|
||||||
log.debug("No real path for '" + path + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
File f = new File(realPath);
|
|
||||||
if (!f.isFile()) {
|
|
||||||
log.debug("No file at '" + realPath + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!f.canRead()) {
|
|
||||||
log.error("Can't read the file at '" + realPath + "'");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.debug("Located file '" + path + "' at '" + realPath + "'");
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public Enumeration<String> getKeys() {
|
|
||||||
return (Enumeration<String>) this.properties.propertyNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object handleGetObject(String key) {
|
|
||||||
String value = this.properties.getProperty(key);
|
|
||||||
if (value == null) {
|
|
||||||
log.debug(bundleName + " has no value for '" + key + "'");
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,21 +15,17 @@ import freemarker.template.TemplateModelException;
|
||||||
* wrapper around an I18nBundle.
|
* wrapper around an I18nBundle.
|
||||||
*/
|
*/
|
||||||
public class I18nBundleTemplateModel implements TemplateHashModel {
|
public class I18nBundleTemplateModel implements TemplateHashModel {
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory.getLog(I18nBundleTemplateModel.class);
|
||||||
.getLog(I18nBundleTemplateModel.class);
|
|
||||||
|
|
||||||
private final String bundleName;
|
|
||||||
private final I18nBundle textBundle;
|
private final I18nBundle textBundle;
|
||||||
|
|
||||||
public I18nBundleTemplateModel(String bundleName, I18nBundle textBundle) {
|
public I18nBundleTemplateModel( I18nBundle textBundle) {
|
||||||
this.bundleName = bundleName;
|
|
||||||
this.textBundle = textBundle;
|
this.textBundle = textBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TemplateModel get(String key) throws TemplateModelException {
|
public TemplateModel get(String key) throws TemplateModelException {
|
||||||
return new I18nStringTemplateModel(bundleName, key,
|
return new I18nStringTemplateModel(key, textBundle.text(key));
|
||||||
textBundle.text(key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -12,7 +12,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
|
||||||
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
|
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
|
||||||
import freemarker.core.Environment;
|
import freemarker.core.Environment;
|
||||||
import freemarker.template.TemplateMethodModel;
|
import freemarker.template.TemplateMethodModelEx;
|
||||||
import freemarker.template.TemplateModelException;
|
import freemarker.template.TemplateModelException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,30 +21,15 @@ import freemarker.template.TemplateModelException;
|
||||||
*
|
*
|
||||||
* If the bundle name is not provided, the default bundle is assumed.
|
* If the bundle name is not provided, the default bundle is assumed.
|
||||||
*/
|
*/
|
||||||
public class I18nMethodModel implements TemplateMethodModel {
|
public class I18nMethodModel implements TemplateMethodModelEx {
|
||||||
private static final Log log = LogFactory.getLog(I18nMethodModel.class);
|
private static final Log log = LogFactory.getLog(I18nMethodModel.class);
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
@Override
|
@Override
|
||||||
public Object exec(List args) throws TemplateModelException {
|
public Object exec(List args) throws TemplateModelException {
|
||||||
if (args.size() > 1) {
|
|
||||||
throw new TemplateModelException("Too many arguments: "
|
|
||||||
+ "displayText method only requires a bundle name.");
|
|
||||||
}
|
|
||||||
Object arg = args.isEmpty() ? I18n.DEFAULT_BUNDLE_NAME : args.get(0);
|
|
||||||
if (!(arg instanceof String)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Arguments to a TemplateMethodModel are supposed to be Strings!");
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("Asking for this bundle: " + arg);
|
|
||||||
String bundleName = (String) arg;
|
|
||||||
|
|
||||||
Environment env = Environment.getCurrentEnvironment();
|
Environment env = Environment.getCurrentEnvironment();
|
||||||
HttpServletRequest request = (HttpServletRequest) env
|
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
|
||||||
.getCustomAttribute("request");
|
I18nBundle tb = I18n.bundle(request);
|
||||||
I18nBundle tb = I18n.bundle(bundleName, request);
|
return new I18nBundleTemplateModel(tb);
|
||||||
return new I18nBundleTemplateModel(bundleName, tb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.i18n.TranslationProvider;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
@ -37,13 +38,10 @@ public class I18nStringTemplateModel implements TemplateMethodModelEx,
|
||||||
private static final Log log = LogFactory
|
private static final Log log = LogFactory
|
||||||
.getLog(I18nStringTemplateModel.class);
|
.getLog(I18nStringTemplateModel.class);
|
||||||
|
|
||||||
private final String bundleName;
|
|
||||||
private final String key;
|
private final String key;
|
||||||
private final String textString;
|
private final String textString;
|
||||||
|
|
||||||
public I18nStringTemplateModel(String bundleName, String key,
|
public I18nStringTemplateModel( String key, String textString) {
|
||||||
String textString) {
|
|
||||||
this.bundleName = bundleName;
|
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.textString = textString;
|
this.textString = textString;
|
||||||
}
|
}
|
||||||
|
@ -56,8 +54,7 @@ public class I18nStringTemplateModel implements TemplateMethodModelEx,
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
@Override
|
@Override
|
||||||
public Object exec(List args) throws TemplateModelException {
|
public Object exec(List args) throws TemplateModelException {
|
||||||
log.debug("Formatting string '" + key + "' from bundle '" + bundleName
|
log.debug("Formatting string '" + key + "' with these arguments: " + args);
|
||||||
+ "' with these arguments: " + args);
|
|
||||||
|
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
return textString;
|
return textString;
|
||||||
|
@ -71,11 +68,10 @@ public class I18nStringTemplateModel implements TemplateMethodModelEx,
|
||||||
if(isOnlineTranslationsEnabled()) {
|
if(isOnlineTranslationsEnabled()) {
|
||||||
return getOnlineTranslationsFormattedMessage(textString, unwrappedArgs);
|
return getOnlineTranslationsFormattedMessage(textString, unwrappedArgs);
|
||||||
} else {
|
} else {
|
||||||
return MessageFormat.format(textString, unwrappedArgs);
|
return MessageFormat.format(TranslationProvider.preprocessForFormating(textString), unwrappedArgs);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String message = "Can't format '" + key + "' from bundle '"
|
String message = "Can't format '" + key + "', wrong argument types: " + args
|
||||||
+ bundleName + "', wrong argument types: " + args
|
|
||||||
+ " for message format'" + textString + "'";
|
+ " for message format'" + textString + "'";
|
||||||
log.warn(message);
|
log.warn(message);
|
||||||
return message;
|
return message;
|
||||||
|
@ -88,13 +84,13 @@ public class I18nStringTemplateModel implements TemplateMethodModelEx,
|
||||||
* and combines preProcessed string back to be used with online translations.
|
* and combines preProcessed string back to be used with online translations.
|
||||||
* Substitutes arguments in message which is a part of preProcessed string
|
* Substitutes arguments in message which is a part of preProcessed string
|
||||||
* @param preProcessed String "startSep + key + intSep + textString + intSep + message + endSep"
|
* @param preProcessed String "startSep + key + intSep + textString + intSep + message + endSep"
|
||||||
* @param arguments that should be listed before message and substituted in the message itself
|
* @param args that should be listed before message and substituted in the message itself
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getOnlineTranslationsFormattedMessage(String preProcessed, Object[] args) {
|
private String getOnlineTranslationsFormattedMessage(String preProcessed, Object[] args) {
|
||||||
String[] parts = preProcessed.split(I18nBundle.INT_SEP);
|
String[] parts = preProcessed.split(I18nBundle.INT_SEP);
|
||||||
final int messageIndex = parts.length -1;
|
final int messageIndex = parts.length -1;
|
||||||
String message = MessageFormat.format(parts[messageIndex], args);
|
String message = MessageFormat.format(TranslationProvider.preprocessForFormating(parts[messageIndex]), args);
|
||||||
String[] arguments = convertToArrayOfStrings(args);
|
String[] arguments = convertToArrayOfStrings(args);
|
||||||
parts[messageIndex] = "";
|
parts[messageIndex] = "";
|
||||||
String result = String.join(I18nBundle.INT_SEP, parts) +
|
String result = String.join(I18nBundle.INT_SEP, parts) +
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class LocaleSelectionController extends HttpServlet {
|
||||||
if (!selectables.contains(locale)) {
|
if (!selectables.contains(locale)) {
|
||||||
log.warn("User selected a locale '" + locale
|
log.warn("User selected a locale '" + locale
|
||||||
+ "' that was not in the list: " + selectables);
|
+ "' that was not in the list: " + selectables);
|
||||||
} else if (!LocaleUtils.isAvailableLocale(locale)) {
|
} else if (!LocaleUtils.isAvailableLocale(locale.stripExtensions())) {
|
||||||
log.warn("User selected an unrecognized locale: '" + locale + "'");
|
log.warn("User selected an unrecognized locale: '" + locale + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,7 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
|
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -36,7 +31,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
|
||||||
* { [a map for each Locale]
|
* { [a map for each Locale]
|
||||||
* code = [the code for the Locale, e.g. "en_US"]
|
* code = [the code for the Locale, e.g. "en_US"]
|
||||||
* label = [the alt text for the Locale, e.g. "Spanish (Spain)"]
|
* label = [the alt text for the Locale, e.g. "Spanish (Spain)"]
|
||||||
* imageUrl = [the URL of the image that represents the Locale]
|
* country = [the country for the Locale, e.g. "United States"]
|
||||||
|
* institution = [the abbreviation for institution, e.g. "UQAM"]
|
||||||
* selected = [true, if this locale is currently selected]
|
* selected = [true, if this locale is currently selected]
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
@ -50,6 +46,8 @@ public class LocaleSelectionDataGetter implements DataGetter {
|
||||||
|
|
||||||
private final VitroRequest vreq;
|
private final VitroRequest vreq;
|
||||||
|
|
||||||
|
private static final char PRIVATE_USE_SUBTAG = 'x';
|
||||||
|
|
||||||
public LocaleSelectionDataGetter(VitroRequest vreq) {
|
public LocaleSelectionDataGetter(VitroRequest vreq) {
|
||||||
this.vreq = vreq;
|
this.vreq = vreq;
|
||||||
}
|
}
|
||||||
|
@ -73,10 +71,23 @@ public class LocaleSelectionDataGetter implements DataGetter {
|
||||||
|
|
||||||
private List<Map<String, Object>> buildLocalesList(List<Locale> selectables) {
|
private List<Map<String, Object>> buildLocalesList(List<Locale> selectables) {
|
||||||
Locale currentLocale = SelectedLocale.getCurrentLocale(vreq);
|
Locale currentLocale = SelectedLocale.getCurrentLocale(vreq);
|
||||||
|
// The next couple of lines check whether there are locales in the list with the same root.
|
||||||
|
// If yes, the institution abbreviation (private tag) will be displayed in UI.
|
||||||
|
// For instance, if there are fr_CA_x_uqam and fr_CA in a VIVO instance runtime.properties,
|
||||||
|
// the institutional abbreviation (UQAM) will be displayed next to locale name
|
||||||
|
// in the dropdown menu for selection of a UI language.
|
||||||
|
boolean includeAbbreviation = false;
|
||||||
|
Set<String> setOfLocalesBase = new HashSet<>();
|
||||||
|
for(final Locale locale: selectables) {
|
||||||
|
setOfLocalesBase.add(locale.stripExtensions().toLanguageTag());
|
||||||
|
}
|
||||||
|
if (setOfLocalesBase.size() < selectables.size()) {
|
||||||
|
includeAbbreviation = true;
|
||||||
|
}
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
for (Locale locale : selectables) {
|
for (Locale locale : selectables) {
|
||||||
try {
|
try {
|
||||||
list.add(buildLocaleMap(locale, currentLocale));
|
list.add(buildLocaleMap(locale, currentLocale, includeAbbreviation));
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
log.warn("Can't show the Locale selector for '" + locale
|
log.warn("Can't show the Locale selector for '" + locale
|
||||||
+ "': " + e);
|
+ "': " + e);
|
||||||
|
@ -86,12 +97,15 @@ public class LocaleSelectionDataGetter implements DataGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> buildLocaleMap(Locale locale,
|
private Map<String, Object> buildLocaleMap(Locale locale,
|
||||||
Locale currentLocale) throws FileNotFoundException {
|
Locale currentLocale, boolean includeAbbreviation) throws FileNotFoundException {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
map.put("code", locale.toLanguageTag().replace('-','_'));
|
map.put("code", locale.toLanguageTag().replace('-','_'));
|
||||||
map.put("label", locale.getDisplayLanguage(locale));
|
map.put("label", locale.getDisplayLanguage(locale));
|
||||||
map.put("country", locale.getDisplayCountry(locale));
|
map.put("country", locale.getDisplayCountry(locale));
|
||||||
|
if (includeAbbreviation) {
|
||||||
|
map.put("institution", Optional.ofNullable(locale.getExtension(LocaleSelectionDataGetter.PRIVATE_USE_SUBTAG)).orElse("").toUpperCase());
|
||||||
|
}
|
||||||
map.put("selected", currentLocale.equals(locale));
|
map.put("selected", currentLocale.equals(locale));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class LocaleSelectionSetup implements ServletContextListener {
|
||||||
Locale locale = LocaleUtility.languageStringToLocale(localeString);
|
Locale locale = LocaleUtility.languageStringToLocale(localeString);
|
||||||
|
|
||||||
if (!"es_GO".equals(localeString) && // No complaint about bogus locale
|
if (!"es_GO".equals(localeString) && // No complaint about bogus locale
|
||||||
!LocaleUtils.isAvailableLocale(locale)) {
|
!LocaleUtils.isAvailableLocale(locale.stripExtensions())) {
|
||||||
ssWarning("'" + locale + "' is not a recognized locale.");
|
ssWarning("'" + locale + "' is not a recognized locale.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,10 @@ public class ModelNames {
|
||||||
public static final String DISPLAY_TBOX_FIRSTTIME_BACKUP = DISPLAY_TBOX + "FirsttimeBackup";
|
public static final String DISPLAY_TBOX_FIRSTTIME_BACKUP = DISPLAY_TBOX + "FirsttimeBackup";
|
||||||
public static final String DISPLAY_DISPLAY = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel";
|
public static final String DISPLAY_DISPLAY = "http://vitro.mannlib.cornell.edu/default/vitro-kb-displayMetadata-displayModel";
|
||||||
public static final String DISPLAY_DISPLAY_FIRSTTIME_BACKUP = DISPLAY_DISPLAY + "FirsttimeBackup";
|
public static final String DISPLAY_DISPLAY_FIRSTTIME_BACKUP = DISPLAY_DISPLAY + "FirsttimeBackup";
|
||||||
|
public static final String INTERFACE_I18N = "http://vitro.mannlib.cornell.edu/default/interface-i18n";
|
||||||
|
public static final String INTERFACE_I18N_FIRSTTIME_BACKUP = INTERFACE_I18N + "FirsttimeBackup";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of the URIS, keyed by their short names, intended only for display
|
* A map of the URIS, keyed by their short names, intended only for display
|
||||||
|
@ -64,6 +68,9 @@ public class ModelNames {
|
||||||
map.put("DISPLAY_TBOX_FIRSTTIME_BACKUP", DISPLAY_TBOX_FIRSTTIME_BACKUP);
|
map.put("DISPLAY_TBOX_FIRSTTIME_BACKUP", DISPLAY_TBOX_FIRSTTIME_BACKUP);
|
||||||
map.put("DISPLAY_DISPLAY", DISPLAY_DISPLAY);
|
map.put("DISPLAY_DISPLAY", DISPLAY_DISPLAY);
|
||||||
map.put("DISPLAY_DISPLAY_FIRSTTIME_BACKUP", DISPLAY_DISPLAY_FIRSTTIME_BACKUP);
|
map.put("DISPLAY_DISPLAY_FIRSTTIME_BACKUP", DISPLAY_DISPLAY_FIRSTTIME_BACKUP);
|
||||||
|
map.put("INTERFACE_I18N", INTERFACE_I18N);
|
||||||
|
map.put("INTERFACE_I18N_FIRSTTIME_BACKUP", INTERFACE_I18N_FIRSTTIME_BACKUP);
|
||||||
|
|
||||||
return Collections.unmodifiableMap(map);
|
return Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@ import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOU
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_FIRSTTIME_BACKUP;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_FIRSTTIME_BACKUP;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX_FIRSTTIME_BACKUP;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX_FIRSTTIME_BACKUP;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY_FIRSTTIME_BACKUP;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY_FIRSTTIME_BACKUP;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.INTERFACE_I18N ;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.INTERFACE_I18N_FIRSTTIME_BACKUP;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.jena.rdf.model.ModelMaker;
|
import org.apache.jena.rdf.model.ModelMaker;
|
||||||
|
@ -25,11 +28,21 @@ public abstract class ConfigurationTripleSource implements TripleSource {
|
||||||
* A list of all Configuration models, in case the implementation wants to
|
* A list of all Configuration models, in case the implementation wants to
|
||||||
* add memory-mapping.
|
* add memory-mapping.
|
||||||
*/
|
*/
|
||||||
protected static final String[] CONFIGURATION_MODELS = { DISPLAY,
|
protected static final String[] CONFIGURATION_MODELS = {
|
||||||
DISPLAY_TBOX, DISPLAY_DISPLAY, USER_ACCOUNTS, ABOX_ASSERTIONS_FIRSTTIME_BACKUP,
|
DISPLAY,
|
||||||
TBOX_ASSERTIONS_FIRSTTIME_BACKUP, APPLICATION_METADATA_FIRSTTIME_BACKUP,
|
DISPLAY_TBOX,
|
||||||
USER_ACCOUNTS_FIRSTTIME_BACKUP, DISPLAY_FIRSTTIME_BACKUP,
|
DISPLAY_DISPLAY,
|
||||||
DISPLAY_TBOX_FIRSTTIME_BACKUP, DISPLAY_DISPLAY_FIRSTTIME_BACKUP };
|
USER_ACCOUNTS,
|
||||||
|
ABOX_ASSERTIONS_FIRSTTIME_BACKUP,
|
||||||
|
TBOX_ASSERTIONS_FIRSTTIME_BACKUP,
|
||||||
|
APPLICATION_METADATA_FIRSTTIME_BACKUP,
|
||||||
|
USER_ACCOUNTS_FIRSTTIME_BACKUP,
|
||||||
|
DISPLAY_FIRSTTIME_BACKUP,
|
||||||
|
DISPLAY_TBOX_FIRSTTIME_BACKUP,
|
||||||
|
DISPLAY_DISPLAY_FIRSTTIME_BACKUP,
|
||||||
|
INTERFACE_I18N,
|
||||||
|
INTERFACE_I18N_FIRSTTIME_BACKUP,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These decorators are added to a Configuration ModelMaker, regardless of
|
* These decorators are added to a Configuration ModelMaker, regardless of
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class LanguageFilteringUtils {
|
||||||
* (as in RDF language specifiers).
|
* (as in RDF language specifiers).
|
||||||
*/
|
*/
|
||||||
public static String localeToLanguage(Locale locale) {
|
public static String localeToLanguage(Locale locale) {
|
||||||
return locale.toString().replace(UNDERSCORE, HYPHEN);
|
return locale.toLanguageTag().replace(UNDERSCORE, HYPHEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,9 +69,9 @@ public class LanguageFilteringUtils {
|
||||||
List<String> langs = new ArrayList<>();
|
List<String> langs = new ArrayList<>();
|
||||||
while (locales.hasMoreElements()) {
|
while (locales.hasMoreElements()) {
|
||||||
Locale locale = (Locale) locales.nextElement();
|
Locale locale = (Locale) locales.nextElement();
|
||||||
langs.add(locale.toString().replace(UNDERSCORE, HYPHEN));
|
langs.add(locale.toLanguageTag().replace(UNDERSCORE, HYPHEN));
|
||||||
}
|
}
|
||||||
if (langs.isEmpty()) {
|
if (!langs.contains(DEFAULT_LANG_STRING)) {
|
||||||
langs.add(DEFAULT_LANG_STRING);
|
langs.add(DEFAULT_LANG_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_DISPLAY;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY_TBOX;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS;
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.USER_ACCOUNTS;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.INTERFACE_I18N;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
@ -13,17 +14,10 @@ import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
import org.apache.jena.ontology.OntModel;
|
import org.apache.jena.ontology.OntModel;
|
||||||
import org.apache.jena.rdf.model.Model;
|
import org.apache.jena.rdf.model.Model;
|
||||||
import org.apache.jena.rdf.model.Property;
|
|
||||||
import org.apache.jena.rdf.model.RDFNode;
|
|
||||||
import org.apache.jena.rdf.model.Resource;
|
|
||||||
import org.apache.jena.rdf.model.Statement;
|
|
||||||
import org.apache.jena.rdf.model.StmtIterator;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
@ -46,6 +40,7 @@ public class ConfigurationModelsSetup implements ServletContextListener {
|
||||||
setupModel(ctx, DISPLAY_TBOX, "displayTbox");
|
setupModel(ctx, DISPLAY_TBOX, "displayTbox");
|
||||||
setupModel(ctx, DISPLAY_DISPLAY, "displayDisplay");
|
setupModel(ctx, DISPLAY_DISPLAY, "displayDisplay");
|
||||||
setupModel(ctx, USER_ACCOUNTS, "auth");
|
setupModel(ctx, USER_ACCOUNTS, "auth");
|
||||||
|
setupModel(ctx, INTERFACE_I18N, "interface-i18n");
|
||||||
ss.info(this, "Set up the display models and the user accounts model.");
|
ss.info(this, "Set up the display models and the user accounts model.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ss.fatal(this, e.getMessage(), e.getCause());
|
ss.fatal(this, e.getMessage(), e.getCause());
|
||||||
|
|
|
@ -137,7 +137,19 @@ public class RDFFilesLoader {
|
||||||
// Which locales are enabled in runtime.properties?
|
// Which locales are enabled in runtime.properties?
|
||||||
List<Locale> locales = SelectedLocale.getSelectableLocales(ctx);
|
List<Locale> locales = SelectedLocale.getSelectableLocales(ctx);
|
||||||
for (Locale locale : locales) {
|
for (Locale locale : locales) {
|
||||||
enabledLocales.add(locale.toLanguageTag().replace('-', '_'));
|
String localeString = locale.toLanguageTag().replace('-', '_');
|
||||||
|
if (! enabledLocales.contains(localeString)) {
|
||||||
|
enabledLocales.add(localeString);
|
||||||
|
}
|
||||||
|
// If a locale with fr_CA_x_uqam is used, the locale fr_CA should be also enabled for loading.
|
||||||
|
// Private tags (lang_CountryCode_x_InstitutionAbbreviation) are inteded to be just extension,
|
||||||
|
// therefore the basic locale (lang_CountryCode) should be loaded as well.
|
||||||
|
if(locale.hasExtensions()){
|
||||||
|
localeString = locale.stripExtensions().toLanguageTag().replace('-', '_');
|
||||||
|
if (! enabledLocales.contains(localeString)) {
|
||||||
|
enabledLocales.add(localeString);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no languages were enabled in runtime.properties, add a fallback as the default
|
// If no languages were enabled in runtime.properties, add a fallback as the default
|
||||||
|
|
|
@ -4,6 +4,9 @@ package edu.cornell.mannlib.vitro.webapp.utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -18,112 +21,227 @@ import org.apache.jena.query.ResultSet;
|
||||||
import org.apache.jena.rdf.model.Model;
|
import org.apache.jena.rdf.model.Model;
|
||||||
import org.apache.jena.rdf.model.ModelFactory;
|
import org.apache.jena.rdf.model.ModelFactory;
|
||||||
import org.apache.jena.rdf.model.Resource;
|
import org.apache.jena.rdf.model.Resource;
|
||||||
import org.apache.jena.rdf.model.ResourceFactory;
|
|
||||||
import org.apache.jena.vocabulary.RDFS;
|
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxDataPropertyWrapper;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxObjectPropertyWrapper;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxPropertyWrapper;
|
||||||
|
|
||||||
public class ApplicationConfigurationOntologyUtils {
|
public class ApplicationConfigurationOntologyUtils {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class);
|
private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class);
|
||||||
|
|
||||||
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, Individual subject, VitroRequest vreq) {
|
private static final String getPossibleFauxQuery(boolean isData) {
|
||||||
Model displayModel = vreq.getDisplayModel();
|
return
|
||||||
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
|
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
|
||||||
return getAdditionalFauxSubpropertiesForList(propList, subject, displayModel, tboxModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ObjectProperty> getAdditionalFauxSubproperties(ObjectProperty prop,
|
|
||||||
Individual subject,
|
|
||||||
Model tboxModel,
|
|
||||||
Model union) {
|
|
||||||
|
|
||||||
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
|
|
||||||
String queryStr = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
|
|
||||||
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
|
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
|
||||||
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
|
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
|
||||||
"SELECT DISTINCT ?range ?domain ?property WHERE { \n" +
|
"SELECT DISTINCT ?domain ?property ?context ?isData WHERE { \n" +
|
||||||
" ?context config:configContextFor ?property . \n" +
|
" ?context config:configContextFor ?property . \n" +
|
||||||
" ?context config:qualifiedBy ?range . \n" +
|
(isData ?
|
||||||
|
"?property a <http://www.w3.org/2002/07/owl#DatatypeProperty> . \n"
|
||||||
|
:
|
||||||
|
"?property a <http://www.w3.org/2002/07/owl#ObjectProperty> . \n" ) +
|
||||||
|
" OPTIONAL { ?context config:qualifiedBy ?range . } \n " +
|
||||||
" ?context config:hasConfiguration ?configuration . \n" +
|
" ?context config:hasConfiguration ?configuration . \n" +
|
||||||
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
|
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
|
||||||
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
|
" OPTIONAL { ?context config:qualifiedByDomain ?domain } . \n" +
|
||||||
"}";
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
if(prop != null) {
|
private static String getFauxPropQuery(String baseUri, boolean optionalRange) {
|
||||||
log.debug("Checking " + prop.getURI() + " for additional properties");
|
return
|
||||||
queryStr = queryStr.replaceAll("For \\?property", "For <" + prop.getURI() + ">");
|
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
|
||||||
}
|
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
|
||||||
log.debug(queryStr);
|
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
|
||||||
Query q = QueryFactory.create(queryStr);
|
"SELECT DISTINCT ?domain ?context WHERE { \n" +
|
||||||
|
" ?context config:configContextFor <" + baseUri + "> . \n" +
|
||||||
|
(optionalRange ? " OPTIONAL { " : "") +
|
||||||
|
" ?context config:qualifiedBy ?range . \n" +
|
||||||
|
(optionalRange ? " } " : "") +
|
||||||
|
" ?context config:hasConfiguration ?configuration . \n" +
|
||||||
|
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
|
||||||
|
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FauxObjectPropertyWrapper> getPopulatedFauxOPs(List<ObjectProperty> populatedObjectProperties, Individual subject, VitroRequest vreq) {
|
||||||
|
List<FauxObjectPropertyWrapper> fauxProperties = new ArrayList<FauxObjectPropertyWrapper>();
|
||||||
|
for (ObjectProperty op : populatedObjectProperties) {
|
||||||
|
fauxProperties.addAll(getPopulatedFauxObjectProperties(op, subject, vreq));
|
||||||
|
}
|
||||||
|
return fauxProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FauxDataPropertyWrapper> getPopulatedFauxDPs(List<DataProperty> populatedDataProperties, Individual subject, VitroRequest vreq) {
|
||||||
|
List<FauxDataPropertyWrapper> fauxProperties = new ArrayList<FauxDataPropertyWrapper>();
|
||||||
|
for (DataProperty dp : populatedDataProperties) {
|
||||||
|
fauxProperties.addAll(getPopulatedFauxDataProperties(dp, subject, vreq));
|
||||||
|
}
|
||||||
|
return fauxProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<FauxObjectPropertyWrapper> getPopulatedFauxObjectProperties(ObjectProperty op, Individual subject, VitroRequest vreq) {
|
||||||
|
Model displayModel = vreq.getDisplayModel();
|
||||||
|
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
|
||||||
|
Model union = ModelFactory.createUnion(displayModel, tboxModel);
|
||||||
|
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
|
||||||
|
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
|
||||||
|
|
||||||
|
Query q = createQuery(op, false);
|
||||||
QueryExecution qe = QueryExecutionFactory.create(q, union);
|
QueryExecution qe = QueryExecutionFactory.create(q, union);
|
||||||
WebappDaoFactory wadf = new WebappDaoFactoryJena(
|
List<FauxObjectPropertyWrapper> fauxObjectProps = new ArrayList<FauxObjectPropertyWrapper>();
|
||||||
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
|
|
||||||
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
|
||||||
try {
|
try {
|
||||||
ResultSet rs = qe.execSelect();
|
ResultSet rs = qe.execSelect();
|
||||||
while (rs.hasNext()) {
|
while (rs.hasNext()) {
|
||||||
QuerySolution qsoln = rs.nextSolution();
|
QuerySolution qsoln = rs.nextSolution();
|
||||||
log.debug(qsoln);
|
log.debug(qsoln);
|
||||||
String opURI = (prop != null) ? prop.getURI() : qsoln.getResource(
|
|
||||||
"property").getURI();
|
|
||||||
Resource domainRes = qsoln.getResource("domain");
|
Resource domainRes = qsoln.getResource("domain");
|
||||||
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
|
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
|
||||||
String rangeURI = qsoln.getResource("range").getURI();
|
String contextURI = qsoln.getResource("context").getURI();
|
||||||
if (appropriateDomain(domainRes, subject, tboxModel)) {
|
if (isDomainMatchSubject(domainURI, subject)) {
|
||||||
ObjectProperty faux = opDao.getObjectPropertyByURIs(
|
try {
|
||||||
opURI, domainURI, rangeURI, (prop != null) ? prop.clone() : null);
|
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
|
||||||
if (faux != null) {
|
if (fp != null) {
|
||||||
additionalProps.add(faux);
|
fauxObjectProps.add(new FauxObjectPropertyWrapper(op.clone(), fp));
|
||||||
} else {
|
}
|
||||||
log.error("Could not retrieve " + opURI + " qualified by " +
|
} catch (Exception e) {
|
||||||
" domain " + domainURI + " and range " + rangeURI);
|
log.warn("Couldn't look up the faux property", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
qe.close();
|
qe.close();
|
||||||
}
|
}
|
||||||
return additionalProps;
|
return fauxObjectProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<FauxDataPropertyWrapper> getPopulatedFauxDataProperties(DataProperty dp, Individual subject, VitroRequest vreq) {
|
||||||
|
Model displayModel = vreq.getDisplayModel();
|
||||||
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList,
|
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
|
||||||
Individual subject,
|
|
||||||
Model displayModel,
|
|
||||||
Model tboxModel) {
|
|
||||||
|
|
||||||
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
|
|
||||||
Model union = ModelFactory.createUnion(displayModel, tboxModel);
|
Model union = ModelFactory.createUnion(displayModel, tboxModel);
|
||||||
|
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
|
||||||
|
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
|
||||||
|
|
||||||
for (ObjectProperty op : propList) {
|
Query q = createQuery(dp, true);
|
||||||
additionalProps.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union));
|
QueryExecution qe = QueryExecutionFactory.create(q, union);
|
||||||
|
List<FauxDataPropertyWrapper> fauxDataProps = new ArrayList<FauxDataPropertyWrapper>();
|
||||||
|
try {
|
||||||
|
ResultSet rs = qe.execSelect();
|
||||||
|
while (rs.hasNext()) {
|
||||||
|
QuerySolution qsoln = rs.nextSolution();
|
||||||
|
log.debug(qsoln);
|
||||||
|
Resource domainRes = qsoln.getResource("domain");
|
||||||
|
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
|
||||||
|
String contextURI = qsoln.getResource("context").getURI();
|
||||||
|
if (isDomainMatchSubject(domainURI, subject)) {
|
||||||
|
try {
|
||||||
|
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
|
||||||
|
if (fp != null) {
|
||||||
|
fauxDataProps.add(new FauxDataPropertyWrapper(dp, fp));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Couldn't look up the faux property", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
}
|
}
|
||||||
|
return fauxDataProps;
|
||||||
return additionalProps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) {
|
private static Query createQuery(Property op, boolean optionalRange) {
|
||||||
if (subject == null || domainRes == null) {
|
String queryStr = getFauxPropQuery(op.getURI(), optionalRange);
|
||||||
|
log.debug(queryStr);
|
||||||
|
Query q = QueryFactory.create(queryStr);
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDomainMatchSubject(String domainUri, Individual subject) {
|
||||||
|
if (subject == null || domainUri == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (VClass vclass : subject.getVClasses()) {
|
Set<String> vClassUris = subject.getVClasses().stream().map(vclass -> vclass.getURI())
|
||||||
if ((vclass.getURI() != null) &&
|
.collect(Collectors.toSet());
|
||||||
((vclass.getURI().equals(domainRes.getURI()) ||
|
for (String vClassUri : vClassUris) {
|
||||||
(tboxModel.contains(
|
if (vClassUri != null && vClassUri.equals(domainUri)) {
|
||||||
ResourceFactory.createResource(
|
|
||||||
vclass.getURI()), RDFS.subClassOf, domainRes))))) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<Property> getPossibleFauxProps(List<? extends FauxPropertyWrapper> curProps, Individual subject, VitroRequest vreq, boolean isData) {
|
||||||
|
Model displayModel = vreq.getDisplayModel();
|
||||||
|
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
|
||||||
|
Model union = ModelFactory.createUnion(displayModel, tboxModel);
|
||||||
|
Map<String, FauxProperty> curPropsMap = curProps.stream()
|
||||||
|
.collect(Collectors.toMap(FauxPropertyWrapper::getContextUri, FauxPropertyWrapper::getFauxProperty));
|
||||||
|
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
|
||||||
|
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
|
||||||
|
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
||||||
|
DataPropertyDao dpDao = wadf.getDataPropertyDao();
|
||||||
|
|
||||||
|
Query q = QueryFactory.create(getPossibleFauxQuery(isData));
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(q, union);
|
||||||
|
List<Property> fauxDataProps = new ArrayList<Property>();
|
||||||
|
try {
|
||||||
|
ResultSet rs = qe.execSelect();
|
||||||
|
while (rs.hasNext()) {
|
||||||
|
QuerySolution qsoln = rs.nextSolution();
|
||||||
|
Resource domainRes = qsoln.getResource("domain");
|
||||||
|
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
|
||||||
|
String basePropertyUri = qsoln.getResource("property").getURI();
|
||||||
|
String contextURI = qsoln.getResource("context").getURI();
|
||||||
|
if (isDomainMatchSubject(domainURI, subject) && !curPropsMap.containsKey(contextURI)) {
|
||||||
|
if (isData) {
|
||||||
|
addDataProperty(fauxDataProps, basePropertyUri, contextURI, fpDao, dpDao);
|
||||||
|
} else {
|
||||||
|
addObjectProperty(fauxDataProps, basePropertyUri, contextURI, fpDao, opDao);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
|
}
|
||||||
|
return fauxDataProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addObjectProperty(List<Property> fauxProps, String basePropertyUri, String contextURI,
|
||||||
|
FauxPropertyDao fpDao, ObjectPropertyDao opDao) {
|
||||||
|
try {
|
||||||
|
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
|
||||||
|
ObjectProperty op = opDao.getObjectPropertyByURI(basePropertyUri);
|
||||||
|
if (fp != null && op != null) {
|
||||||
|
fauxProps.add(new FauxObjectPropertyWrapper(op, fp));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Couldn't look up the faux object property, contextUri " + contextURI, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addDataProperty(List<Property> fauxProps, String basePropertyUri, String contextURI,
|
||||||
|
FauxPropertyDao fpDao, DataPropertyDao dpDao) {
|
||||||
|
try {
|
||||||
|
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
|
||||||
|
DataProperty dp = dpDao.getDataPropertyByURI(basePropertyUri);
|
||||||
|
if (fp != null && dp != null) {
|
||||||
|
fauxProps.add(new FauxDataPropertyWrapper(dp, fp));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Couldn't look up the faux data property, contextUri " + contextURI, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,17 @@ public final class LocaleUtility {
|
||||||
|
|
||||||
public static Locale languageStringToLocale(String localeString){
|
public static Locale languageStringToLocale(String localeString){
|
||||||
String[] parsedLoc = localeString.trim().split("_", -1);
|
String[] parsedLoc = localeString.trim().split("_", -1);
|
||||||
//regex pattern for locale tag with script specified
|
Locale locale = null;
|
||||||
Locale locale = localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}") ?
|
if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. sr_Latn_RS_x_uns
|
||||||
new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build() :
|
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).setExtension('x', parsedLoc[4]).build();
|
||||||
LocaleUtils.toLocale(localeString);
|
} else if (localeString.matches("^[a-z]{1,3}_[A-Za-z]{2}_x_[a-z]{1,}")) { //regex pattern for locale tag with script and private-use subtag, e.g. fr_CA_x_uqam
|
||||||
|
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[1]).setExtension('x', parsedLoc[3]).build();
|
||||||
|
} else if (localeString.matches("^[a-z]{1,3}_[A-Z][a-z]{3}_[A-Z]{2}")) { //regex pattern for locale tag with script specified, e.g. sr_Latn_RS
|
||||||
|
locale = new Locale.Builder().setLanguage(parsedLoc[0]).setRegion(parsedLoc[2]).setScript(parsedLoc[1]).build();
|
||||||
|
} else { // other, just languge, e.g. es, or language + region, e.g. en_US, pt_BR, ru_RU, etc.
|
||||||
|
locale = LocaleUtils.toLocale(localeString);
|
||||||
|
}
|
||||||
|
String localeLang = locale.toLanguageTag();
|
||||||
return locale;
|
return locale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,11 +209,11 @@ public class SearchQueryUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSortFieldNameForLocale(Locale locale) {
|
public static String getSortFieldNameForLocale(Locale locale) {
|
||||||
return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX;
|
return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_SORT_SUFFIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLabelFieldNameForLocale(Locale locale) {
|
public static String getLabelFieldNameForLocale(Locale locale) {
|
||||||
return locale.toString().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX;
|
return locale.toLanguageTag().replace('_', '-') + VitroSearchTermNames.LABEL_DISPLAY_SUFFIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchQuery getRandomQuery(List<String> vclassUris, int page, int pageSize){
|
public static SearchQuery getRandomQuery(List<String> vclassUris, int page, int pageSize){
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.directives;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
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.email.FreemarkerEmailMessage;
|
|
||||||
import freemarker.core.Environment;
|
|
||||||
import freemarker.template.TemplateDirectiveBody;
|
|
||||||
import freemarker.template.TemplateException;
|
|
||||||
import freemarker.template.TemplateModel;
|
|
||||||
import freemarker.template.TemplateModelException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the inputs for a FreemarkerEmailMessage.
|
|
||||||
*
|
|
||||||
* @see FreemarkerEmailMessage
|
|
||||||
*/
|
|
||||||
public class EmailDirective extends BaseTemplateDirectiveModel {
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(EmailDirective.class);
|
|
||||||
|
|
||||||
private final FreemarkerEmailMessage message;
|
|
||||||
|
|
||||||
public EmailDirective(FreemarkerEmailMessage message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Environment env, Map params, TemplateModel[] loopVars,
|
|
||||||
TemplateDirectiveBody body) throws TemplateException, IOException {
|
|
||||||
|
|
||||||
String subject = getOptionalSimpleScalarParameter(params, "subject");
|
|
||||||
if (subject != null) {
|
|
||||||
message.setSubject(subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
String htmlContent = getOptionalSimpleScalarParameter(params, "html");
|
|
||||||
if (htmlContent != null) {
|
|
||||||
message.setHtmlContent(htmlContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
String textContent = getOptionalSimpleScalarParameter(params, "text");
|
|
||||||
if (textContent != null) {
|
|
||||||
message.setTextContent(textContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((htmlContent == null) && (textContent == null)) {
|
|
||||||
throw new TemplateModelException("The email directive must have "
|
|
||||||
+ "either a 'html' parameter or a 'text' parameter.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> help(String name) {
|
|
||||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
|
||||||
|
|
||||||
map.put("effect",
|
|
||||||
"Create an email message from the parameters set in the invoking template.");
|
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<String, String>();
|
|
||||||
params.put("subject", "email subject (optional)");
|
|
||||||
params.put("html", "HTML version of email message (optional)");
|
|
||||||
params.put("text", "Plain text version of email message (optional)");
|
|
||||||
map.put("parameters", params);
|
|
||||||
|
|
||||||
List<String> examples = new ArrayList<String>();
|
|
||||||
examples.add("<email subject=\"Password reset confirmation\" html=html text=text>");
|
|
||||||
examples.add("<email html=html text=text>");
|
|
||||||
map.put("examples", examples);
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,332 @@
|
||||||
|
/* $This file is distributed under the terms of the license in LICENSE$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.jena.rdf.model.ResourceFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A DataProperty that has some of its values overridden by a FauxProperty.
|
||||||
|
*
|
||||||
|
* TODO This is a horrible kluge that should be discarded as soon as we can
|
||||||
|
* rewrite GroupedPropertyList.
|
||||||
|
*/
|
||||||
|
public class FauxDataPropertyWrapper extends DataProperty implements FauxPropertyWrapper{
|
||||||
|
private final DataProperty innerDP;
|
||||||
|
private final FauxProperty faux;
|
||||||
|
|
||||||
|
public FauxDataPropertyWrapper(DataProperty inner, FauxProperty faux) {
|
||||||
|
this.innerDP = inner;
|
||||||
|
this.faux = faux;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Methods where FauxProperty overrides.
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroupURI() {
|
||||||
|
String uri = faux.getGroupURI();
|
||||||
|
if (uri != null) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
return innerDP.getGroupURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGroupURI(String groupUri) {
|
||||||
|
faux.setGroupURI(groupUri);
|
||||||
|
innerDP.setGroupURI(groupUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDomainVClassURI() {
|
||||||
|
String uri = faux.getDomainVClassURI();
|
||||||
|
if (uri != null) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
return innerDP.getDomainVClassURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDomainVClassURI(String domainClassURI) {
|
||||||
|
faux.setDomainURI(domainClassURI);
|
||||||
|
innerDP.setDomainVClassURI(domainClassURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRangeVClassURI() {
|
||||||
|
String uri = faux.getRangeVClassURI();
|
||||||
|
if (uri != null) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
return innerDP.getRangeVClassURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRangeVClassURI(String rangeClassURI) {
|
||||||
|
faux.setRangeURI(rangeClassURI);
|
||||||
|
innerDP.setRangeVClassURI(rangeClassURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCustomEntryForm() {
|
||||||
|
String s = faux.getCustomEntryForm();
|
||||||
|
if (s != null) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return innerDP.getCustomEntryForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCustomEntryForm(String s) {
|
||||||
|
faux.setCustomEntryForm(s);
|
||||||
|
innerDP.setCustomEntryForm(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPublicDescription() {
|
||||||
|
String s = faux.getPublicDescription();
|
||||||
|
if (s != null) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return innerDP.getPublicDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPublicDescription(String s) {
|
||||||
|
faux.setPublicDescription(s);
|
||||||
|
innerDP.setPublicDescription(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPickListName() {
|
||||||
|
String name = faux.getDisplayName();
|
||||||
|
if (name != null) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
return innerDP.getPickListName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPickListName(String pickListName) {
|
||||||
|
faux.setDisplayName(pickListName);
|
||||||
|
innerDP.setPickListName(pickListName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Methods from DataProperty
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return innerDP.getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return innerDP.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDescription(String description) {
|
||||||
|
innerDP.setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExample() {
|
||||||
|
return innerDP.getExample();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExample(String example) {
|
||||||
|
innerDP.setExample(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDisplayTier() {
|
||||||
|
return faux.getDisplayTier();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getFunctional() {
|
||||||
|
return innerDP.getFunctional();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFunctional(boolean functional) {
|
||||||
|
innerDP.setFunctional(functional);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLabel(String label) {
|
||||||
|
innerDP.setLabel(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSubjectSide() {
|
||||||
|
return innerDP.isSubjectSide();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEditLinkSuppressed() {
|
||||||
|
return innerDP.isEditLinkSuppressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAddLinkSuppressed() {
|
||||||
|
return innerDP.isAddLinkSuppressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeleteLinkSuppressed() {
|
||||||
|
return innerDP.isDeleteLinkSuppressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEditLinkSuppressed(boolean editLinkSuppressed) {
|
||||||
|
innerDP.setEditLinkSuppressed(editLinkSuppressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAddLinkSuppressed(boolean addLinkSuppressed) {
|
||||||
|
innerDP.setAddLinkSuppressed(addLinkSuppressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) {
|
||||||
|
innerDP.setDeleteLinkSuppressed(deleteLinkSuppressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAnonymous() {
|
||||||
|
return innerDP.isAnonymous();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getURI() {
|
||||||
|
return innerDP.getURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setURI(String URI) {
|
||||||
|
innerDP.setURI(URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return innerDP.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNamespace(String namespace) {
|
||||||
|
innerDP.setNamespace(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLocalName() {
|
||||||
|
return innerDP.getLocalName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLocalName(String localName) {
|
||||||
|
innerDP.setLocalName(localName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLocalNameWithPrefix() {
|
||||||
|
return innerDP.getLocalNameWithPrefix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLocalNameWithPrefix(String prefixedLocalName) {
|
||||||
|
innerDP.setLocalNameWithPrefix(prefixedLocalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = prime * result + ((faux == null) ? 0 : faux.hashCode());
|
||||||
|
result = prime * result + ((innerDP == null) ? 0 : innerDP.hashCode());
|
||||||
|
return Objects.hash(innerDP, faux);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
FauxDataPropertyWrapper that = (FauxDataPropertyWrapper) obj;
|
||||||
|
return Objects.equals(this.innerDP, that.innerDP)
|
||||||
|
&& Objects.equals(this.faux, that.faux);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DataPropertyStatement> getDataPropertyStatements() {
|
||||||
|
return innerDP.getDataPropertyStatements();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("FauxDataPropertyWrapper[ %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]",
|
||||||
|
localName(getDomainVClassURI()),
|
||||||
|
localName(getURI()),
|
||||||
|
localName(getRangeVClassURI()),
|
||||||
|
(getDataPropertyStatements() == null ? 0: getDataPropertyStatements().size()),
|
||||||
|
localName(getGroupURI()),
|
||||||
|
simpleName(getCustomEntryForm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object simpleName(String classname) {
|
||||||
|
if (classname == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return classname.substring(classname.lastIndexOf(".") + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object localName(String uri) {
|
||||||
|
if (uri == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return ResourceFactory.createResource(uri).getLocalName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FauxProperty getFauxProperty() {
|
||||||
|
return faux;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContextUri() {
|
||||||
|
return faux.getContextUri();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
* TODO This is a horrible kluge that should be discarded as soon as we can
|
* TODO This is a horrible kluge that should be discarded as soon as we can
|
||||||
* rewrite GroupedPropertyList.
|
* rewrite GroupedPropertyList.
|
||||||
*/
|
*/
|
||||||
public class FauxObjectPropertyWrapper extends ObjectProperty {
|
public class FauxObjectPropertyWrapper extends ObjectProperty implements FauxPropertyWrapper{
|
||||||
private final ObjectProperty innerOP;
|
private final ObjectProperty innerOP;
|
||||||
private final FauxProperty faux;
|
private final FauxProperty faux;
|
||||||
|
|
||||||
|
@ -226,6 +226,10 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRangeEntityURI() {
|
public String getRangeEntityURI() {
|
||||||
|
String uri = faux.getRootRangeUri();
|
||||||
|
if (uri != null) {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
return innerOP.getRangeEntityURI();
|
return innerOP.getRangeEntityURI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +376,7 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDomainDisplayTier() {
|
public int getDomainDisplayTier() {
|
||||||
return innerOP.getDomainDisplayTier();
|
return faux.getDisplayTier();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -624,8 +628,11 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("FauxObjectPropertyWrapper[ %s <==> %s | %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]",
|
return String.format("FauxObjectPropertyWrapper[ %s <==> %s | %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]",
|
||||||
getDomainPublic(), getRangePublic(),
|
getDomainPublic(),
|
||||||
localName(getDomainVClassURI()), localName(getURI()), localName(getRangeVClassURI()),
|
getRangePublic(),
|
||||||
|
localName(getDomainVClassURI()),
|
||||||
|
localName(getURI()),
|
||||||
|
localName(getRangeVClassURI()),
|
||||||
(getObjectPropertyStatements() == null ? 0: getObjectPropertyStatements().size()),
|
(getObjectPropertyStatements() == null ? 0: getObjectPropertyStatements().size()),
|
||||||
localName(getGroupURI()),
|
localName(getGroupURI()),
|
||||||
simpleName(getCustomEntryForm()));
|
simpleName(getCustomEntryForm()));
|
||||||
|
@ -647,4 +654,14 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FauxProperty getFauxProperty() {
|
||||||
|
return faux;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContextUri() {
|
||||||
|
return faux.getContextUri();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||||
|
|
||||||
|
public interface FauxPropertyWrapper {
|
||||||
|
|
||||||
|
public FauxProperty getFauxProperty();
|
||||||
|
|
||||||
|
public String getContextUri();
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -17,7 +19,6 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.jena.vocabulary.OWL;
|
import org.apache.jena.vocabulary.OWL;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
|
@ -25,7 +26,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
||||||
|
@ -63,53 +63,53 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
|
|
||||||
private List<PropertyGroupTemplateModel> groups;
|
private List<PropertyGroupTemplateModel> groups;
|
||||||
|
|
||||||
GroupedPropertyList(Individual subject, VitroRequest vreq,
|
GroupedPropertyList(Individual subject, VitroRequest vreq, boolean editing) {
|
||||||
boolean editing) {
|
|
||||||
this.vreq = vreq;
|
this.vreq = vreq;
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
this.wdf = vreq.getWebappDaoFactory();
|
this.wdf = vreq.getWebappDaoFactory();
|
||||||
|
|
||||||
// Create the property list for the subject. The properties will be put
|
// Create the property list for the subject. The properties will be put
|
||||||
// into groups later.
|
// into groups later.
|
||||||
List<Property> propertyList = new ArrayList<Property>();
|
List<Property> allProperties = new ArrayList<Property>();
|
||||||
|
|
||||||
// First get all the object properties that occur in statements in the
|
// First get all the object properties that occur in statements in the
|
||||||
// db with this subject as subject.
|
// db with this subject as subject.
|
||||||
// This may include properties that are not defined as
|
// This may include properties that are not defined as
|
||||||
// "possible properties" for a subject of this class,
|
// "possible properties" for a subject of this class,
|
||||||
// so we cannot just rely on getting that list.
|
// so we cannot just rely on getting that list.
|
||||||
List<ObjectProperty> populatedObjectPropertyList = subject
|
List<ObjectProperty> populatedOPs = subject.getPopulatedObjectPropertyList();
|
||||||
.getPopulatedObjectPropertyList();
|
|
||||||
|
|
||||||
Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap(
|
Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap(populatedOPs);
|
||||||
populatedObjectPropertyList);
|
|
||||||
|
|
||||||
// save applicable ranges before deduping to filter later
|
// save applicable ranges before deduping to filter later
|
||||||
populatedObjectPropertyList = dedupe(populatedObjectPropertyList);
|
populatedOPs = dedupe(populatedOPs);
|
||||||
|
|
||||||
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
|
List<FauxObjectPropertyWrapper> populatedFauxOPs = ApplicationConfigurationOntologyUtils.getPopulatedFauxOPs(populatedOPs, subject, vreq);
|
||||||
.getAdditionalFauxSubpropertiesForList(
|
|
||||||
populatedObjectPropertyList, subject, vreq);
|
|
||||||
|
|
||||||
additions = filterAdditions(additions, populatedObjTypes);
|
populatedFauxOPs = filterAdditions(populatedFauxOPs, populatedObjTypes);
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
for (ObjectProperty t : additions) {
|
for (ObjectProperty fauxOP : populatedFauxOPs) {
|
||||||
log.debug("addition: " + t);
|
log.debug("faux object property: " + fauxOP);
|
||||||
}
|
}
|
||||||
log.debug("Added " + additions.size() +
|
log.debug("Added " + populatedFauxOPs.size() + " faux object properties due to application configuration ontology");
|
||||||
" properties due to application configuration ontology");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
populatedObjectPropertyList.addAll(additions);
|
if(editing) {
|
||||||
|
List<Property> possibleFauxProps = ApplicationConfigurationOntologyUtils.getPossibleFauxProps(populatedFauxOPs, subject, vreq, false);
|
||||||
|
allProperties.addAll(possibleFauxProps);
|
||||||
|
}
|
||||||
|
|
||||||
propertyList.addAll(populatedObjectPropertyList);
|
populatedOPs.addAll(populatedFauxOPs);
|
||||||
|
|
||||||
|
allProperties.addAll(populatedOPs);
|
||||||
|
|
||||||
// If editing this page, merge in object properties applicable to the individual that are currently
|
// If editing this page, merge in object properties applicable to the individual that are currently
|
||||||
// unpopulated, so the properties are displayed to allow statements to be added to these properties.
|
// unpopulated, so the properties are displayed to allow statements to be added to these properties.
|
||||||
// RY In future, we should limit this to properties that the user has permission to add properties to.
|
// RY In future, we should limit this to properties that the user has permission to add properties to.
|
||||||
if (editing) {
|
if (editing) {
|
||||||
propertyList = mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList);
|
List<Property> possibleOPs = getPossibleOPs(populatedOPs, allProperties, subject);
|
||||||
|
allProperties.addAll(possibleOPs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones
|
// Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones
|
||||||
|
@ -118,25 +118,36 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
// DataPropertyStatements. Note that this does not apply to object properties, because the queries
|
// DataPropertyStatements. Note that this does not apply to object properties, because the queries
|
||||||
// can be customized and thus differ from property to property. So it's easier for now to keep the
|
// can be customized and thus differ from property to property. So it's easier for now to keep the
|
||||||
// two working in parallel.
|
// two working in parallel.
|
||||||
List<DataProperty> populatedDataPropertyList = subject
|
List<DataProperty> populatedDPs = subject.getPopulatedDataPropertyList();
|
||||||
.getPopulatedDataPropertyList();
|
|
||||||
propertyList.addAll(populatedDataPropertyList);
|
|
||||||
|
|
||||||
if (editing) {
|
if (editing) {
|
||||||
mergeAllPossibleDataProperties(propertyList);
|
List<Property> possibleDPs = getPossibleDPs(populatedDPs, allProperties);
|
||||||
|
allProperties.addAll(possibleDPs);
|
||||||
}
|
}
|
||||||
sort(propertyList);
|
|
||||||
|
List<FauxDataPropertyWrapper> populatedFauxDPs = ApplicationConfigurationOntologyUtils.getPopulatedFauxDPs(populatedDPs, subject, vreq);
|
||||||
|
|
||||||
|
if(editing) {
|
||||||
|
List<Property> possibleFauxProps = ApplicationConfigurationOntologyUtils.getPossibleFauxProps(populatedFauxDPs, subject, vreq, true);
|
||||||
|
allProperties.addAll(possibleFauxProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
populatedDPs.addAll(populatedFauxDPs);
|
||||||
|
|
||||||
|
allProperties.addAll(populatedDPs);
|
||||||
|
|
||||||
|
sort(allProperties);
|
||||||
|
|
||||||
// Put the list into groups
|
// Put the list into groups
|
||||||
List<PropertyGroup> propertyGroupList = addPropertiesToGroups(propertyList);
|
List<PropertyGroup> propertyGroups = addPropertiesToGroups(allProperties);
|
||||||
|
|
||||||
// Build the template data model from the groupList
|
// Build the template data model from the groupList
|
||||||
groups = new ArrayList<PropertyGroupTemplateModel>(
|
groups = new ArrayList<PropertyGroupTemplateModel>(
|
||||||
propertyGroupList.size());
|
propertyGroups.size());
|
||||||
for (PropertyGroup propertyGroup : propertyGroupList) {
|
for (PropertyGroup propertyGroup : propertyGroups) {
|
||||||
groups.add(new PropertyGroupTemplateModel(vreq, propertyGroup,
|
groups.add(new PropertyGroupTemplateModel(vreq, propertyGroup,
|
||||||
subject, editing, populatedDataPropertyList,
|
subject, editing, populatedDPs,
|
||||||
populatedObjectPropertyList));
|
populatedOPs));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!editing) {
|
if (!editing) {
|
||||||
|
@ -160,14 +171,20 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ObjectProperty> filterAdditions(Collection<ObjectProperty> additions,
|
private List<FauxObjectPropertyWrapper> filterAdditions(List<FauxObjectPropertyWrapper> populatedFauxOPs,
|
||||||
Map<String, List<String>> populatedObjTypes) {
|
Map<String, List<String>> populatedObjTypes) {
|
||||||
List<ObjectProperty> filteredAdditions = new ArrayList<ObjectProperty>();
|
List<FauxObjectPropertyWrapper> filteredAdditions = new ArrayList<FauxObjectPropertyWrapper>();
|
||||||
for (ObjectProperty prop : additions) {
|
for (FauxObjectPropertyWrapper prop : populatedFauxOPs) {
|
||||||
List<String> allowedTypes = populatedObjTypes.get(prop.getURI());
|
List<String> allowedTypes = populatedObjTypes.get(prop.getURI());
|
||||||
if(allowedTypes != null && (allowedTypes.contains(prop.getRangeVClassURI())
|
if (allowedTypes == null) {
|
||||||
|| allowedTypes.contains(prop.getRangeEntityURI()) ) ) {
|
continue;
|
||||||
|
}
|
||||||
|
String rangeVClassURI = prop.getRangeVClassURI();
|
||||||
|
String rangeEntityURI = prop.getRangeEntityURI();
|
||||||
|
if(allowedTypes.contains(rangeVClassURI) ) {
|
||||||
filteredAdditions.add(prop);
|
filteredAdditions.add(prop);
|
||||||
|
} else if (allowedTypes.contains(rangeEntityURI)) {
|
||||||
|
filteredAdditions.add(prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return filteredAdditions;
|
return filteredAdditions;
|
||||||
|
@ -223,9 +240,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Property> mergeAllPossibleObjectProperties(
|
private List<Property> getPossibleOPs(List<ObjectProperty> populatedOPs, List<Property> allProperties, Individual subject) {
|
||||||
List<ObjectProperty> populatedObjectPropertyList,
|
|
||||||
List<Property> propertyList) {
|
|
||||||
|
|
||||||
// There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to
|
// There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to
|
||||||
// DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties
|
// DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties
|
||||||
|
@ -235,27 +250,27 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
// breaks blank node structures in the restrictions that determine applicable properties.
|
// breaks blank node structures in the restrictions that determine applicable properties.
|
||||||
WebappDaoFactory wadf = vreq.getLanguageNeutralWebappDaoFactory();
|
WebappDaoFactory wadf = vreq.getLanguageNeutralWebappDaoFactory();
|
||||||
PropertyInstanceDao piDao = wadf.getPropertyInstanceDao();
|
PropertyInstanceDao piDao = wadf.getPropertyInstanceDao();
|
||||||
|
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
||||||
|
Set<String> vClassUris = subject.getVClasses().stream().map(vclass -> vclass.getURI()).collect(Collectors.toSet());
|
||||||
|
Map<String, Property> possiblePropertiesMap = new HashMap<String,Property>();
|
||||||
|
|
||||||
Collection<PropertyInstance> allPossiblePI = piDao
|
Collection<PropertyInstance> allPossiblePI = piDao.getAllPossiblePropInstForIndividual(subject.getURI());
|
||||||
.getAllPossiblePropInstForIndividual(subject.getURI());
|
|
||||||
if (allPossiblePI != null) {
|
if (allPossiblePI != null) {
|
||||||
for (PropertyInstance possiblePI : allPossiblePI) {
|
for (PropertyInstance possiblePI : allPossiblePI) {
|
||||||
if (possiblePI != null) {
|
if (possiblePI != null) {
|
||||||
// use the language-aware wdf because redundancy check
|
// use the language-aware wdf because redundancy check
|
||||||
// for display will depend on public label match
|
// for display will depend on public label match
|
||||||
ObjectProperty possibleOP = assembleObjectProperty(possiblePI);
|
ObjectProperty possibleOP = opDao.getObjectPropertyByURI(possiblePI.getPropertyURI());
|
||||||
if (possibleOP == null) {
|
if (possibleOP == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boolean addToList = true;
|
if (isInPopulatedOPs(populatedOPs, possibleOP)) {
|
||||||
for(ObjectProperty populatedOP : populatedObjectPropertyList) {
|
continue;
|
||||||
if (redundant(populatedOP, possibleOP)) {
|
|
||||||
addToList = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(addToList) {
|
if (!vClassUris.contains(possibleOP.getDomainVClassURI())) {
|
||||||
propertyList.add(possibleOP);
|
continue;
|
||||||
}
|
}
|
||||||
|
possiblePropertiesMap.put(possibleOP.getURI(), possibleOP);
|
||||||
} else {
|
} else {
|
||||||
log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null");
|
log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null");
|
||||||
}
|
}
|
||||||
|
@ -267,34 +282,23 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
// These properties are outside the ontologies (in vitro and vitro public) but need to be added to the list.
|
// These properties are outside the ontologies (in vitro and vitro public) but need to be added to the list.
|
||||||
// In future, vitro ns props will be phased out. Vitro public properties should be changed so they do not
|
// In future, vitro ns props will be phased out. Vitro public properties should be changed so they do not
|
||||||
// constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()).
|
// constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()).
|
||||||
|
ArrayList<Property> possibleProperties = new ArrayList<>(possiblePropertiesMap.values());
|
||||||
|
|
||||||
for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) {
|
for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) {
|
||||||
if (!alreadyOnPropertyList(propertyList, propertyUri)) {
|
if (!alreadyOnPropertyList(possibleProperties, propertyUri) && !alreadyOnPropertyList(allProperties, propertyUri)) {
|
||||||
addObjectPropertyToPropertyList(propertyUri, null, null, propertyList);
|
addObjectPropertyToPropertyList(propertyUri, null, null, possibleProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return possibleProperties;
|
||||||
return propertyList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectProperty assembleObjectProperty(PropertyInstance pi) {
|
private boolean isInPopulatedOPs(List<ObjectProperty> populatedOPs, ObjectProperty possibleOP) {
|
||||||
WebappDaoFactory rawWadf = ModelAccess.on(vreq).getWebappDaoFactory();
|
for(ObjectProperty populatedOP : populatedOPs) {
|
||||||
ObjectPropertyDao opDao = rawWadf.getObjectPropertyDao();
|
if (redundant(populatedOP, possibleOP)) {
|
||||||
FauxPropertyDao fpDao = rawWadf.getFauxPropertyDao();
|
return true;
|
||||||
|
|
||||||
String base = pi.getPropertyURI();
|
|
||||||
String domain = pi.getDomainClassURI();
|
|
||||||
String range = pi.getRangeClassURI();
|
|
||||||
|
|
||||||
ObjectProperty op = opDao.getObjectPropertyByURIs(base, domain, range);
|
|
||||||
try {
|
|
||||||
FauxProperty fp = fpDao.getFauxPropertyByUris(domain, base, range);
|
|
||||||
if (fp != null) {
|
|
||||||
return new FauxObjectPropertyWrapper(op, fp);
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("Couldn't look up the faux property", e);
|
|
||||||
}
|
}
|
||||||
return op;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -367,19 +371,19 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void mergeAllPossibleDataProperties(List<Property> propertyList) {
|
protected List<Property> getPossibleDPs(List<DataProperty> populatedDPs, List<Property> allProperties) {
|
||||||
// see comments in mergeAllPossibleObjectProperties() for the reason
|
// see comments in mergeAllPossibleObjectProperties() for the reason
|
||||||
// that we need a neutral WebappDaoFactory here.
|
// that we need a neutral WebappDaoFactory here.
|
||||||
DataPropertyDao dpDao = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao();
|
DataPropertyDao dpDao = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao();
|
||||||
Collection<DataProperty> allDatapropColl = dpDao
|
List<Property> possibleProperties = new ArrayList<Property>();
|
||||||
.getAllPossibleDatapropsForIndividual(subject.getURI());
|
Collection<DataProperty> allDatapropColl = dpDao.getAllPossibleDatapropsForIndividual(subject.getURI());
|
||||||
if (allDatapropColl != null) {
|
if (allDatapropColl != null) {
|
||||||
for (DataProperty dp : allDatapropColl) {
|
for (DataProperty dp : allDatapropColl) {
|
||||||
if (dp != null) {
|
if (dp != null) {
|
||||||
if (dp.getURI() == null) {
|
if (dp.getURI() == null) {
|
||||||
log.error("DataProperty dp returned with null propertyURI from dpDao.getAllPossibleDatapropsForIndividual()");
|
log.error("DataProperty dp returned with null propertyURI from dpDao.getAllPossibleDatapropsForIndividual()");
|
||||||
} else if (!alreadyOnPropertyList(propertyList, dp)) {
|
} else if (!alreadyOnPropertyList(allProperties, dp) && !alreadyOnPropertyList(populatedDPs, dp)) {
|
||||||
propertyList.add(dp);
|
possibleProperties.add(dp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("a data property in the Collection created in DataPropertyDao.getAllPossibleDatapropsForIndividual() is unexpectedly null)");
|
log.error("a data property in the Collection created in DataPropertyDao.getAllPossibleDatapropsForIndividual() is unexpectedly null)");
|
||||||
|
@ -388,9 +392,10 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
} else {
|
} else {
|
||||||
log.error("a null Collection is returned from DataPropertyDao.getAllPossibleDatapropsForIndividual())");
|
log.error("a null Collection is returned from DataPropertyDao.getAllPossibleDatapropsForIndividual())");
|
||||||
}
|
}
|
||||||
|
return possibleProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean alreadyOnPropertyList(List<Property> propertyList,
|
private boolean alreadyOnPropertyList(List<? extends Property> propertyList,
|
||||||
Property p) {
|
Property p) {
|
||||||
if (p.getURI() == null) {
|
if (p.getURI() == null) {
|
||||||
log.error("Property p has no propertyURI in alreadyOnPropertyList()");
|
log.error("Property p has no propertyURI in alreadyOnPropertyList()");
|
||||||
|
@ -399,8 +404,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
return (alreadyOnPropertyList(propertyList, p.getURI()));
|
return (alreadyOnPropertyList(propertyList, p.getURI()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean alreadyOnPropertyList(List<Property> propertyList,
|
private boolean alreadyOnPropertyList(List<? extends Property> propertyList, String propertyUri) {
|
||||||
String propertyUri) {
|
|
||||||
for (Property p : propertyList) {
|
for (Property p : propertyList) {
|
||||||
String uri = p.getURI();
|
String uri = p.getURI();
|
||||||
if (uri != null && uri.equals(propertyUri)) {
|
if (uri != null && uri.equals(propertyUri)) {
|
||||||
|
|
|
@ -17,7 +17,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
||||||
|
|
||||||
|
@ -40,26 +39,30 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
||||||
protected String addUrl;
|
protected String addUrl;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private FauxProperty fauxProperty;
|
|
||||||
private int displayLimit;
|
private int displayLimit;
|
||||||
|
|
||||||
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) {
|
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) {
|
||||||
this.vreq = vreq;
|
this.vreq = vreq;
|
||||||
subjectUri = subject.getURI();
|
subjectUri = subject.getURI();
|
||||||
this.property = property;
|
this.property = property;
|
||||||
propertyUri = property.getURI();
|
if (isFauxProperty(property)) {
|
||||||
localName = property.getLocalName();
|
FauxProperty fauxProperty = getFauxProperty(property);
|
||||||
this.name = name;
|
this.name = fauxProperty.getDisplayName();
|
||||||
addUrl = "";
|
this.displayLimit = fauxProperty.getDisplayLimit();
|
||||||
|
propertyUri = fauxProperty.getBaseURI();
|
||||||
fauxProperty = isFauxProperty(property);
|
} else {
|
||||||
if (fauxProperty != null) {
|
propertyUri = property.getURI();
|
||||||
this.name = fauxProperty.getDisplayName();
|
this.name = name;
|
||||||
this.displayLimit = fauxProperty.getDisplayLimit();
|
|
||||||
}
|
}
|
||||||
|
localName = property.getLocalName();
|
||||||
|
addUrl = "";
|
||||||
setVerboseDisplayValues(property);
|
setVerboseDisplayValues(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FauxProperty getFauxProperty(Property property) {
|
||||||
|
return ((FauxPropertyWrapper) property).getFauxProperty();
|
||||||
|
}
|
||||||
|
|
||||||
protected void setVerboseDisplayValues(Property property) {
|
protected void setVerboseDisplayValues(Property property) {
|
||||||
|
|
||||||
// No verbose display for vitro and vitro public properties.
|
// No verbose display for vitro and vitro public properties.
|
||||||
|
@ -104,15 +107,17 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
||||||
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
|
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
|
||||||
verboseDisplay.put("propertyEditUrl", editUrl);
|
verboseDisplay.put("propertyEditUrl", editUrl);
|
||||||
|
|
||||||
if (fauxProperty != null) {
|
if (isFauxProperty(property)) {
|
||||||
verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(fauxProperty));
|
verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(getFauxProperty(property)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FauxProperty isFauxProperty(Property prop) {
|
private boolean isFauxProperty(Property prop) {
|
||||||
FauxPropertyDao fpDao = vreq.getUnfilteredWebappDaoFactory().getFauxPropertyDao();
|
if (prop instanceof FauxPropertyWrapper) {
|
||||||
return fpDao.getFauxPropertyByUris(prop.getDomainVClassURI(), prop.getURI(), prop.getRangeVClassURI());
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> assembleFauxPropertyValues(FauxProperty fp) {
|
private Map<String, Object> assembleFauxPropertyValues(FauxProperty fp) {
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
@ -168,10 +173,6 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
||||||
return (addUrl != null) ? addUrl : "";
|
return (addUrl != null) ? addUrl : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
//check to see whether or not this property represents a faux property
|
|
||||||
public boolean getIsFauxProperty() {
|
|
||||||
return (fauxProperty != null);
|
|
||||||
}
|
|
||||||
public Map<String, Object> getVerboseDisplay() {
|
public Map<String, Object> getVerboseDisplay() {
|
||||||
return verboseDisplay;
|
return verboseDisplay;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.i18n;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import stubs.javax.servlet.ServletContextStub;
|
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale;
|
|
||||||
|
|
||||||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the I18N functionality.
|
|
||||||
*
|
|
||||||
* Start by checking the logic that finds approximate matches for
|
|
||||||
* language-specific property files.
|
|
||||||
*/
|
|
||||||
public class I18nTest extends AbstractTestClass {
|
|
||||||
private static final List<Locale> SELECTABLE_LOCALES = locales("es_MX",
|
|
||||||
"en_US");
|
|
||||||
|
|
||||||
ServletContextStub ctx;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
ctx = new ServletContextStub();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noMatchOnLanguageRegion() {
|
|
||||||
assertLocales("fr_CA", SELECTABLE_LOCALES, "fr_CA", "fr", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noMatchOnLanguage() {
|
|
||||||
assertLocales("fr", SELECTABLE_LOCALES, "fr", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void noMatchOnRoot() {
|
|
||||||
assertLocales("", SELECTABLE_LOCALES, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void matchOnLanguageRegion() {
|
|
||||||
assertLocales("es_ES", SELECTABLE_LOCALES, "es_ES", "es", "es_MX", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void matchOnLanguage() {
|
|
||||||
assertLocales("es", SELECTABLE_LOCALES, "es", "es_MX", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Helper methods
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private void assertLocales(String requested, List<Locale> selectable,
|
|
||||||
String... expected) {
|
|
||||||
SelectedLocale.setSelectableLocales(ctx, selectable);
|
|
||||||
List<Locale> expectedLocales = locales(expected);
|
|
||||||
|
|
||||||
I18n.ThemeBasedControl control = new I18n.ThemeBasedControl(ctx,
|
|
||||||
"bogusThemeDirectory");
|
|
||||||
List<Locale> actualLocales = control.getCandidateLocales(
|
|
||||||
"bogusBaseName", locale(requested));
|
|
||||||
|
|
||||||
assertEquals("Expected locales", expectedLocales, actualLocales);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Locale> locales(String... strings) {
|
|
||||||
List<Locale> locales = new ArrayList<>();
|
|
||||||
for (String s : strings) {
|
|
||||||
locales.add(locale(s));
|
|
||||||
}
|
|
||||||
return locales;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Locale locale(String s) {
|
|
||||||
String[] parts = s.split("_");
|
|
||||||
String language = (parts.length > 0) ? parts[0] : "";
|
|
||||||
String country = (parts.length > 1) ? parts[1] : "";
|
|
||||||
String variant = (parts.length > 2) ? parts[2] : "";
|
|
||||||
return new Locale(language, country, variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
|
||||||
|
import org.apache.jena.graph.NodeFactory;
|
||||||
|
import org.apache.jena.ontology.OntModel;
|
||||||
|
import org.apache.jena.rdf.model.Selector;
|
||||||
|
import org.apache.jena.rdf.model.SimpleSelector;
|
||||||
|
import org.apache.jena.rdf.model.StmtIterator;
|
||||||
|
import org.apache.jena.rdf.model.impl.PropertyImpl;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
|
|
||||||
|
public class TranslationConverterTest {
|
||||||
|
|
||||||
|
private static final String WILMA = "wilma";
|
||||||
|
private static final String HAS_THEME = "http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme";
|
||||||
|
private static final String VITRO = "Vitro";
|
||||||
|
private static final String VIVO = "VIVO";
|
||||||
|
private static final String HAS_APP = "http://vivoweb.org/ontology/core/properties/vocabulary#hasApp";
|
||||||
|
private static final String HAS_KEY = "http://vivoweb.org/ontology/core/properties/vocabulary#hasKey";
|
||||||
|
private static final String ROOT_PATH = "src/test/resources/edu/cornell/mannlib/vitro/webapp/i18n/TranslationConverterTest/root";
|
||||||
|
private static final String INIT_N3_FILE = "src/test/resources/edu/cornell/mannlib/vitro/webapp/i18n/TranslationConverterTest/modelInitContent.n3";
|
||||||
|
ServletContextStub ctx = new ServletContextStub();
|
||||||
|
private OntModel model;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConversion() throws FileNotFoundException {
|
||||||
|
VitroResourceBundle.addAppPrefix("customprefix");
|
||||||
|
VitroResourceBundle.addAppPrefix("vivo");
|
||||||
|
TranslationConverter converter = TranslationConverter.getInstance();
|
||||||
|
model = converter.memModel;
|
||||||
|
File n3 = new File(INIT_N3_FILE);
|
||||||
|
assertTrue(model.isEmpty());
|
||||||
|
model.read(new FileReader(n3), null, "n3");
|
||||||
|
assertFalse(model.isEmpty());
|
||||||
|
File appI18n = new File(ROOT_PATH + TranslationConverter.APP_I18N_PATH);
|
||||||
|
File localI18n = new File(ROOT_PATH + TranslationConverter.LOCAL_I18N_PATH);
|
||||||
|
File themes = new File(ROOT_PATH + TranslationConverter.THEMES_PATH);
|
||||||
|
ctx.setRealPath(TranslationConverter.APP_I18N_PATH, appI18n.getAbsolutePath());
|
||||||
|
ctx.setRealPath(TranslationConverter.LOCAL_I18N_PATH, localI18n.getAbsolutePath());
|
||||||
|
ctx.setRealPath(TranslationConverter.THEMES_PATH, themes.getAbsolutePath());
|
||||||
|
converter.ctx = ctx;
|
||||||
|
converter.convertAll();
|
||||||
|
|
||||||
|
assertEquals(2, getCount(HAS_KEY, "test_key_all_en_US"));
|
||||||
|
assertEquals(2, getCount(HAS_KEY, "test_key_all_en_CA"));
|
||||||
|
|
||||||
|
assertEquals(2, getCount(HAS_KEY, "test_key_all"));
|
||||||
|
|
||||||
|
assertEquals(1, getCount(HAS_KEY, "property_to_overwrite"));
|
||||||
|
|
||||||
|
assertTrue(n3TranslationValueIsOverwrittenByProperty(model));
|
||||||
|
|
||||||
|
assertEquals(3, getCount(HAS_THEME, WILMA));
|
||||||
|
assertEquals(6, getCount(HAS_APP, VITRO));
|
||||||
|
assertEquals(3, getCount(HAS_APP, VIVO));
|
||||||
|
// printResultModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printResultModel() {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
model.write(baos, "N3");
|
||||||
|
System.out.println(baos.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getCount(String hasTheme, String wilma) {
|
||||||
|
Selector selector = new SimpleSelector(null, new PropertyImpl(hasTheme), wilma);
|
||||||
|
StmtIterator it = model.listStatements(selector);
|
||||||
|
int count = 0;
|
||||||
|
while (it.hasNext()) {
|
||||||
|
count++;
|
||||||
|
it.next();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean n3TranslationValueIsOverwrittenByProperty(OntModel model) {
|
||||||
|
return model.getGraph().contains(
|
||||||
|
NodeFactory.createURI("urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663600"),
|
||||||
|
NodeFactory.createURI("http://www.w3.org/2000/01/rdf-schema#label"),
|
||||||
|
NodeFactory.createLiteral("value from properties file","en-US"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.i18n;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.apache.jena.query.Dataset;
|
||||||
|
import org.apache.jena.query.DatasetFactory;
|
||||||
|
import org.apache.jena.rdf.model.Model;
|
||||||
|
import org.apache.jena.rdf.model.ModelFactory;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel;
|
||||||
|
|
||||||
|
public class TranslationProviderTest {
|
||||||
|
|
||||||
|
private static final String VITRO = "Vitro";
|
||||||
|
private static final String VIVO = "VIVO";
|
||||||
|
private static final String ROOT = "src/test/resources/edu/cornell/mannlib/vitro/webapp/i18n/TranslationProviderTest/";
|
||||||
|
private static final String TRANSLATIONS_N3_FILE = ROOT + "modelInitContent.n3";
|
||||||
|
private static final String WILMA = "wilma";
|
||||||
|
private static final String NEMO = "nemo";
|
||||||
|
|
||||||
|
private Model i18nModel;
|
||||||
|
private RDFServiceModel rdfService;
|
||||||
|
private TranslationProvider tp;
|
||||||
|
|
||||||
|
public void init(String i18nFile, String themeName, String appName) throws FileNotFoundException {
|
||||||
|
i18nModel = ModelFactory.createDefaultModel();
|
||||||
|
i18nModel.read(new FileReader(new File(i18nFile)), null, "n3");
|
||||||
|
Dataset ds = DatasetFactory.createTxnMem();
|
||||||
|
ds.addNamedModel("http://vitro.mannlib.cornell.edu/default/interface-i18n", i18nModel);
|
||||||
|
rdfService = new RDFServiceModel(ds);
|
||||||
|
tp = TranslationProvider.getInstance();
|
||||||
|
tp.rdfService = rdfService;
|
||||||
|
tp.setTheme(themeName);
|
||||||
|
tp.application = appName;
|
||||||
|
tp.clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotExistingKey() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "non_existing_key", array);
|
||||||
|
assertEquals("ERROR: Translation not found 'non_existing_key'", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVitroWilmaEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro wilma en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVitroWilmaDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro wilma de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVIVOWilmaEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey VIVO wilma en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVIVOWilmaDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey", array);
|
||||||
|
assertEquals("testkey VIVO wilma de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThemeFallbackVitroNemoEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro no theme en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThemeFallbackVitroNemoDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro no theme de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThemeFallbackVIVONemoEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey VIVO no theme en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThemeFallbackVIVONemoDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey", array);
|
||||||
|
assertEquals("testkey VIVO no theme de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppFallbackVIVONemoEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey_app_fallback", array);
|
||||||
|
assertEquals("testkey_app_fallback Vitro wilma en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppFallbackVIVONemoDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey_app_fallback", array);
|
||||||
|
assertEquals("testkey_app_fallback Vitro wilma de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppAndThemeFallbackVIVONemoEnUS() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey_app_fallback", array);
|
||||||
|
assertEquals("testkey_app_fallback Vitro no theme en-US", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppAndThemeFallbackVIVONemoDeDE() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, NEMO, VIVO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("de-DE"), "testkey_app_fallback", array);
|
||||||
|
assertEquals("testkey_app_fallback Vitro no theme de-DE", translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCache() throws FileNotFoundException {
|
||||||
|
init(TRANSLATIONS_N3_FILE, WILMA, VITRO);
|
||||||
|
Object array[] = {};
|
||||||
|
String translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro wilma en-US", translation);
|
||||||
|
tp.application = VIVO;
|
||||||
|
translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey Vitro wilma en-US", translation);
|
||||||
|
tp.clearCache();
|
||||||
|
translation = tp.getTranslation(Collections.singletonList("en-US"), "testkey", array);
|
||||||
|
assertEquals("testkey VIVO wilma en-US", translation);
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,14 +51,11 @@ public class I18nStub extends I18n {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected I18nBundle getBundle(String bundleName, HttpServletRequest req) {
|
protected I18nBundle getBundle( HttpServletRequest req) {
|
||||||
return new I18nBundleStub(bundleName);
|
return new I18nBundleStub();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class I18nBundleStub extends I18nBundle {
|
private class I18nBundleStub implements I18nBundle {
|
||||||
public I18nBundleStub(String bundleName) {
|
|
||||||
super(bundleName, new DummyResourceBundle(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String text(String key, Object... parameters) {
|
public String text(String key, Object... parameters) {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||||
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663600>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "value from n3 file"@en-US ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"VIVO" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"property_to_overwrite" .
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all = test value all
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all_en_CA = test value all_en_CA
|
|
@ -0,0 +1 @@
|
||||||
|
test_key = test value vitro_all
|
|
@ -0,0 +1,2 @@
|
||||||
|
test_key = test value vivo_all_en_US
|
||||||
|
property_to_overwrite = value from properties file
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all_en_US = test value customprefix_all_en_US
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all = test value all wilma
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all_en_CA = test value all_en_CA wilma
|
|
@ -0,0 +1 @@
|
||||||
|
test_key_all_en_US = test value vivo_all_en_US wilma
|
|
@ -0,0 +1,77 @@
|
||||||
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||||
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663600>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey VIVO no theme en-US"@en-US ;
|
||||||
|
rdfs:label "testkey VIVO no theme de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"VIVO" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663601>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey Vitro no theme en-US"@en-US ;
|
||||||
|
rdfs:label "testkey Vitro no theme de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"Vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663602>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey VIVO wilma en-US"@en-US ;
|
||||||
|
rdfs:label "testkey VIVO wilma de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"VIVO" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme>
|
||||||
|
"wilma" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663603>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey Vitro wilma en-US"@en-US ;
|
||||||
|
rdfs:label "testkey Vitro wilma de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"Vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme>
|
||||||
|
"wilma" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663604>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey Vitro vitro en-US"@en-US ;
|
||||||
|
rdfs:label "testkey Vitro vitro de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"Vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme>
|
||||||
|
"vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663605>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey_app_fallback Vitro wilma en-US"@en-US ;
|
||||||
|
rdfs:label "testkey_app_fallback Vitro wilma de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"Vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasTheme>
|
||||||
|
"wilma" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey_app_fallback" .
|
||||||
|
|
||||||
|
<urn:uuid:8c80dbf5-adda-41d5-a6fe-d5efde663606>
|
||||||
|
a owl:NamedIndividual , <http://vivoweb.org/ontology/core/properties/vocabulary#PropertyKey> ;
|
||||||
|
rdfs:label "testkey_app_fallback Vitro no theme en-US"@en-US ;
|
||||||
|
rdfs:label "testkey_app_fallback Vitro no theme de-DE"@de-DE ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasApp>
|
||||||
|
"Vitro" ;
|
||||||
|
<http://vivoweb.org/ontology/core/properties/vocabulary#hasKey>
|
||||||
|
"testkey_app_fallback" .
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,8 @@ proxy.eligibleTypeList = http://www.w3.org/2002/07/owl#Thing
|
||||||
#
|
#
|
||||||
# A list of supported languages or Locales that the user may choose to
|
# A list of supported languages or Locales that the user may choose to
|
||||||
# use instead of the one specified by the browser. The selected language(s)
|
# use instead of the one specified by the browser. The selected language(s)
|
||||||
# must exist in the Vitro-languages repository. This affects RDF data
|
# must exist in the list of property files in webapps or in the list of ttl
|
||||||
|
# files in interface-i18n directories within Vitro home. This affects RDF data
|
||||||
# retrieved from the model, if RDFService.languageFilter is true.
|
# retrieved from the model, if RDFService.languageFilter is true.
|
||||||
# This also affects the text of pages that have been modified to support
|
# This also affects the text of pages that have been modified to support
|
||||||
# multiple languages.
|
# multiple languages.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Die Nutzungsbedingungen sollten hier stehen</p>
|
||||||
|
"""@de-DE ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@de-DE ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Terms of use should be here</p>
|
||||||
|
"""@en-CA ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@en-CA ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Terms of use should be here</p>
|
||||||
|
"""@en-US ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@en-US ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,4 @@
|
||||||
|
@prefix vitro-public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
vitro-public:storedFile rdfs:label "stored file"@en-US .
|
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Las condiciones de uso deberían estar aquí</p>
|
||||||
|
"""@es ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@es ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Les conditions d'utilisation devraient être ici</p>
|
||||||
|
"""@fr-CA ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@fr-CA ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Os termos de uso devem estar aqui</p>
|
||||||
|
"""@pt-BR ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@pt-BR ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Условия использования должны находиться здесь</p>
|
||||||
|
"""@ru-RU ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@ru-RU ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
||||||
|
# $This file is distributed under the terms of the license in LICENSE$
|
||||||
|
|
||||||
|
@prefix default: <http://vitro.mannlib.cornell.edu/ns/default/pages#> .
|
||||||
|
|
||||||
|
default:terms_of_use_dg
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#htmlValue>
|
||||||
|
"""
|
||||||
|
<p>Uslovi korišćenja bi trebalo da budu ovde</p>
|
||||||
|
"""@sr-Latn-RS ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#saveToVar>
|
||||||
|
"termsOfUse" .
|
||||||
|
default:terms_of_use
|
||||||
|
a <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#Page> ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#hasDataGetter>
|
||||||
|
default:terms_of_use_dg ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#title>
|
||||||
|
"Terms of use"@sr-Latn-RS ;
|
||||||
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#urlMapping>
|
||||||
|
"/termsOfUse" .
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,39 @@
|
||||||
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
||||||
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||||
|
@prefix prop-data: <http://vivoweb.org/ontology/core/properties/individual#> .
|
||||||
|
@prefix prop: <http://vivoweb.org/ontology/core/properties/vocabulary#> .
|
||||||
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
|
||||||
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
|
||||||
|
prop:hasPackage rdf:type owl:DatatypeProperty ;
|
||||||
|
rdfs:domain prop:PropertyKey ;
|
||||||
|
rdfs:label "has package" ;
|
||||||
|
rdfs:range xsd:string .
|
||||||
|
|
||||||
|
prop:hasKey rdf:type owl:DatatypeProperty ;
|
||||||
|
rdfs:comment "Value of the key" ;
|
||||||
|
rdfs:domain prop:PropertyKey ;
|
||||||
|
rdfs:label "Propertie file url " ;
|
||||||
|
rdfs:range xsd:string .
|
||||||
|
|
||||||
|
prop:hasTheme rdf:type owl:DatatypeProperty ;
|
||||||
|
rdfs:domain prop:PropertyKey ;
|
||||||
|
rdfs:label "has theme" ;
|
||||||
|
rdfs:range xsd:string .
|
||||||
|
|
||||||
|
prop:PropertyKey rdf:type owl:Class ;
|
||||||
|
rdfs:label skos:Concept ;
|
||||||
|
rdfs:subClassOf owl:Thing ;
|
||||||
|
rdfs:subClassOf skos:Concept .
|
||||||
|
|
||||||
|
prop:ftlUrl rdf:type owl:DatatypeProperty ;
|
||||||
|
rdfs:comment "Points to the FTL file containing the key" ;
|
||||||
|
rdfs:domain prop:PropertyKey ;
|
||||||
|
rdfs:label "ftl file url" ;
|
||||||
|
rdfs:range xsd:anyURI .
|
||||||
|
|
||||||
|
prop:hasApp rdf:type owl:DatatypeProperty ;
|
||||||
|
rdfs:domain prop:PropertyKey ;
|
||||||
|
rdfs:label "has application" ;
|
||||||
|
rdfs:range xsd:string .
|
|
@ -107,11 +107,5 @@
|
||||||
<artifactId>vitro-home</artifactId>
|
<artifactId>vitro-home</artifactId>
|
||||||
<type>tar.gz</type>
|
<type>tar.gz</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.vivoweb</groupId>
|
|
||||||
<artifactId>vitro-languages-home-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>tar.gz</type>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -44,12 +44,6 @@
|
||||||
<artifactId>vitro-webapp</artifactId>
|
<artifactId>vitro-webapp</artifactId>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</overlay>
|
</overlay>
|
||||||
<!-- Overlays for multilingual support -->
|
|
||||||
<overlay>
|
|
||||||
<groupId>org.vivoweb</groupId>
|
|
||||||
<artifactId>vitro-languages-webapp-core</artifactId>
|
|
||||||
<type>war</type>
|
|
||||||
</overlay>
|
|
||||||
</overlays>
|
</overlays>
|
||||||
<webResources>
|
<webResources>
|
||||||
<resource>
|
<resource>
|
||||||
|
@ -147,14 +141,6 @@
|
||||||
<artifactId>vitro-webapp</artifactId>
|
<artifactId>vitro-webapp</artifactId>
|
||||||
<type>war</type>
|
<type>war</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Dependency for multilingual support -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.vivoweb</groupId>
|
|
||||||
<artifactId>vitro-languages-webapp-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<type>war</type>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
|
|
|
@ -21,6 +21,7 @@ edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.ConfigurationModelsSetup
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ConfigurationModelsSetup
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewServiceSetup
|
||||||
edu.ucsf.vitro.opensocial.OpenSocialSmokeTests
|
edu.ucsf.vitro.opensocial.OpenSocialSmokeTests
|
||||||
|
|
||||||
# For multiple language support
|
# For multiple language support
|
||||||
edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup
|
edu.cornell.mannlib.vitro.webapp.i18n.I18nContextListener
|
||||||
|
|
||||||
# The search indexer uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
# The search indexer uses a "public" permission, so the PropertyRestrictionPolicyHelper
|
||||||
# and the PermissionRegistry must already be set up.
|
# and the PermissionRegistry must already be set up.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/de_DE/interface-i18n/firsttime/vitro_UiLabel_de_DE.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/de_DE/display/interface-i18n/vitro_UiLabel_de_DE.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/en_CA/interface-i18n/firsttime/vitro_UiLabel_en_CA.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/en_CA/display/interface-i18n/vitro_UiLabel_en_CA.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/en_US/interface-i18n/firsttime/vitro_UiLabel_en_US.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/en_US/display/interface-i18n/vitro_UiLabel_en_US.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
8
webapp/src/main/webapp/i18n/README_vitro_UiLabel_es.txt
Normal file
8
webapp/src/main/webapp/i18n/README_vitro_UiLabel_es.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/es/interface-i18n/firsttime/vitro_UiLabel_es.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/es/display/interface-i18n/vitro_UiLabel_es.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/fr_CA/interface-i18n/firsttime/vitro_UiLabel_fr_CA.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/fr_CA/display/interface-i18n/vitro_UiLabel_fr_CA.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/pt_BR/interface-i18n/firsttime/vitro_UiLabel_pt_BR.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/pt_BR/display/interface-i18n/vitro_UiLabel_pt_BR.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/ru_RU/interface-i18n/firsttime/vitro_UiLabel_ru_RU.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/ru_RU/display/interface-i18n/vitro_UiLabel_ru_RU.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
Please note that although usage of property files for translation of UI labels is supported at the moment,
|
||||||
|
it is deprecated and not recommended. Please, consider using ontology instead of property file located at:
|
||||||
|
Source code: [VIVO project]Vitro/home/src/main/resources/rdf/i18n/sr_Latn_RS/interface-i18n/firsttime/vitro_UiLabel_sr_Latn_RS.ttl
|
||||||
|
Deployment: [VIVO home]/rdf/i18n/sr_Latn_RS/display/interface-i18n/vitro_UiLabel_sr_Latn_RS.ttl
|
||||||
|
|
||||||
|
However, if you decide to use property files, please create and post the file in the same
|
||||||
|
directory as this Readme file.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue