ingo@100: /* ingo@100: * Copyright (c) 2010 by Intevation GmbH ingo@100: * ingo@100: * This program is free software under the LGPL (>=v2.1) ingo@100: * Read the file LGPL.txt coming with the software for details ingo@100: * or visit http://www.gnu.org/licenses/ if it does not exist. ingo@100: */ ingo@100: teichmann@475: package org.dive4elements.artifactdatabase; sascha@58: teichmann@475: import org.dive4elements.artifacts.Artifact; teichmann@475: import org.dive4elements.artifacts.CallContext; sascha@58: sascha@93: import java.io.IOException; sascha@93: import java.io.OutputStream; sascha@93: tom@570: import org.apache.logging.log4j.Logger; tom@570: import org.apache.logging.log4j.LogManager; sascha@58: sascha@93: import org.w3c.dom.Document; sascha@58: sascha@58: /** sascha@89: * The proxy artifact is a wrapper around another artifact. It simply forwards sascha@89: * the interface calls to this underlaying artifact. sascha@89: * The reason for using proxy artifacts is enable the workflow to exchange sascha@89: * artifacts at any time by something else without losing the concrete sascha@89: * artifact. From the outside it always looks like there is only one sascha@89: * distinct artifact.
sascha@89: * sascha@89: * An inner artifact is able to replace itself by indirectly hand over sascha@89: * the replacement via the call context to the proxy artifact.
sascha@89: * To do so the proxied artifact has to call sascha@90: * callContext.getContextValue(EPLACE_PROXY, replacement);. sascha@89: * After the current call (describe, feed, advance and out) of the proxied sascha@89: * artifact is finished the proxy artifact replaces the former proxied artifact sascha@89: * with the replacement. sascha@90: * sascha@77: * @author Sascha L. Teichmann sascha@58: */ sascha@58: public class ProxyArtifact sascha@58: extends DefaultArtifact sascha@58: { sascha@89: /** sascha@89: * Key to signal that the proxied artifact should be replaced. sascha@89: */ sascha@58: public static final Object REPLACE_PROXY = new Object(); sascha@58: tom@570: private static Logger logger = LogManager.getLogger(ProxyArtifact.class); sascha@58: sascha@89: /** sascha@89: * The proxied artifact. sascha@89: */ sascha@58: protected Artifact proxied; sascha@58: sascha@89: /** sascha@89: * Default constructor. sascha@89: */ sascha@58: public ProxyArtifact() { sascha@58: } sascha@58: sascha@89: /** sascha@89: * Constructor to create a new proxy artifact around a given artifact. sascha@89: * @param proxied The artifact to be proxied. sascha@89: */ sascha@58: public ProxyArtifact(Artifact proxied) { sascha@58: this.proxied = proxied; sascha@58: } sascha@58: sascha@89: /** sascha@89: * The currently proxied artifact. sascha@89: * @return The proxied artifact. sascha@89: */ sascha@58: public Artifact getProxied() { sascha@58: return proxied; sascha@58: } sascha@58: sascha@89: /** sascha@89: * Explicitly set the proxied artifacts. sascha@89: * @param proxied sascha@89: */ sascha@58: public void setProxied(Artifact proxied) { sascha@58: this.proxied = proxied; sascha@58: } sascha@58: sascha@89: @Override ingo@81: public void setIdentifier(String identifier) { ingo@81: this.identifier = identifier; ingo@81: ingo@81: if (proxied != null) ingo@81: proxied.setIdentifier(identifier); ingo@81: } ingo@81: sascha@89: /** sascha@89: * Method to check if the current proxied artifact should be replaced sascha@89: * by a new one coming from the call context. sascha@89: * @param callContext sascha@89: */ sascha@58: protected void checkReplacement(CallContext callContext) { sascha@58: Object replacement = callContext.getContextValue(REPLACE_PROXY); sascha@58: if (replacement instanceof Artifact) { sascha@58: setProxied((Artifact)replacement); sascha@58: } sascha@58: } sascha@58: sascha@89: @Override sascha@58: public String hash() { sascha@58: return proxied != null sascha@58: ? proxied.hash() sascha@58: : super.hash(); sascha@58: } sascha@58: sascha@89: @Override sascha@58: public Document describe(Document data, CallContext context) { sascha@58: try { sascha@58: return proxied != null sascha@58: ? proxied.describe(data, context) sascha@58: : super.describe(data, context); sascha@58: } sascha@58: finally { sascha@58: checkReplacement(context); sascha@58: } sascha@58: } sascha@58: sascha@89: @Override sascha@58: public Document advance(Document target, CallContext context) { sascha@58: try { sascha@58: return proxied != null sascha@58: ? proxied.advance(target, context) sascha@58: : super.advance(target, context); sascha@58: } sascha@58: finally { sascha@58: checkReplacement(context); sascha@58: } sascha@58: } sascha@58: sascha@89: @Override sascha@58: public Document feed(Document target, CallContext context) { sascha@58: try { sascha@86: return proxied != null sascha@58: ? proxied.feed(target, context) sascha@58: : super.feed(target, context); sascha@58: } sascha@58: finally { sascha@58: checkReplacement(context); sascha@58: } sascha@58: } sascha@58: sascha@89: @Override sascha@58: public void out( sascha@58: Document format, sascha@58: OutputStream out, sascha@58: CallContext context sascha@58: ) sascha@58: throws IOException sascha@58: { sascha@58: try { sascha@58: if (proxied != null) { sascha@58: proxied.out(format, out, context); sascha@58: } sascha@58: else { sascha@58: super.out(format, out, context); sascha@58: } sascha@58: } sascha@58: finally { sascha@58: checkReplacement(context); sascha@58: } sascha@58: } sascha@58: sascha@89: @Override sascha@58: public void endOfLife(Object context) { sascha@58: if (proxied != null) { sascha@58: proxied.endOfLife(context); sascha@58: } sascha@58: else { sascha@58: super.endOfLife(context); sascha@58: } sascha@58: } ingo@82: sascha@89: @Override ingo@82: public void cleanup(Object context) { ingo@82: if (proxied != null) ingo@82: proxied.cleanup(context); ingo@82: else ingo@82: super.cleanup(context); ingo@82: } sascha@58: } sascha@89: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :