changeset 48:41c225c8bd41

Add i18n support via "Accept-Language" HTTP headers. artifacts/trunk@168 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 01 Oct 2009 16:03:12 +0000
parents 4ae4dc99127d
children 823850c63d95
files Changelog artifact-database/pom.xml artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultCallMeta.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactOutResource.java artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactResource.java artifact-database/src/main/java/de/intevation/artifactdatabase/rest/BaseResource.java artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CreateResource.java artifacts/src/main/java/de/intevation/artifacts/ArtifactDatabase.java artifacts/src/main/java/de/intevation/artifacts/CallContext.java artifacts/src/main/java/de/intevation/artifacts/CallMeta.java artifacts/src/main/java/de/intevation/artifacts/PreferredLocale.java contrib/run.sh
diffstat 15 files changed, 235 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/Changelog	Thu Oct 01 09:04:17 2009 +0000
+++ b/Changelog	Thu Oct 01 16:03:12 2009 +0000
@@ -1,3 +1,46 @@
+2009-10-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Add i18n support via "Accept-Language" HTTP headers.
+
+	* artifact-database/pom.xml: Using restlet 2.0 snapshot. 
+	M3 does not implement the required API, M4 is not in maven repo yet.
+	TODO: Bring to M4 as soon it is released in maven repository.
+
+	* contrib/run.sh: Adjusted to use the snapshot.
+
+	* artifacts/src/main/java/de/intevation/artifacts/CallMeta.java:
+	New. Meta information of a call, languages, e.g.
+
+	* artifacts/src/main/java/de/intevation/artifacts/PreferredLocale.java:
+	New. Model preferred languages.
+
+	* artifacts/src/main/java/de/intevation/artifacts/CallContext.java:
+	Has now a reference to the meta information.
+
+	* artifacts/src/main/java/de/intevation/artifacts/ArtifactDatabase.java:
+	describe, feed, advance and out call contexts are now enriched with 
+	external meta data.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java:
+	Additional debug output how long the cleaner slept between cleanups.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java:
+	New. Default implementation of PreferredLocale.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultCallMeta.java:
+	New. Default implementation of CallMeta.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java:
+	Adjusted to take the additional meta information.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/rest/BaseResource.java:
+	Added a method to create a CallMeta object from web client information.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactResource.java,
+	artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CreateResource.java,
+	artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactOutResource.java:
+	Call the artifact database with the meta data from there base class BaseResoure.
+
 2009-10-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* artifact-database/src/main/java/de/intevation/artifactdatabase/SQL.java,
--- a/artifact-database/pom.xml	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/pom.xml	Thu Oct 01 16:03:12 2009 +0000
@@ -52,12 +52,12 @@
     <dependency>
       <groupId>org.restlet</groupId>
       <artifactId>org.restlet</artifactId>
-      <version>2.0-M3</version>
+      <version>2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.restlet</groupId>
       <artifactId>org.restlet.ext.xml</artifactId>
-      <version>2.0-M3</version>
+      <version>2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.h2database</groupId>
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java	Thu Oct 01 16:03:12 2009 +0000
@@ -10,6 +10,7 @@
 import de.intevation.artifacts.ArtifactFactory;
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
 
 import de.intevation.artifactdatabase.Backend.PersistentArtifact;
 
