changeset 90:68285f7bc476

More javadoc. artifacts/trunk@846 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 26 Mar 2010 17:59:50 +0000
parents d348fe1fd822
children 730ff077a58c
files ChangeLog artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactContext.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactFactory.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultService.java artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultServiceFactory.java artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java
diffstat 9 files changed, 373 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Mar 26 16:16:32 2010 +0000
+++ b/ChangeLog	Fri Mar 26 17:59:50 2010 +0000
@@ -1,3 +1,15 @@
+2010-03-26	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultService.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactContext.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactFactory.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultServiceFactory.java,
+	  artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java:
+	  Even more javadoc.
+
 2010-03-26	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java,
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/Backend.java	Fri Mar 26 17:59:50 2010 +0000
@@ -15,6 +15,9 @@
 import org.apache.log4j.Logger;
 
 /**
+ * The backend implements the low level layer used to store artifacts
+ * in a SQL database.
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class Backend
@@ -22,37 +25,92 @@
 {
     private static Logger logger = Logger.getLogger(Backend.class);
 
+    /**
+     * The SQL statement to create new artifact id inside the database.
+     */
     public static final String SQL_NEXT_ID =
         SQL.get("artifacts.id.nextval");
 
+    /**
+     * The SQL statement to insert an artifact into the database.
+     */
     public static final String SQL_INSERT =
         SQL.get("artifacts.insert");
 
+    /**
+     * The SQL statement to update some columns of an existing
+     * artifact in the database.
+     */
     public static final String SQL_UPDATE =
         SQL.get("artifacts.update");
 
+    /**
+     * The SQL statement to touch the access time of an
+     * artifact inside the database.
+     */
     public static final String SQL_TOUCH =
         SQL.get("artifacts.touch");
 
+    /**
+     * The SQL statement to load an artifact by a given
+     * identifier from the database.
+     */
     public static final String SQL_LOAD_BY_GID =
         SQL.get("artifacts.select.gid");
 
+    /**
+     * The SQL statement to get the database id of an artifact
+     * identified by the identifier.
+     */
     public static final String SQL_GET_ID =
         SQL.get("artifacts.get.id");
 
+    /**
+     * The SQL statement to replace the content of an
+     * existing artifact inside the database.
+     */
     public static final String SQL_REPLACE =
         SQL.get("artifacts.replace");
 
+    /**
+     * The database cleaner. Reference is stored here because
+     * the cleaner is woken up if the backend finds an outdated
+     * artifact. This artifact should be removed as soon as
+     * possible.
+     */
     protected DatabaseCleaner cleaner;
 
+    /**
+     * To revive an artifact from the bytes coming from the database
+     * we need the artifact factory which references the artifact
+     * serializer which is able to do the reviving job.
+     */
     protected FactoryLookup   factoryLookup;
 
+    /**
+     * Little helper interface to decouple the ArtifactDatabase
+     * from the Backend. A ArtifactDatabase should depend on a
+     * Backend but a Backend not from an ArtifactDatabase.
+     */
     public interface FactoryLookup {
 
+        /**
+         * Returns an ArtifactFactory which is bound to a given name.
+         * @param factoryName The name of the artifact factory.
+         * @return The ArtifactFactory bound to the factory name or
+         * null if not matching factory is found.
+         */
         ArtifactFactory getArtifactFactory(String factoryName);
 
     } // interface FactoryLookup
 
