Mercurial > dive4elements > framework
view artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java @ 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 | 9a29899b31e5 |
children | 89e3de0ee05f |
line wrap: on
line source
package de.intevation.artifactdatabase; import java.util.HashMap; import java.util.HashSet; import java.util.ArrayList; import java.util.List; import de.intevation.artifacts.ArtifactDatabaseException; import de.intevation.artifacts.ArtifactDatabase; 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; import org.apache.log4j.Logger; import org.w3c.dom.Document; import java.io.OutputStream; import java.io.IOException; /** * @author Sascha L. Teichmann */ public class ArtifactDatabaseImpl implements ArtifactDatabase, Id.Filter, Backend.FactoryLookup { private static Logger logger = Logger.getLogger(ArtifactDatabaseImpl.class); public static final String NO_SUCH_FACTORY = "No such factory"; public static final String NO_SUCH_ARTIFACT = "No such artifact"; public static final String NOT_IN_BACKGROUND = "Not in background"; public static final String INVALID_CALL_STATE = "Invalid after call state"; public static final String CREATION_FAILED = "Creation of artifact failed"; public static final String INTERNAL_ERROR = "Creation of artifact failed"; public class CallContextImpl implements CallContext { protected PersistentArtifact artifact; protected int action; protected CallMeta callMeta; protected HashMap customValues; public CallContextImpl( PersistentArtifact artifact, int action, CallMeta callMeta ) { this.artifact = artifact; this.action = action; this.callMeta = callMeta; } public void afterCall(int action) { this.action = action; if (action == BACKGROUND) { addIdToBackground(artifact.getId()); } } public void afterBackground(int action) { if (this.action != BACKGROUND) { throw new IllegalStateException(NOT_IN_BACKGROUND); } fromBackground(artifact, action); } public Object globalContext() { return context; } public CallMeta getMeta() { return callMeta; } public void postCall() { switch (action) { case NOTHING: break; case TOUCH: artifact.touch(); break; case STORE: artifact.store(); break; case BACKGROUND: logger.warn("BACKGROUND processing is not fully implemented, yet!"); artifact.store(); break; default: logger.error(INVALID_CALL_STATE + ": " + action); 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 implements DeferredOutput { protected PersistentArtifact artifact; protected Document format; protected CallMeta callMeta; public DeferredOutputImpl() { } public DeferredOutputImpl( PersistentArtifact artifact, 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, callMeta); try { artifact.getArtifact().out(format, output, cc); } finally { cc.postCall(); } } } // class DeferredOutputImpl protected String [][] factoryNamesAndDescription; protected HashMap name2factory; protected Backend backend; protected Object context; protected HashSet backgroundIds; public ArtifactDatabaseImpl() { } public ArtifactDatabaseImpl(FactoryBootstrap bootstrap) { this(bootstrap, null); } public ArtifactDatabaseImpl(FactoryBootstrap bootstrap, Backend backend) { backgroundIds = new HashSet(); name2factory = new HashMap(); ArtifactFactory [] factories = bootstrap.getArtifactFactories(); factoryNamesAndDescription = new String[factories.length][]; for (int i = 0; i < factories.length; ++i) { ArtifactFactory factory = factories[i]; String name = factory.getName(); String description = factory.getDescription(); factoryNamesAndDescription[i] = new String [] { name, description }; name2factory.put(name, factory); } context = bootstrap.getContext(); wireWithBackend(backend); } public void wireWithBackend(Backend backend) { if (backend != null) { this.backend = backend; backend.setFactoryLookup(this); } } protected void fromBackground(PersistentArtifact artifact, int action) { logger.warn("BACKGROUND processing is not fully implemented, yet!"); switch (action) { case CallContext.NOTHING: break; case CallContext.TOUCH: artifact.touch(); break; case CallContext.STORE: artifact.store(); break; default: logger.warn("operation not allowed in fromBackground"); } removeIdFromBackground(artifact.getId()); } protected void removeIdFromBackground(int id) { synchronized (backgroundIds) { backgroundIds.remove(Integer.valueOf(id)); } } protected void addIdToBackground(int id) { synchronized (backgroundIds) { backgroundIds.add(Integer.valueOf(id)); } } public List filterIds(List ids) { int N = ids.size(); ArrayList out = new ArrayList(N); synchronized (backgroundIds) { for (int i = 0; i < N; ++i) { Id id = (Id)ids.get(i); if (!backgroundIds.contains(Integer.valueOf(id.getId()))) { out.add(id); } } } return out; } public String [][] artifactFactoryNamesAndDescriptions() { return factoryNamesAndDescription; } public ArtifactFactory getArtifactFactory(String factoryName) { return (ArtifactFactory)name2factory.get(factoryName); } public Document createArtifactWithFactory( String factoryName, CallMeta callMeta ) throws ArtifactDatabaseException { ArtifactFactory factory = getArtifactFactory(factoryName); if (factory == null) { throw new ArtifactDatabaseException(NO_SUCH_FACTORY); } Artifact artifact = factory.createArtifact( backend.newIdentifier(), context); if (artifact == null) { throw new ArtifactDatabaseException(CREATION_FAILED); } PersistentArtifact persistentArtifact; try { persistentArtifact = backend.storeInitially( artifact, factory, factory.timeToLiveUntouched(artifact, context)); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); throw new ArtifactDatabaseException(CREATION_FAILED); } CallContextImpl cc = new CallContextImpl( persistentArtifact, CallContext.NOTHING, callMeta); try { return artifact.describe(null, cc); } finally { cc.postCall(); } } public Document describe(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.TOUCH, callMeta); try { return artifact.getArtifact().describe(data, cc); } finally { cc.postCall(); } } public Document advance(String identifier, Document target, 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().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); } finally { cc.postCall(); } } public DeferredOutput out(String identifier, Document format, CallMeta callMeta) throws ArtifactDatabaseException { // TODO: Handle background tasks PersistentArtifact artifact = backend.getArtifact(identifier); if (artifact == null) { throw new ArtifactDatabaseException(NO_SUCH_ARTIFACT); } return new DeferredOutputImpl(artifact, format, callMeta); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: