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:
sascha@58: package de.intevation.artifactdatabase;
sascha@58:
sascha@58: import de.intevation.artifacts.Artifact;
sascha@58: import de.intevation.artifacts.CallContext;
sascha@58:
sascha@93: import java.io.IOException;
sascha@93: import java.io.OutputStream;
sascha@93:
sascha@58: import org.apache.log4j.Logger;
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:
sascha@58: private static Logger logger = Logger.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 :