+    /**
+     * Inner class that brigdes between the persisten form of the
+     * artifact and the living one inside the artifact database.
+     * After the describe(), feed(), advance() and out() operations
+     * of the artifact it must be possible to write to modified artifact
+     * back into the database.
+     */
     public final class PersistentArtifact
     extends            Id
     {
@@ -60,6 +118,14 @@
         private ArtifactSerializer serializer;
         private Long               ttl;
 
+        /**
+         * Cronstructor to create a persistent artifact.
+         * @param artifact   The living artifact.
+         * @param serializer The serializer to store the artifact
+         * after the operations.
+         * @param ttl The time to life of the artifact.
+         * @param id The database id of the artifact.
+         */
         public PersistentArtifact(
             Artifact           artifact,
             ArtifactSerializer serializer,
@@ -72,18 +138,34 @@
             this.ttl        = ttl;
         }
 
+        /**
+         * Returns the wrapped living artifact.
+         * @return the living artifact.
+         */
         public Artifact getArtifact() {
             return artifact;
         }
 
+        /**
+         * Returns the serialized which is able to write a
+         * modified artifact back into the database.
+         * @return The serializer.
+         */
         public ArtifactSerializer getSerializer() {
             return serializer;
         }
 
+        /**
+         * The time to life of the artifact.
+         * @return The time to live.
+         */
         public Long getTTL() {
             return ttl;
         }
 
+        /**
+         * Stores the living artifact back into the database.
+         */
         public void store() {
             if (logger.isDebugEnabled()) {
                 logger.debug("storing artifact id = " + getId());
@@ -91,6 +173,9 @@
             Backend.this.store(this);
         }
 
+        /**
+         * Only touches the access time of the artifact.
+         */
         public void touch() {
             if (logger.isDebugEnabled()) {
                 logger.debug("touching artifact id = " + getId());
@@ -99,26 +184,59 @@
         }
     } // class ArtifactWithId
 
+    /**
+     * Default constructor
+     */
     public Backend() {
     }
 
+    /**
+     * Constructor to create a backend with a link to the database cleaner.
+     * @param cleaner The clean which periodically removes outdated
+     * artifacts from the database.
+     */
     public Backend(DatabaseCleaner cleaner) {
         this.cleaner = cleaner;
     }
 
+    /**
+     * Sets the factory lookup mechanism to decouple ArtifactDatabase
+     * and Backend.
+     * @param factoryLookup
+     */
     public void setFactoryLookup(FactoryLookup factoryLookup) {
         this.factoryLookup = factoryLookup;
     }
 
+    /**
+     * Sets the database cleaner explicitly.
+     * @param cleaner The database cleaner
+     */
     public void setCleaner(DatabaseCleaner cleaner) {
         this.cleaner = cleaner;
     }
 
+    /**
+     * Returns a new unique identifier to external identify
+     * the artifact across the system. This implementation
+     * uses random UUIDs v4 to achieve this target.
+     * @return the new identifier
+     */
     public String newIdentifier() {
         // TODO: check database for collisions.
         return StringUtils.newUUID();
     }
 
+    /**
+     * Stores a new artifact into the database.
+     * @param artifact The artifact to be stored
+     * @param factory  The factory which build the artifact
+     * @param ttl      The initial time to life of the artifact.
+     * @return         A persistent wrapper around the living
+     * artifact to be able to write modification later.
+     * @throws Exception Thrown if something went wrong with the
+     * storage process.
+     */
     public PersistentArtifact storeInitially(
         Artifact        artifact,
         ArtifactFactory factory,
@@ -133,6 +251,17 @@
             insertDatabase(artifact, factory, ttl));
     }
 
+    /**
+     * Stores an artifact into database if it does not exist there.
+     * If it exists there it is only updated.
+     * @param artifact The artifact to store/update.
+     * @param factory The factory which created the artifact.
+     * @param ttl The initial time to live of the artifact.
+     * @return A persistent version of the artifact to be able
+     * to store a modification later.
+     * @throws Exception Thrown if something went wrong during
+     * storing/updating.
+     */
     public PersistentArtifact storeOrReplace(
         Artifact        artifact,
         ArtifactFactory factory,
@@ -147,12 +276,32 @@
             storeOrReplaceDatabase(artifact, factory, ttl));
     }
 
+    /**
+     * Implementors of this interface are able to process the raw
+     * artifact data from the database for loading.
+     */
     public interface ArtifactLoader {
 
+        /**
+         * Creates a custom object from the raw artifact database data.
+         * @param factory The factory that created this artifact.
+         * @param ttl The current time to life of the artifact.
+         * @param bytes The raw artifact bytes from the database.
+         * @param id The database id of the artifact.
+         * @return The custom object created by the implementation.
+         */
         Object load(ArtifactFactory factory, Long ttl, byte [] bytes, int id);
 
     } // interface ArtifactLoader
 
+    /**
+     * Fetches an artifact from the database identified by the
+     * given identifier.
+     * @param identifer The identifier of the artifact.
+     * @return A persistent wrapper around the found artifact
+     * to be able to write back a modifaction later or null
+     * if no artifact is found for this identifier.
+     */
     public PersistentArtifact getArtifact(String identifer) {
 
         return (PersistentArtifact)loadArtifact(
@@ -176,6 +325,13 @@
             });
     }
 