@@ -52,10 +53,16 @@
     {
         protected PersistentArtifact artifact;
         protected int                action;
+        protected CallMeta           callMeta;
 
-        public CallContextImpl(PersistentArtifact artifact, int action) {
+        public CallContextImpl(
+            PersistentArtifact artifact, 
+            int                action,
+            CallMeta           callMeta
+        ) {
             this.artifact = artifact;
             this.action   = action;
+            this.callMeta = callMeta;
         }
 
         public void afterCall(int action) {
@@ -76,6 +83,10 @@
             return context;
         }
 
+        public CallMeta getMeta() {
+            return callMeta;
+        }
+
         public void postCall() {
             switch (action) {
                 case NOTHING:
@@ -102,22 +113,25 @@
     {
         protected PersistentArtifact artifact;
         protected Document           format;
+        protected CallMeta           callMeta;
 
         public DeferredOutputImpl() {
         }
 
         public DeferredOutputImpl(
             PersistentArtifact artifact,
-            Document           format
+            Document           format,
+            CallMeta           callMeta
         ) {
             this.artifact = artifact;
             this.format   = format;
+            this.callMeta = callMeta;
         }
 
         public void write(OutputStream output) throws IOException {
 
             CallContextImpl cc = new CallContextImpl(
-                artifact, CallContext.TOUCH);
+                artifact, CallContext.TOUCH, callMeta);
 
             try {
                 artifact.getArtifact().out(format, output, cc);
@@ -227,8 +241,11 @@
         return (ArtifactFactory)name2factory.get(factoryName);
     }
 
-    public Document createArtifactWithFactory(String factoryName)
-        throws ArtifactDatabaseException
+    public Document createArtifactWithFactory(
+        String   factoryName, 
+        CallMeta callMeta
+    )
+    throws ArtifactDatabaseException
     {
         ArtifactFactory factory = getArtifactFactory(factoryName);
 
@@ -258,7 +275,7 @@
         }
 
         CallContextImpl cc = new CallContextImpl(
-            persistentArtifact, CallContext.NOTHING);
+            persistentArtifact, CallContext.NOTHING, callMeta);
 
         try {
             return artifact.describe(cc);
@@ -268,28 +285,7 @@
         }
     }
 
-    public Document describe(String identifier)
-        throws ArtifactDatabaseException
-    {
-        // TODO: Handle background tasks
-        PersistentArtifact artifact = backend.getArtifact(identifier);
-
-        if (artifact == null) {
-            throw new ArtifactDatabaseException(NO_SUCH_ARTIFACT);
-        }
-
-        CallContextImpl cc = new CallContextImpl(
-            artifact, CallContext.TOUCH);
-
-        try {
-            return artifact.getArtifact().describe(cc);
-        }
-        finally {
-            cc.postCall();
-        }
-    }
-
-    public Document advance(String identifier, Document target)
+    public Document describe(String identifier, CallMeta callMeta)
         throws ArtifactDatabaseException
     {
         // TODO: Handle background tasks
@@ -300,17 +296,17 @@
         }
 
         CallContextImpl cc = new CallContextImpl(
-            artifact, CallContext.STORE);
+            artifact, CallContext.TOUCH, callMeta);
 
         try {
-            return artifact.getArtifact().advance(target, cc);
+            return artifact.getArtifact().describe(cc);
         }
         finally {
             cc.postCall();
         }
     }
 
-    public Document feed(String identifier, Document data)
+    public Document advance(String identifier, Document target, CallMeta callMeta)
         throws ArtifactDatabaseException
     {
         // TODO: Handle background tasks
@@ -321,7 +317,28 @@
         }
 
         CallContextImpl cc = new CallContextImpl(
-            artifact, CallContext.STORE);
+            artifact, CallContext.STORE, callMeta);
+
+        try {
+            return artifact.getArtifact().advance(target, cc);
+        }
+        finally {
+            cc.postCall();
+        }
+    }
+
+    public Document feed(String identifier, Document data, CallMeta callMeta)
+        throws ArtifactDatabaseException
+    {
+        // TODO: Handle background tasks
+        PersistentArtifact artifact = backend.getArtifact(identifier);
+
+        if (artifact == null) {
+            throw new ArtifactDatabaseException(NO_SUCH_ARTIFACT);
+        }
+
+        CallContextImpl cc = new CallContextImpl(
+            artifact, CallContext.STORE, callMeta);
 
         try {
             return artifact.getArtifact().feed(data, cc);
@@ -331,7 +348,7 @@
         }
     }
 
-    public DeferredOutput out(String identifier, Document format)
+    public DeferredOutput out(String identifier, Document format, CallMeta callMeta)
         throws ArtifactDatabaseException
     {
         // TODO: Handle background tasks
@@ -341,7 +358,7 @@
             throw new ArtifactDatabaseException(NO_SUCH_ARTIFACT);
         }
 
