From 4c292626f41066caf3201f35846b543bb75f5275 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:20:11 +0000
Subject: [PATCH 01/13] ADD Language support interfaces
---
.../registry/language/Language.java | 29 +++++++++++++++++++
.../registry/language/LanguageConfig.java | 7 +++++
.../registry/language/LanguageManager.java | 25 ++++++++++++++++
3 files changed, 61 insertions(+)
create mode 100644 src/main/java/com/epimorphics/registry/language/Language.java
create mode 100644 src/main/java/com/epimorphics/registry/language/LanguageConfig.java
create mode 100644 src/main/java/com/epimorphics/registry/language/LanguageManager.java
diff --git a/src/main/java/com/epimorphics/registry/language/Language.java b/src/main/java/com/epimorphics/registry/language/Language.java
new file mode 100644
index 00000000..4e6b4055
--- /dev/null
+++ b/src/main/java/com/epimorphics/registry/language/Language.java
@@ -0,0 +1,29 @@
+package com.epimorphics.registry.language;
+
+/**
+ * Representation of a supported language.
+ */
+interface Language {
+ /**
+ * @return The ISO 639-1 language code.
+ */
+ String getCode();
+
+ /**
+ * @return The user friendly label, in the corresponding language (if available).
+ */
+ String getLabel();
+
+ class Base implements Language {
+ private final String code;
+ private final String label;
+
+ Base(String code, String label) {
+ this.code = code;
+ this.label = label;
+ }
+
+ @Override public String getCode() { return code; }
+ @Override public String getLabel() { return label; }
+ }
+}
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageConfig.java b/src/main/java/com/epimorphics/registry/language/LanguageConfig.java
new file mode 100644
index 00000000..b63a1966
--- /dev/null
+++ b/src/main/java/com/epimorphics/registry/language/LanguageConfig.java
@@ -0,0 +1,7 @@
+package com.epimorphics.registry.language;
+
+import java.util.List;
+
+interface LanguageConfig {
+ List getLanguages();
+}
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManager.java b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
new file mode 100644
index 00000000..dd589b81
--- /dev/null
+++ b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
@@ -0,0 +1,25 @@
+package com.epimorphics.registry.language;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Multilingual registry support.
+ */
+public interface LanguageManager {
+ /**
+ * Determine whether the registry is configured to support multiple languages.
+ * @return True if and only if multiple languages are supported.
+ */
+ Boolean isMultilingual();
+
+ /**
+ * @return All of the supported languages.
+ */
+ List getLanguages();
+
+ class Default implements LanguageManager {
+ @Override public Boolean isMultilingual() { return false; }
+ @Override public List getLanguages() { return Collections.emptyList(); }
+ }
+}
\ No newline at end of file
From bc89129cb90ae0db6f690d46aeab9566b4f89c7e Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:20:43 +0000
Subject: [PATCH 02/13] ADD Language type and property definitions to vocab
---
.../registry/vocab/RegistryVocab.java | 4 ++++
src/main/vocabs/registryVocab.ttl | 16 ++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/src/main/java/com/epimorphics/registry/vocab/RegistryVocab.java b/src/main/java/com/epimorphics/registry/vocab/RegistryVocab.java
index 0f7b7218..632350dd 100644
--- a/src/main/java/com/epimorphics/registry/vocab/RegistryVocab.java
+++ b/src/main/java/com/epimorphics/registry/vocab/RegistryVocab.java
@@ -86,6 +86,8 @@ public class RegistryVocab {
* of type is available.
*/
public static final ObjectProperty itemClass = m_model.createObjectProperty( "http://purl.org/linked-data/registry#itemClass" );
+
+ public static final ObjectProperty languageCode = m_model.createObjectProperty("http://dbpedia.org/ontology/languageCode");
/** The manager of the register, may be a person (foaf:Person) or an organization
* (org:Organization). Operates the register on behalf of the owner, makes day
@@ -199,6 +201,8 @@ public class RegistryVocab {
* which traverse the register hierarchy such as entity search will also be forwarded
*/
public static final OntClass FederatedRegister = m_model.createClass( "http://purl.org/linked-data/registry#FederatedRegister" );
+
+ public static final OntClass Language = m_model.createClass("http://dbpedia.org/ontology/Language");
/** A registerable entity which simply forwards all requests to the delegation
* target.
diff --git a/src/main/vocabs/registryVocab.ttl b/src/main/vocabs/registryVocab.ttl
index 3821d641..db1bdc17 100644
--- a/src/main/vocabs/registryVocab.ttl
+++ b/src/main/vocabs/registryVocab.ttl
@@ -4,6 +4,7 @@
@prefix rdfs: .
@prefix owl: .
@prefix xsd: .
+@prefix dbo: .
@prefix dct: .
@prefix dc: .
@prefix foaf: .
@@ -501,3 +502,18 @@ reg:sourceDataset a owl:ObjectProperty;
rdfs:domain void:Linkset;
rdfs:range void:Dataset;
.
+
+# -- Internationalisation --------------------------------------------------
+
+dbo:Language a owl:Class;
+ rdfs:label "Language";
+ rdfs:comment "A language that is supported by a multilingual registry.";
+ .
+
+dbo:languageCode a owl:DatatypeProperty;
+ rdfs:label "Language code";
+ rdfs:comment "The two-character ISO 639-1 language code.";
+ rdfs:domain dbo:Language;
+ rdfs:range xsd:string;
+ .
+
From 0af9c1288af0b8fd6d96e260e7601ebbddfea51f Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:21:03 +0000
Subject: [PATCH 03/13] ADD Language manager and system register config
---
.../language/LanguageManagerImpl.java | 19 ++++
.../registry/language/LanguageRegister.java | 97 +++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java
create mode 100644 src/main/java/com/epimorphics/registry/language/LanguageRegister.java
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java b/src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java
new file mode 100644
index 00000000..3b573429
--- /dev/null
+++ b/src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java
@@ -0,0 +1,19 @@
+package com.epimorphics.registry.language;
+
+import java.util.List;
+
+public class LanguageManagerImpl implements LanguageManager {
+ private LanguageConfig config;
+
+ public void setConfig(LanguageConfig config) {
+ this.config = config;
+ }
+
+ public Boolean isMultilingual() {
+ return getLanguages().size() > 1;
+ }
+
+ public List getLanguages() {
+ return config.getLanguages();
+ }
+}
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageRegister.java b/src/main/java/com/epimorphics/registry/language/LanguageRegister.java
new file mode 100644
index 00000000..e9cb21f1
--- /dev/null
+++ b/src/main/java/com/epimorphics/registry/language/LanguageRegister.java
@@ -0,0 +1,97 @@
+package com.epimorphics.registry.language;
+
+import com.epimorphics.appbase.core.App;
+import com.epimorphics.appbase.core.Startup;
+import com.epimorphics.registry.core.Description;
+import com.epimorphics.registry.core.Register;
+import com.epimorphics.registry.core.Registry;
+import com.epimorphics.registry.message.MessagingService;
+import com.epimorphics.registry.message.ProcessIfChanges;
+import com.epimorphics.registry.store.RegisterEntryInfo;
+import com.epimorphics.registry.store.StoreAPI;
+import com.epimorphics.registry.vocab.RegistryVocab;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.RDFS;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LanguageRegister implements LanguageConfig, Startup {
+ private static final String REGISTER = "/system/language";
+
+ private Logger log = LoggerFactory.getLogger(LanguageRegister.class);
+ private List languages = new ArrayList<>();
+
+ @Override public void startup(App app) {
+ Registry reg = app.getA(Registry.class);
+ initLanguages(reg);
+
+ String register = reg.getBaseURI() + REGISTER;
+ MessagingService msgSvc = reg.getMessagingService();
+ MessagingService.Process onMonitorChange = new ProcessIfChanges(msg -> initLanguages(reg), register);
+
+ msgSvc.processMessages(onMonitorChange);
+ }
+
+ public synchronized void initLanguages(Registry reg) {
+ List nextLanguages = new ArrayList<>();
+
+ String uri = reg.getBaseURI() + REGISTER;
+ StoreAPI store = reg.getStore();
+ store.beginSafeRead();
+
+ try {
+ Description desc = store.getDescription(uri);
+ if (desc instanceof Register) {
+ Register register = desc.asRegister();
+ List members = register.getMembers();
+ members.forEach(entry -> addLanguage(entry, store, nextLanguages));
+ this.languages = nextLanguages;
+ } else {
+ log.warn("System register " + uri + " does not exist - unable to configure languages.");
+ }
+ } finally {
+ store.endSafeRead();
+ }
+ }
+
+ private void addLanguage(RegisterEntryInfo entry, StoreAPI store, List languages) {
+ Resource root = store.getDescription(entry.getEntityURI()).getRoot();
+ if (root.hasProperty(RDF.type, RegistryVocab.Language)) {
+ Statement langStmt = root.getProperty(RegistryVocab.languageCode);
+ if (langStmt != null) {
+ String lang = langStmt.getObject().asLiteral().getLexicalForm();
+ String label = getLabel(root, lang);
+ languages.add(new Language.Base(lang, label));
+ log.info("Registered language: " + label + " (" + lang + ")");
+ } else {
+ log.warn("Unable to add language entry " + entry.getItemURI() + ": Resource must specify a dbo:languageCode value.");
+ }
+ } else {
+ log.warn("Unable to add language entry " + entry.getItemURI() + ": Resource must have a rdf:type value of dbo:Language.");
+ }
+
+ }
+
+ private String getLabel(Resource root, String lang) {
+ Statement nativeLabel = root.getProperty(RDFS.label, lang);
+ if (nativeLabel != null) {
+ return nativeLabel.getObject().asLiteral().getLexicalForm();
+ }
+
+ Statement anyLabel = root.getProperty(RDFS.label);
+ if (anyLabel != null) {
+ return anyLabel.getObject().asLiteral().getLexicalForm();
+ }
+
+ return lang;
+ }
+
+ public List getLanguages() {
+ return languages;
+ }
+}
From b1a430bea877f6fbd00ba7c06906e32416768519 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:22:17 +0000
Subject: [PATCH 04/13] ADD Language manager to registry
---
.../com/epimorphics/registry/core/Registry.java | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/main/java/com/epimorphics/registry/core/Registry.java b/src/main/java/com/epimorphics/registry/core/Registry.java
index a59ffee1..cd1f54e9 100644
--- a/src/main/java/com/epimorphics/registry/core/Registry.java
+++ b/src/main/java/com/epimorphics/registry/core/Registry.java
@@ -36,6 +36,7 @@
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
+import com.epimorphics.registry.language.LanguageManager;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.util.FileUtils;
@@ -125,6 +126,7 @@ public class Registry extends ComponentBase implements Startup, Shutdown {
protected GenericConfig configExtensions;
protected RequestLogger requestLogger;
protected boolean cacheRegisters = false;
+ protected LanguageManager languageManager = new LanguageManager.Default();
public void setBaseUri(String uri) {
baseURI = uri;
@@ -224,6 +226,14 @@ public void setCacheRegisters(boolean cacheRegisters) {
this.cacheRegisters = cacheRegisters;
}
+ public void setLanguageManager(LanguageManager languageManager) {
+ this.languageManager = languageManager;
+ }
+
+ public LanguageManager getLanguageManager() {
+ return languageManager;
+ }
+
@Override
public void startup(App app) {
super.startup(app);
@@ -291,6 +301,11 @@ public void processMessage(Message message) {
} else {
log.warn("No backup service configured");
}
+
+ LanguageManager languageManager = app.getA(LanguageManager.class);
+ if (languageManager != null) {
+ setLanguageManager(languageManager);
+ }
}
/**
From 4a00a74a4d3385b867a5dc0ba6ca68330f8ceeca Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:22:44 +0000
Subject: [PATCH 05/13] Upgrade lib version (fixing language choice bug)
---
pom.xml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/pom.xml b/pom.xml
index 0b7ec6d8..e38fee57 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,7 @@
3.9.0
3.9.0
7.0.94
+ 3.1.1-SNAPSHOT
@@ -108,6 +109,12 @@
${appbase.version}
+
+
+ com.epimorphics
+ lib
+ ${lib.version}
+
org.apache.jena
From 79b9e56733aec87d90e644d5dccfef5ce4b1f21e Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Thu, 20 Feb 2020 17:31:20 +0000
Subject: [PATCH 06/13] Refactor request processor to use language query
parameter
---
.../registry/webapi/RequestProcessor.java | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java b/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
index 0550a6da..be565e45 100644
--- a/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
+++ b/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
@@ -166,11 +166,21 @@ private Response readAsRDF(PassThroughResult ptr, String mime, String ext) {
return builder.build();
}
- public static Response render(String template, UriInfo uriInfo, ServletContext context, HttpServletRequest request, Object...params) {
- String language = request.getLocale().getLanguage();
- if (language.isEmpty()) {
- language = "en";
+ private static String getRequestLanguage(HttpServletRequest request) {
+ String param = request.getParameter("lang");
+ if (param != null && !param.isEmpty()) {
+ return param;
+ }
+ String header = request.getLocale().getLanguage();
+ if (header != null && !header.isEmpty()) {
+ return header;
}
+
+ return "en";
+ }
+
+ public static Response render(String template, UriInfo uriInfo, ServletContext context, HttpServletRequest request, Object...params) {
+ String language = getRequestLanguage(request);
Object[] fullParams = new Object[params.length + 10];
int i = 0;
while (i < params.length) {
From 76bb511da7f817bce6356bce5245597ab986dbe9 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Mon, 2 Mar 2020 17:21:38 +0000
Subject: [PATCH 07/13] Rename multilingual language component Add cookie
config
---
.../registry/language/LanguageManager.java | 6 ++++++
...uageManagerImpl.java => MultiLanguageManager.java} | 11 ++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
rename src/main/java/com/epimorphics/registry/language/{LanguageManagerImpl.java => MultiLanguageManager.java} (57%)
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManager.java b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
index dd589b81..19e51425 100644
--- a/src/main/java/com/epimorphics/registry/language/LanguageManager.java
+++ b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
@@ -18,8 +18,14 @@ public interface LanguageManager {
*/
List getLanguages();
+ /**
+ * TODO
+ */
+ Boolean getUseCookies();
+
class Default implements LanguageManager {
@Override public Boolean isMultilingual() { return false; }
@Override public List getLanguages() { return Collections.emptyList(); }
+ @Override public Boolean getUseCookies() { return null; }
}
}
\ No newline at end of file
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java b/src/main/java/com/epimorphics/registry/language/MultiLanguageManager.java
similarity index 57%
rename from src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java
rename to src/main/java/com/epimorphics/registry/language/MultiLanguageManager.java
index 3b573429..4c7a0f38 100644
--- a/src/main/java/com/epimorphics/registry/language/LanguageManagerImpl.java
+++ b/src/main/java/com/epimorphics/registry/language/MultiLanguageManager.java
@@ -2,9 +2,14 @@
import java.util.List;
-public class LanguageManagerImpl implements LanguageManager {
+public class MultiLanguageManager implements LanguageManager {
+ private Boolean useCookies = false;
private LanguageConfig config;
+ public void setUseCookies(Boolean useCookies) {
+ this.useCookies = useCookies;
+ }
+
public void setConfig(LanguageConfig config) {
this.config = config;
}
@@ -16,4 +21,8 @@ public Boolean isMultilingual() {
public List getLanguages() {
return config.getLanguages();
}
+
+ public Boolean getUseCookies() {
+ return useCookies;
+ }
}
From 065e1561bd70c776e0111248575b1c35a4c64da9 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Mon, 2 Mar 2020 17:22:33 +0000
Subject: [PATCH 08/13] ADD Cookies to language negotiation
---
.../registry/webapi/RequestProcessor.java | 119 ++++++++++--------
1 file changed, 69 insertions(+), 50 deletions(-)
diff --git a/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java b/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
index be565e45..9c30c15b 100644
--- a/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
+++ b/src/main/java/com/epimorphics/registry/webapi/RequestProcessor.java
@@ -23,34 +23,27 @@
package com.epimorphics.registry.webapi;
-import static com.epimorphics.webapi.marshalling.RDFXMLMarshaller.FULL_MIME_RDFXML;
-import static com.epimorphics.webapi.marshalling.RDFXMLMarshaller.MIME_RDFXML;
-
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.StreamingOutput;
-import javax.ws.rs.core.UriInfo;
-
+import com.epimorphics.appbase.core.AppConfig;
+import com.epimorphics.appbase.templates.VelocityRender;
+import com.epimorphics.appbase.webapi.BaseEndpoint;
+import com.epimorphics.appbase.webapi.WebApiException;
+import com.epimorphics.registry.commands.CommandUpdate;
+import com.epimorphics.registry.core.*;
+import com.epimorphics.registry.core.Command.Operation;
+import com.epimorphics.registry.core.ForwardingRecord.Type;
+import com.epimorphics.registry.csv.CSVPayloadRead;
+import com.epimorphics.registry.csv.RDFCSVUtil;
+import com.epimorphics.registry.language.LanguageManager;
+import com.epimorphics.registry.security.UserInfo;
+import com.epimorphics.registry.util.JSONLDSupport;
+import com.epimorphics.registry.util.PATCH;
+import com.epimorphics.registry.util.UiForm;
import com.epimorphics.registry.vocab.RegistryVocab;
-import org.apache.jena.rdf.model.*;
+import com.epimorphics.util.NameUtils;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
import org.apache.jena.util.FileManager;
import org.apache.jena.util.FileUtils;
import org.apache.jena.vocabulary.RDF;
@@ -62,29 +55,27 @@
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.FormDataParam;
-import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.epimorphics.appbase.core.AppConfig;
-import com.epimorphics.appbase.templates.VelocityRender;
-import com.epimorphics.appbase.webapi.BaseEndpoint;
-import com.epimorphics.appbase.webapi.WebApiException;
-import com.epimorphics.registry.commands.CommandUpdate;
-import com.epimorphics.registry.core.Command;
-import com.epimorphics.registry.core.Command.Operation;
-import com.epimorphics.registry.core.ForwardingRecord;
-import com.epimorphics.registry.core.ForwardingRecord.Type;
-import com.epimorphics.registry.core.ForwardingService;
-import com.epimorphics.registry.core.MatchResult;
-import com.epimorphics.registry.core.Registry;
-import com.epimorphics.registry.csv.CSVPayloadRead;
-import com.epimorphics.registry.csv.RDFCSVUtil;
-import com.epimorphics.registry.security.UserInfo;
-import com.epimorphics.registry.util.JSONLDSupport;
-import com.epimorphics.registry.util.PATCH;
-import com.epimorphics.registry.util.UiForm;
-import com.epimorphics.util.NameUtils;
+import javax.servlet.ServletContext;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.Response.Status;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.epimorphics.webapi.marshalling.RDFXMLMarshaller.FULL_MIME_RDFXML;
+import static com.epimorphics.webapi.marshalling.RDFXMLMarshaller.MIME_RDFXML;
+import static javax.ws.rs.core.Cookie.DEFAULT_VERSION;
+import static javax.ws.rs.core.NewCookie.DEFAULT_MAX_AGE;
/**
* Filter all requests as possible register API requests.
@@ -101,6 +92,7 @@ public class RequestProcessor extends BaseEndpoint {
public static final String VARY_HEADER = "Vary";
public static final String UI_PATH = "ui";
private static final String SYSTEM_QUERY = "system/query";
+ private static final String LANGUAGE_COOKIE = "registry-pref-lang";
@GET
@Produces("text/html")
@@ -166,11 +158,22 @@ private Response readAsRDF(PassThroughResult ptr, String mime, String ext) {
return builder.build();
}
- private static String getRequestLanguage(HttpServletRequest request) {
+ private static String getRequestLanguage(LanguageManager languageManager, HttpServletRequest request) {
String param = request.getParameter("lang");
if (param != null && !param.isEmpty()) {
return param;
}
+
+ if (languageManager.getUseCookies()) {
+ Cookie cookie = Arrays.stream(request.getCookies())
+ .filter(c -> c.getName().equals(LANGUAGE_COOKIE))
+ .findFirst()
+ .orElse(null);
+ if (cookie != null) {
+ return cookie.getValue();
+ }
+ }
+
String header = request.getLocale().getLanguage();
if (header != null && !header.isEmpty()) {
return header;
@@ -179,8 +182,21 @@ private static String getRequestLanguage(HttpServletRequest request) {
return "en";
}
+ private static void setLanguageCookie(LanguageManager languageManager, ResponseBuilder response, HttpServletRequest request) {
+ if (languageManager.getUseCookies()) {
+ String param = request.getParameter("lang");
+ if (param != null && !param.isEmpty()) {
+ NewCookie cookie = new NewCookie(LANGUAGE_COOKIE, param, "/", null, DEFAULT_VERSION, null, DEFAULT_MAX_AGE, null, false, false);
+ response.cookie(cookie);
+ }
+ }
+ }
+
public static Response render(String template, UriInfo uriInfo, ServletContext context, HttpServletRequest request, Object...params) {
- String language = getRequestLanguage(request);
+ Registry reg = Registry.get();
+ LanguageManager languageManager = reg.getLanguageManager();
+
+ String language = getRequestLanguage(languageManager, request);
Object[] fullParams = new Object[params.length + 10];
int i = 0;
while (i < params.length) {
@@ -188,7 +204,7 @@ public static Response render(String template, UriInfo uriInfo, ServletContext c
i++;
}
fullParams[i++] = "registry";
- fullParams[i++] = Registry.get();
+ fullParams[i++] = reg;
fullParams[i++] = "subject";
fullParams[i++] = SecurityUtils.getSubject();
fullParams[i++] = "requestor";
@@ -205,6 +221,9 @@ public static Response render(String template, UriInfo uriInfo, ServletContext c
if (SecurityUtils.getSubject().isAuthenticated()) {
builder.header("Cache-control", "no-cache");
}
+
+ setLanguageCookie(languageManager, builder, request);
+
return builder.entity(out).build();
}
From 330afd33622817a07d28fd1759b1893414e7c675 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Tue, 3 Mar 2020 12:30:20 +0000
Subject: [PATCH 09/13] ADD Doc comments
---
.../com/epimorphics/registry/language/LanguageConfig.java | 6 ++++++
.../com/epimorphics/registry/language/LanguageManager.java | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageConfig.java b/src/main/java/com/epimorphics/registry/language/LanguageConfig.java
index b63a1966..0a8b52aa 100644
--- a/src/main/java/com/epimorphics/registry/language/LanguageConfig.java
+++ b/src/main/java/com/epimorphics/registry/language/LanguageConfig.java
@@ -2,6 +2,12 @@
import java.util.List;
+/**
+ * Maintains the state of the registry's supported languages.
+ */
interface LanguageConfig {
+ /**
+ * @return The list of languages supported by the registry.
+ */
List getLanguages();
}
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManager.java b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
index 19e51425..82d7ccd8 100644
--- a/src/main/java/com/epimorphics/registry/language/LanguageManager.java
+++ b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
@@ -19,7 +19,8 @@ public interface LanguageManager {
List getLanguages();
/**
- * TODO
+ * Determines whether to use cookies to store users' language preference.
+ * @return True if and only if cookies should be used. Otherwise, false.
*/
Boolean getUseCookies();
From e0cab5be8869b8ddd73ec89f32805108fae2b653 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Wed, 4 Mar 2020 10:04:41 +0000
Subject: [PATCH 10/13] FIX Null boolean value
---
.../java/com/epimorphics/registry/language/LanguageManager.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/epimorphics/registry/language/LanguageManager.java b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
index 82d7ccd8..7457ed33 100644
--- a/src/main/java/com/epimorphics/registry/language/LanguageManager.java
+++ b/src/main/java/com/epimorphics/registry/language/LanguageManager.java
@@ -27,6 +27,6 @@ public interface LanguageManager {
class Default implements LanguageManager {
@Override public Boolean isMultilingual() { return false; }
@Override public List getLanguages() { return Collections.emptyList(); }
- @Override public Boolean getUseCookies() { return null; }
+ @Override public Boolean getUseCookies() { return false; }
}
}
\ No newline at end of file
From 151e7e0b93d6041b2067f79bd21d81eefe127828 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Wed, 4 Mar 2020 10:41:47 +0000
Subject: [PATCH 11/13] Use normal property binding for language manager on
registry
---
.../epimorphics/registry/core/Registry.java | 35 ++++++++++---------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/src/main/java/com/epimorphics/registry/core/Registry.java b/src/main/java/com/epimorphics/registry/core/Registry.java
index cd1f54e9..351e3cc6 100644
--- a/src/main/java/com/epimorphics/registry/core/Registry.java
+++ b/src/main/java/com/epimorphics/registry/core/Registry.java
@@ -247,21 +247,26 @@ public void startup(App app) {
}
registry = this; // Assumes singleton registry
- // Initialize the registry RDF store from the bootstrap registers if needed
- Description root = store.getDescription(getBaseURI() + "/");
- if (root == null) {
- // Blank store, need to install a bootstrap root registers
- for(String bootSrc : bootFile.split("\\|")) {
- log.info("Loading bootstrap file " + expandFileLocation(bootSrc));
- store.loadBootstrap( expandFileLocation(bootSrc) );
- }
- if (bootdirs != null) {
- for (String bootdir : bootdirs.split("\\|")) {
- bootdir = expandFileLocation( bootdir );
- loadInitialRegisterTree(bootdir);
+ store.beginSafeRead();
+ try {
+ // Initialize the registry RDF store from the bootstrap registers if needed
+ Description root = store.getDescription(getBaseURI() + "/");
+ if (root == null) {
+ // Blank store, need to install a bootstrap root registers
+ for(String bootSrc : bootFile.split("\\|")) {
+ log.info("Loading bootstrap file " + expandFileLocation(bootSrc));
+ store.loadBootstrap( expandFileLocation(bootSrc) );
+ }
+ if (bootdirs != null) {
+ for (String bootdir : bootdirs.split("\\|")) {
+ bootdir = expandFileLocation( bootdir );
+ loadInitialRegisterTree(bootdir);
+ }
}
+ log.info("Installed bootstrap root register");
}
- log.info("Installed bootstrap root register");
+ } finally {
+ store.endSafeRead();
}
// Initialize the forwarding service from the stored forwarding records
@@ -302,10 +307,6 @@ public void processMessage(Message message) {
log.warn("No backup service configured");
}
- LanguageManager languageManager = app.getA(LanguageManager.class);
- if (languageManager != null) {
- setLanguageManager(languageManager);
- }
}
/**
From 631a0dad25460a28d53f83ebfc58791bea817e23 Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Wed, 4 Mar 2020 12:38:29 +0000
Subject: [PATCH 12/13] Fix bootstrap loading
---
.../epimorphics/registry/core/Registry.java | 37 ++++++++++---------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/src/main/java/com/epimorphics/registry/core/Registry.java b/src/main/java/com/epimorphics/registry/core/Registry.java
index 351e3cc6..e0bfeabe 100644
--- a/src/main/java/com/epimorphics/registry/core/Registry.java
+++ b/src/main/java/com/epimorphics/registry/core/Registry.java
@@ -37,6 +37,8 @@
import javax.ws.rs.core.Response;
import com.epimorphics.registry.language.LanguageManager;
+import com.epimorphics.registry.security.DBUserStore;
+import com.epimorphics.registry.security.RegPermission;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.util.FileUtils;
@@ -247,28 +249,30 @@ public void startup(App app) {
}
registry = this; // Assumes singleton registry
+ // Initialize the registry RDF store from the bootstrap registers if needed
+ Description root;
store.beginSafeRead();
try {
- // Initialize the registry RDF store from the bootstrap registers if needed
- Description root = store.getDescription(getBaseURI() + "/");
- if (root == null) {
- // Blank store, need to install a bootstrap root registers
- for(String bootSrc : bootFile.split("\\|")) {
- log.info("Loading bootstrap file " + expandFileLocation(bootSrc));
- store.loadBootstrap( expandFileLocation(bootSrc) );
- }
- if (bootdirs != null) {
- for (String bootdir : bootdirs.split("\\|")) {
- bootdir = expandFileLocation( bootdir );
- loadInitialRegisterTree(bootdir);
- }
- }
- log.info("Installed bootstrap root register");
- }
+ root = store.getDescription(getBaseURI() + "/");
} finally {
store.endSafeRead();
}
+ if (root == null) {
+ // Blank store, need to install a bootstrap root registers
+ for(String bootSrc : bootFile.split("\\|")) {
+ log.info("Loading bootstrap file " + expandFileLocation(bootSrc));
+ store.loadBootstrap( expandFileLocation(bootSrc) );
+ }
+ if (bootdirs != null) {
+ for (String bootdir : bootdirs.split("\\|")) {
+ bootdir = expandFileLocation( bootdir );
+ loadInitialRegisterTree(bootdir);
+ }
+ }
+ log.info("Installed bootstrap root register");
+ }
+
// Initialize the forwarding service from the stored forwarding records
if (forwarder != null) {
store.beginRead();
@@ -306,7 +310,6 @@ public void processMessage(Message message) {
} else {
log.warn("No backup service configured");
}
-
}
/**
From be508ad5bb63ec9556d409d57f1402bd41e2538a Mon Sep 17 00:00:00 2001
From: Simon Oakes
Date: Wed, 4 Mar 2020 12:53:16 +0000
Subject: [PATCH 13/13] Tidy imports
---
.../epimorphics/registry/core/Registry.java | 63 ++++++++-----------
1 file changed, 26 insertions(+), 37 deletions(-)
diff --git a/src/main/java/com/epimorphics/registry/core/Registry.java b/src/main/java/com/epimorphics/registry/core/Registry.java
index e0bfeabe..50726d13 100644
--- a/src/main/java/com/epimorphics/registry/core/Registry.java
+++ b/src/main/java/com/epimorphics/registry/core/Registry.java
@@ -21,49 +21,15 @@
package com.epimorphics.registry.core;
-import static com.epimorphics.registry.core.Status.LIFECYCLE_REGISTER;
-import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-
-import com.epimorphics.registry.language.LanguageManager;
-import com.epimorphics.registry.security.DBUserStore;
-import com.epimorphics.registry.security.RegPermission;
-import org.apache.jena.rdf.model.Model;
-import org.apache.jena.rdf.model.ModelFactory;
-import org.apache.jena.util.FileUtils;
-import org.apache.jena.vocabulary.RDF;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.UnavailableSecurityManagerException;
-import org.glassfish.jersey.uri.UriComponent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.epimorphics.appbase.core.App;
-import com.epimorphics.appbase.core.ComponentBase;
-import com.epimorphics.appbase.core.GenericConfig;
import com.epimorphics.appbase.core.Shutdown;
-import com.epimorphics.appbase.core.Startup;
+import com.epimorphics.appbase.core.*;
import com.epimorphics.appbase.templates.VelocityRender;
import com.epimorphics.appbase.webapi.WebApiException;
import com.epimorphics.rdfutil.ModelWrapper;
import com.epimorphics.registry.core.Command.Operation;
import com.epimorphics.registry.core.ForwardingRecord.Type;
-import com.epimorphics.registry.message.LocalMessagingService;
-import com.epimorphics.registry.message.Message;
-import com.epimorphics.registry.message.MessagingService;
-import com.epimorphics.registry.message.ProcessIfChanges;
-import com.epimorphics.registry.message.RequestLogger;
+import com.epimorphics.registry.language.LanguageManager;
+import com.epimorphics.registry.message.*;
import com.epimorphics.registry.security.UserInfo;
import com.epimorphics.registry.security.UserStore;
import com.epimorphics.registry.store.BackupService;
@@ -75,6 +41,29 @@
import com.epimorphics.registry.webapi.facets.FacetService;
import com.epimorphics.util.EpiException;
import com.epimorphics.util.FileUtil;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.util.FileUtils;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.UnavailableSecurityManagerException;
+import org.glassfish.jersey.uri.UriComponent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.epimorphics.registry.core.Status.LIFECYCLE_REGISTER;
+import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
/**
* This the primary configuration point for the Registry.