+    /**
+     * More general loading mechanism for artifacts. The concrete
+     * load processing is delegated to the given loader.
+     * @param identifer The identifier of the artifact.
+     * @param loader The loader which processes the raw database data.
+     * @return The object created by the loader.
+     */
     public Object loadArtifact(String identifer, ArtifactLoader loader) {
 
         if (!StringUtils.checkUUID(identifer)) {
@@ -250,6 +406,11 @@
         return null;
     }
 
+    /**
+     * Called if the load mechanism found an outdated artifact.
+     * It  wakes up the database cleaner.
+     * @param id The id of the outdated artifact.
+     */
     protected void artifactOutdated(int id) {
         if (logger.isDebugEnabled()) {
             logger.info("artifactOutdated: id = " + id);
@@ -268,7 +429,8 @@
             .getArtifactFactory(factoryName);
 
         if (factory == null) {
-            logger.error("reviveArtifact: no factory '" + factoryName + "' found");
+            logger.error(
+                "reviveArtifact: no factory '" + factoryName + "' found");
             return null;
         }
 
@@ -277,6 +439,15 @@
         return serializer.fromBytes(bytes);
     }
 
+    /**
+     * Internal method to store/replace an artifact inside the database.
+     * If an artifact with the given identifier does not exists it is
+     * created else only the content data is updated.
+     * @param artifact The artifact to be store/update inside the database.
+     * @param factory The factory that created the artifact.
+     * @param ttl The initial time to life of the artifact.
+     * @return The database id of the stored/updated artifact.
+     */
     protected int storeOrReplaceDatabase(
         Artifact        artifact,
         ArtifactFactory factory,
@@ -391,6 +562,13 @@
         throw new RuntimeException("failed insert artifact into database");
     }
 
+    /**
+     * Internal method to store an artifact inside the database.
+     * @param artifact The artifact to be stored.
+     * @param factory The factory which created the artifact.
+     * @param ttl The initial time to live of the artifact.
+     * @return The database id of the stored artifact.
+     */
     protected int insertDatabase(
         Artifact        artifact,
         ArtifactFactory factory,
@@ -470,6 +648,11 @@
         throw new RuntimeException("failed insert artifact into database");
     }
 
+    /**
+     * Touches the access timestamp of a given artifact to prevent
+     * that it will be removed from the database by the database cleaner.
+     * @param artifact The persistent wrapper around the living artifact.
+     */
     public void touch(PersistentArtifact artifact) {
 
         try {
@@ -508,6 +691,11 @@
         }
     }
 
+    /**
+     * Writes modification of an artifact back to the database.
+     * @param artifact The persistent wrapper around a living
+     * artifact.
+     */
     public void store(PersistentArtifact artifact) {
 
         try {
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DatabaseCleaner.java	Fri Mar 26 17:59:50 2010 +0000
@@ -15,46 +15,111 @@
 import java.util.List;
 
 /**
+ * The database cleaner runs in background. It sleep for a configurable
+ * while and when it wakes up it removes outdated artifacts from the
+ * database. Outdated means that the the last access to the artifact
+ * is longer aga then the time to live of this artifact.<br>
+ * Before the artifact is finally removed from the system it is
+ * revived one last time an the #endOfLife() method of the artifact
+ * is called.<br>
+ * The artifact implementations may e.g. use this to remove some extrenal
+ * resources form the system.
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class DatabaseCleaner
 extends      Thread
 {
+    /**
+     * Implementors of this interface are able to create a
+     * living artifact from a given byte array.
+     */
     public interface ArtifactReviver {
 
+        /**
+         * Called to revive an artifact from a given byte array.
+         * @param factoryName The name of the factory which
+         * created this artifact.
+         * @param bytes The bytes of the serialized artifact.
+         * @return The revived artfiact.
+         */
         Artifact reviveArtifact(String factoryName, byte [] bytes);
 
     } // interface ArtifactReviver
 
     private static Logger logger = Logger.getLogger(DatabaseCleaner.class);
 
+    /**
+     * Number of artifacts to be loaded at once. Used to
+     * mitigate the problem of a massive denial of service
+     * if too many artifacts have died since last cleanup.
+     */
     public static final int MAX_ROWS = 50;
 
+    /**
+     * The SQL statement to select the outdated artifacts.
+     */
     public static final String SQL_OUTDATED =
         SQL.get("artifacts.outdated");
 
+    /**
+     * The SQL statement to delete some artifacts from the database.
+     */
     public static final String SQL_DELETE =
         SQL.get("artifacts.delete");
 
+    /**
+     * XPath to figure out how long the cleaner should sleep between
+     * cleanups. This is stored in the global configuration.
+     */
     public static final String SLEEP_XPATH =
         "/artifact-database/cleaner/sleep-time/text()";
 
+    /**
+     * Default nap time between cleanups: 5 minutes.
+     */
     public static final long SLEEP_DEFAULT =
         5 * 60 * 1000L; // 5 minutes
 
+    /**
+     * The configured nap time.
+     */
     protected long sleepTime;
 
+    /**
+     * Internal locking mechanism to prevent some race conditions.
+     */
     protected Object sleepLock = new Object();
 
+    /**
+     * A reference to the global context.
+     */
     protected Object context;
 
+    /**
+     * A specialized Id filter which only delete some artifacts.
+     * This is used to prevent deletion of living artifacts.
+     */
     protected Id.Filter filter;
 
+    /**
+     * The reviver used to bring the dead artifact on last
+     * time back to live to call endOfLife() on them.
+     */
     protected ArtifactReviver reviver;
 
+    /**
+     * Default constructor.
+     */
     public DatabaseCleaner() {
     }
 
+    /**
+     * Constructor to create a cleaner with a given global context
+     * and an given reviver.
+     * @param context The global context of the artifact database
+     * @param reviver The reviver to awake artifact one last time.
+     */
     public DatabaseCleaner(Object context, ArtifactReviver reviver) {
         setDaemon(true);
         sleepTime = getSleepTime();
@@ -62,16 +127,32 @@
         this.reviver = reviver;
     }
 
+    /**
+     * Sets the filter that prevents deletion of living artifacts.
+     * Living artifacts are artifacts which are currently active
+     * inside the artifact database. Deleting them in this state
+     * would create severe internal problems.
+     * @param filter
+     */
     public void setFilter(Id.Filter filter) {
         this.filter = filter;
     }
 
+    /**
+     * External hook to tell the cleaner to wake up before its
+     * regular nap time is over. This is the case when the artifact
+     * database finds an artifact which is already outdated.
+     */
     public void wakeup() {
         synchronized (sleepLock) {
             sleepLock.notify();
         }
     }
 
+    /**
+     * Fetches the sleep time from the global configuration.
+     * @return the time to sleep between database cleanups in ms.
+     */
     protected static long getSleepTime() {
         String sleepTimeString = Config.getStringXPath(SLEEP_XPATH);
 
@@ -202,6 +283,11 @@
         logger.info("artifacts removed: " + removedArtifacts);
     }
 
+    /**
+     * The main code of the cleaner. It sleeps for the configured
+     * nap time, cleans up the database, sleeps again and so on.
+     */
+    @Override
     public void run() {
         logger.info("sleep time: " + sleepTime + "ms");
         for (;;) {
@@ -224,4 +310,4 @@
         } // for (;;)
     }
 }
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactContext.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactContext.java	Fri Mar 26 17:59:50 2010 +0000
@@ -12,29 +12,62 @@
  */
 public class DefaultArtifactContext
 {
+    /**
+     * The global configuration document of the artifact database.
+     */
     protected Document config;
 
+    /**
+     * Custom key/value pairs to be used globally in the whole server.
+     */
     protected HashMap  map;
 
+    /**
+     * Default constructor
+     */
     public DefaultArtifactContext() {
         this(null);
     }
 
+    /**
+     * Constructor to create a context with a given global
+     * configuration document and an empty map of custom
+     * key/value pairs.
+     * @param config
+     */
     public DefaultArtifactContext(Document config) {
         this.config = config;
         map = new HashMap();
     }
 
+    /**
+     * Fetch a custom value from the global key/value map using
+     * a given key.
+     * @param key The key.
+     * @return The stored value or null if no value was found under
+     * this key.
+     */
     public synchronized Object get(Object key) {
         return map.get(key);
     }
 
+    /**
+     * Store a custom key/value pair in the global map.
+     * @param key The key to store
+     * @param value The value to store
+     * @return The old value registered under the key or null
+     * if none wa there before.
+     */
     public synchronized Object put(Object key, Object value) {
         return map.put(key, value);
     }
 
+    /**
+     * Returns a reference to the global configuration document.
+     * @return The global configuration document.
+     */
     public Document getConfig() {
         return config;
     }
 }
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactFactory.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultArtifactFactory.java	Fri Mar 26 17:59:50 2010 +0000
@@ -9,6 +9,12 @@
 import de.intevation.artifacts.ArtifactSerializer;
 
 /**
+ * Trivial implementation of the ArtifactFactory interface.
+ * Time to live (ttl), name and description are configured
+ * via the Node given to #setup(Document, Node) with attributes
+ * of same name. The class name of the artifacts to be build by this
+ * factory is configures with the attribute 'artifact'.
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class DefaultArtifactFactory
@@ -17,25 +23,60 @@
     private static Logger logger =
         Logger.getLogger(DefaultArtifactFactory.class);
 
+    /**
+     * XPath to access the TTL of this artifact.
+     */
     public static final String XPATH_TTL         = "@ttl";
+    /**
+     * XPath to access the name of this factory.
+     */
     public static final String XPATH_NAME        = "@name";
+    /**
+     * XPath to access the description of this artifact factory.
+     */
     public static final String XPATH_DESCRIPTION = "@description";
+    /**
+     * XPath to access the class name of the artifacts to be build
+     * by this factory.
+     */
     public static final String XPATH_ARTIFACT    = "@artifact";
 
+    /**
+     * Default description of this factory if none is given by the
+     * configuration.
+     */
     public static final String DEFAULT_DESCRIPTION =
         "No description available";
 
+    /**
+     * Class to load if no artifact class is given in the configuration.
+     */
     public static final String DEFAULT_ARTIFACT =
         "de.intevation.artifactdatabase.DefaultArtifact";
 
+    /**
+     * The Time to live of the artifacts build by this factory.
+     */
     protected Long   ttl;
 
+    /**
+     * The name of this factory.
+     */
     protected String name;
 
+    /**
+     * The description of this factory.
+     */
     protected String description;
 
+    /**
+     * The class of the artifacts to be build by this factory.
+     */
     protected Class  artifactClass;
 
+    /**
+     * Default constructor.
+     */
     public DefaultArtifactFactory() {
     }
 
@@ -47,10 +88,11 @@
         return description;
     }
 
-    public Artifact createArtifact(String identifier,
-                                   Object context,
-                                   Document data) {
-
+    public Artifact createArtifact(
+        String   identifier,
+        Object   context,
+        Document data
+    ) {
         try {
             Artifact artifact =
                 (Artifact)artifactClass.newInstance();
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultPreferredLocale.java	Fri Mar 26 17:59:50 2010 +0000
@@ -7,7 +7,7 @@
 /**
  * Models a pair of Locale and quality (0.0-1.0) to be used to
  * find best matching locale between server offerings and clients requests.
- * 
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class DefaultPreferredLocale
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultService.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultService.java	Fri Mar 26 17:59:50 2010 +0000
@@ -11,7 +11,7 @@
 /**
  * Trivial implementation of an artifact database service. Useful to
  * be subclassed.
- * 
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class DefaultService
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultServiceFactory.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/DefaultServiceFactory.java	Fri Mar 26 17:59:50 2010 +0000
@@ -14,7 +14,7 @@
  * #setup(Document, Node) via the 'name' and 'description' attributes.
  * The name of the class that provides the concrete serice is configured
  * by the 'service' attribute.
- * 
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class DefaultServiceFactory
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java	Fri Mar 26 16:16:32 2010 +0000
+++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ProxyArtifact.java	Fri Mar 26 17:59:50 2010 +0000
@@ -21,11 +21,11 @@
  * An inner artifact is able to replace itself by indirectly hand over
  * the replacement via the call context to the proxy artifact.<br>
  * To do so the proxied artifact has to call
- * <code>callContext.getContextValue(EPLACE_PROXY, replacement);</code>. 
+ * <code>callContext.getContextValue(EPLACE_PROXY, replacement);</code>.
  * After the current call (describe, feed, advance and out) of the proxied
  * artifact is finished the proxy artifact replaces the former proxied artifact
  * with the replacement.
- * 
+ *
  * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
  */
 public class ProxyArtifact

http://dive4elements.wald.intevation.org