# HG changeset patch # User Sascha L. Teichmann # Date 1254412992 0 # Node ID 41c225c8bd41ef5a8d63047cdeea227bfdbf09cd # Parent 4ae4dc99127dd730ddc7c3d28447953e0d7babc6 Add i18n support via "Accept-Language" HTTP headers. artifacts/trunk@168 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 4ae4dc99127d -r 41c225c8bd41 Changelog --- 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 + + 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 * artifact-database/src/main/java/de/intevation/artifactdatabase/SQL.java, diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/pom.xml --- 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 @@ org.restlet org.restlet - 2.0-M3 + 2.0-SNAPSHOT org.restlet org.restlet.ext.xml - 2.0-M3 + 2.0-SNAPSHOT com.h2database diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java --- 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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java --- 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 (;;) } } diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultCallMeta.java --- /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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java --- /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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactOutResource.java --- 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(); diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ArtifactResource.java --- 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); diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/BaseResource.java --- 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> pl = clientInfo.getAcceptedLanguages(); + + PreferredLocale [] languages = new PreferredLocale[pl.size()]; + + int index = 0; + + for (Iterator> 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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CreateResource.java --- 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(); diff -r 4ae4dc99127d -r 41c225c8bd41 artifacts/src/main/java/de/intevation/artifacts/ArtifactDatabase.java --- 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; } diff -r 4ae4dc99127d -r 41c225c8bd41 artifacts/src/main/java/de/intevation/artifacts/CallContext.java --- 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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifacts/src/main/java/de/intevation/artifacts/CallMeta.java --- /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: diff -r 4ae4dc99127d -r 41c225c8bd41 artifacts/src/main/java/de/intevation/artifacts/PreferredLocale.java --- /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: diff -r 4ae4dc99127d -r 41c225c8bd41 contrib/run.sh --- 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`