-        return new DeferredOutputImpl(artifact, format);
+        return new DeferredOutputImpl(artifact, format, callMeta);
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java	Thu Oct 01 16:03:12 2009 +0000
@@ -206,6 +206,8 @@
         logger.info("sleep time: " + sleepTime + "ms");
         for (;;) {
             cleanup();
+            long startTime = System.currentTimeMillis();
+
             try {
                 synchronized (sleepLock) {
                     sleepLock.wait(sleepTime);
@@ -213,6 +215,12 @@
             }
             catch (InterruptedException ie) {
             }
+
+            long stopTime = System.currentTimeMillis();
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("Cleaner slept " + (stopTime - startTime) + "ms");
+            }
         } // for (;;)
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultCallMeta.java	Thu Oct 01 16:03:12 2009 +0000
@@ -0,0 +1,24 @@
+package de.intevation.artifactdatabase;
+
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.PreferredLocale;
+
+/**
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public class DefaultCallMeta
+implements   CallMeta
+{
+    protected PreferredLocale [] languages;
+
+    public DefaultCallMeta() {
+    }
+
+    public DefaultCallMeta(PreferredLocale [] languages) {
+    }
+
+    public PreferredLocale [] getLanguages() {
+        return languages;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java	Thu Oct 01 16:03:12 2009 +0000
@@ -0,0 +1,32 @@
+package de.intevation.artifactdatabase;
+
+import de.intevation.artifacts.PreferredLocale;
+
+import java.util.Locale;
+
+/**
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public class DefaultPreferredLocale
+implements   PreferredLocale
+{
+    protected Locale locale;
+    protected float  quality;
+
+    public DefaultPreferredLocale() {
+    }
+
+    public DefaultPreferredLocale(String lang, float quality) {
+        locale = new Locale(lang);
+        this.quality = quality;
+    }
+
+    public Locale getLocale() {
+        return locale;
+    }
+
+    public float getQuality() {
+        return quality;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactOutResource.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactOutResource.java	Thu Oct 01 16:03:12 2009 +0000
@@ -84,7 +84,7 @@
         try {
             return new OutRepresentation(
                 mimeType,
-                db.out(identifier, inputDocument));
+                db.out(identifier, inputDocument, getCallMeta()));
         }
         catch (ArtifactDatabaseException adbe) {
             Response response = getResponse();
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactResource.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactResource.java	Thu Oct 01 16:03:12 2009 +0000
@@ -62,7 +62,7 @@
         try {
             return new DomRepresentation(
                 MediaType.APPLICATION_XML,
-                db.describe(identifier));
+                db.describe(identifier, getCallMeta()));
         }
         catch (ArtifactDatabaseException adbe) {
             logger.warn(adbe.getLocalizedMessage(), adbe);
@@ -83,10 +83,10 @@
 
         try {
             if (action.equals(FEED)) {
-                out = db.feed(identifier, source);
+                out = db.feed(identifier, source, getCallMeta());
             }
             else if (action.equals(ADVANCE)) {
-                out = db.advance(identifier, source);
+                out = db.advance(identifier, source, getCallMeta());
             }
             else {
                 throw new ArtifactDatabaseException(NO_SUCH_ACTION_MESSAGE);
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/BaseResource.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/BaseResource.java	Thu Oct 01 16:03:12 2009 +0000
@@ -1,5 +1,8 @@
 package de.intevation.artifactdatabase.rest;
 
+import de.intevation.artifacts.CallMeta;
+import de.intevation.artifacts.PreferredLocale;
+
 import org.apache.log4j.Logger;
 
 import org.restlet.resource.ServerResource;
@@ -7,6 +10,16 @@
 
 import org.restlet.representation.Representation;
 
+import org.restlet.data.Language;
+import org.restlet.data.ClientInfo;
+import org.restlet.data.Preference;
+
+import java.util.List;
+import java.util.Iterator;
+
+import de.intevation.artifactdatabase.DefaultCallMeta;
+import de.intevation.artifactdatabase.DefaultPreferredLocale;
+
 /**
  * @author Sascha L. Teichmann (sascha.teichmann@intevation)
  */
@@ -59,5 +72,24 @@
     {
         return super.get();
     }
