changeset 58:39fec7d714dc

Added a real artifact proxy class to be more flexible with artifact replacements in artifact databases. artifacts/trunk@359 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 23 Nov 2009 11:15:44 +0000
parents cf9848c85755
children 8cd770330f1b
files ChangeLog artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java artifacts/src/main/java/de/intevation/artifacts/CallContext.java
diffstat 4 files changed, 161 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Nov 13 18:37:51 2009 +0000
+++ b/ChangeLog	Mon Nov 23 11:15:44 2009 +0000
@@ -1,3 +1,30 @@
+2009-11-23	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* artifacts/src/main/java/de/intevation/artifacts/CallContext.java:
+	Added a context dictionary accessible through putContextValue(key, value)
+	and getContextValue(key). Purpose is make artifact calls stackable and
+	transfer information through the call level transparently.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java:
+	Adjusted default implementation of CallContext.
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java:
+	New. A general proxy class for artifacts in artifact databases. This class uses 
+	the extended call context semantics.
+
+	The artifact calls (feed, describe, out, ...) are passed to a proxied artifact.
+	If the proxied artifact decides to be replaced by some other artifact it has to
+	to store a reference to the replacement artifact in the call context with
+	putContextValue(ProxyArtifact.REPLACE_PROXY, my_new_artifact). After the call
+	is finished the proxied object will change. This indirect callback mechanism is
+	used to minimize side effects.
+
+	The identifier() call is not forwarded to the proxied artifact to have a stable id.
+
+	Limitations: This mechanism does not let you build real matroska (multi level)
+	like artifact structures. This would only be possible if a kind of call context
+	stack is introduced.
+
 2009-11-13  Hans Plum <hans@intevation.de>
 
 	RELEASE 0.2
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java	Fri Nov 13 18:37:51 2009 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java	Mon Nov 23 11:15:44 2009 +0000
@@ -54,6 +54,7 @@
         protected PersistentArtifact artifact;
         protected int                action;
         protected CallMeta           callMeta;
+        protected HashMap            customValues;
 
         public CallContextImpl(
             PersistentArtifact artifact, 
@@ -106,6 +107,19 @@
                     throw new IllegalStateException(INVALID_CALL_STATE);
             }
         }
+
+        public Object getContextValue(Object key) {
+            return customValues != null
+                ? customValues.get(key)
+                : null;
+        }
+
+        public Object putContextValue(Object key, Object value) {
+            if (customValues == null) {
+                customValues = new HashMap();
+            }
+            return customValues.put(key, value);
+        }
     } // class CallContextImpl
 
     public class DeferredOutputImpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java	Mon Nov 23 11:15:44 2009 +0000
@@ -0,0 +1,116 @@
+package de.intevation.artifactdatabase;
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.ArtifactFactory;
+
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public class ProxyArtifact
+extends      DefaultArtifact
+{
+    public static final Object REPLACE_PROXY = new Object();
+
+    private static Logger logger = Logger.getLogger(ProxyArtifact.class);
+
+    protected Artifact proxied;
+
+    public ProxyArtifact() {
+    }
+
+    public ProxyArtifact(Artifact proxied) {
+        this.proxied = proxied;
+    }
+
+    public Artifact getProxied() {
+        return proxied;
+    }
+
+    public void setProxied(Artifact proxied) {
+        this.proxied = proxied;
+    }
+
+    protected void checkReplacement(CallContext callContext) {
+        Object replacement = callContext.getContextValue(REPLACE_PROXY);
+        if (replacement instanceof Artifact) {
+            setProxied((Artifact)replacement);
+        }
+    }
+
+    public String hash() {
+        return proxied != null
+            ? proxied.hash()
+            : super.hash();
+    }
+
+    public Document describe(Document data, CallContext context) {
+        try {
+            return proxied != null
+                ? proxied.describe(data, context)
+                : super.describe(data, context);
+        }
+        finally {
+            checkReplacement(context);
+        }
+    }
+
+    public Document advance(Document target, CallContext context) {
+        try {
+            return proxied != null
+                ? proxied.advance(target, context)
+                : super.advance(target, context);
+        }
+        finally {
+            checkReplacement(context);
+        }
+    }
+
+    public Document feed(Document target, CallContext context) {
+        try {
+            return proxied != null 
+                ? proxied.feed(target, context)
+                : super.feed(target, context);
+        }
+        finally {
+            checkReplacement(context);
+        }
+    }
+
+    public void out(
+        Document     format,
+        OutputStream out,
+        CallContext  context
+    )
+    throws IOException
+    {
+        try {
+            if (proxied != null) {
+                proxied.out(format, out, context);
+            }
+            else {
+                super.out(format, out, context);
+            }
+        }
+        finally {
+            checkReplacement(context);
+        }
+    }
+
+    public void endOfLife(Object context) {
+        if (proxied != null) {
+            proxied.endOfLife(context);
+        }
+        else {
+            super.endOfLife(context);
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/artifacts/src/main/java/de/intevation/artifacts/CallContext.java	Fri Nov 13 18:37:51 2009 +0000
+++ b/artifacts/src/main/java/de/intevation/artifacts/CallContext.java	Mon Nov 23 11:15:44 2009 +0000
@@ -16,5 +16,9 @@
     Object globalContext();
 
     CallMeta getMeta();
+    
+    Object getContextValue(Object key);
+
+    Object putContextValue(Object key, Object value);
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org