+
+    protected CallMeta getCallMeta() {
+        ClientInfo clientInfo = getClientInfo();
+
+        List<Preference<Language>> pl = clientInfo.getAcceptedLanguages();
+
+        PreferredLocale [] languages = new PreferredLocale[pl.size()];
+
+        int index = 0;
+
+        for (Iterator<Preference<Language>> iter = pl.iterator(); iter.hasNext();) {
+            Preference p = iter.next();
+            String lang    = p.getMetadata().getName();
+            float  quality = p.getQuality();
+            languages[index++] = new DefaultPreferredLocale(lang, quality); 
+        }
+
+        return new DefaultCallMeta(languages);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CreateResource.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CreateResource.java	Thu Oct 01 16:03:12 2009 +0000
@@ -77,7 +77,7 @@
         try {
             return new DomRepresentation(
                 MediaType.APPLICATION_XML,
-                db.createArtifactWithFactory(factory));
+                db.createArtifactWithFactory(factory, getCallMeta()));
         }
         catch (ArtifactDatabaseException adbe) {
             Response response = getResponse();
--- a/artifacts/src/main/java/de/intevation/artifacts/ArtifactDatabase.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifacts/src/main/java/de/intevation/artifacts/ArtifactDatabase.java	Thu Oct 01 16:03:12 2009 +0000
@@ -24,19 +24,19 @@
      */
     String [][] artifactFactoryNamesAndDescriptions();
 
-    Document createArtifactWithFactory(String factory)
-        throws ArtifactDatabaseException;
-
-    Document describe(String artifact)
+    Document createArtifactWithFactory(String factory, CallMeta callMeta)
         throws ArtifactDatabaseException;
 
-    Document advance(String artifact, Document target)
+    Document describe(String artifact, CallMeta callMeta)
         throws ArtifactDatabaseException;
 
-    Document feed(String artifact, Document data)
+    Document advance(String artifact, Document target, CallMeta callMeta)
         throws ArtifactDatabaseException;
 
-    DeferredOutput out(String artifact, Document format)
+    Document feed(String artifact, Document data, CallMeta callMeta)
+        throws ArtifactDatabaseException;
+
+    DeferredOutput out(String artifact, Document format, CallMeta callMeta)
         throws ArtifactDatabaseException;
 
 }
--- a/artifacts/src/main/java/de/intevation/artifacts/CallContext.java	Thu Oct 01 09:04:17 2009 +0000
+++ b/artifacts/src/main/java/de/intevation/artifacts/CallContext.java	Thu Oct 01 16:03:12 2009 +0000
@@ -14,5 +14,7 @@
     void afterBackground(int action);
 
     Object globalContext();
+
+    CallMeta getMeta();
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/de/intevation/artifacts/CallMeta.java	Thu Oct 01 16:03:12 2009 +0000
@@ -0,0 +1,12 @@
+package de.intevation.artifacts;
+
+/**
+ * Interface to inject meta data like languages to CallContexts.
+ *
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public interface CallMeta
+{
+    PreferredLocale [] getLanguages();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/de/intevation/artifacts/PreferredLocale.java	Thu Oct 01 16:03:12 2009 +0000
@@ -0,0 +1,15 @@
+package de.intevation.artifacts;
+
+import java.util.Locale;
+
+/**
+ * Interface to build pairs of preference and quality.
+ *
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public interface PreferredLocale
+{
+    Locale getLocale();
+    float getQuality();
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/contrib/run.sh	Thu Oct 01 09:04:17 2009 +0000
+++ b/contrib/run.sh	Thu Oct 01 16:03:12 2009 +0000
@@ -1,6 +1,6 @@
 #!/bin/bash
-RESTLET_CORE=`find -L ~/.m2 -name org\.restlet-\*M\*.jar`
-RESTLET_XML=`find -L ~/.m2 -name org\.restlet.ext.xml-\*M\*.jar`
+RESTLET_CORE=`find -L ~/.m2 -name org\.restlet-\*SNAP\*.jar`
+RESTLET_XML=`find -L ~/.m2 -name org\.restlet.ext.xml-\*SNAP\*.jar`
 H2=`find -L ~/.m2 -name h2-\*.jar`
 LOG4J=`find -L ~/.m2 -name log4j-1.2.13\*.jar`
 DBCP=`find -L ~/.m2 -name commons-dbcp-\*.jar`

http://dive4elements.wald.intevation.org