Mercurial > dive4elements > framework
view artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java @ 75:d4c4c23847f5
Extended the Artifact-Interface-Method setup to be able to put the XML-Document which can contain further Data
to the Artifact-Implementation.
artifacts/trunk@649 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Mon, 01 Feb 2010 13:54:05 +0000 |
parents | ce488c1d3fc4 |
children | f69e5b87f05f |
line wrap: on
line source
package de.intevation.artifactdatabase; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import org.apache.log4j.Logger; import org.w3c.dom.Document; import de.intevation.artifactdatabase.Backend.PersistentArtifact; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactDatabase; import de.intevation.artifacts.ArtifactDatabaseException; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.CallContext; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.Service; import de.intevation.artifacts.ServiceFactory; /** * @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 static final String NO_SUCH_SERVICE = "No such service"; 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 ArtifactDatabase getDatabase() { return ArtifactDatabaseImpl.this; } 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 String [][] serviceNamesAndDescription; protected HashMap name2service; 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(); setupArtifactFactories(bootstrap); setupServices(bootstrap); context = bootstrap.getContext(); wireWithBackend(backend); } protected void setupArtifactFactories(FactoryBootstrap bootstrap) { 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); } } protected void setupServices(FactoryBootstrap bootstrap) { name2service = new HashMap(); ServiceFactory [] serviceFactories = bootstrap.getServiceFactories(); serviceNamesAndDescription = new String[serviceFactories.length][]; for (int i = 0; i < serviceFactories.length; ++i) { ServiceFactory factory = serviceFactories[i]; String name = factory.getName(); String description = factory.getDescription(); serviceNamesAndDescription[i] = new String [] { name, description }; name2service.put( name, factory.createService(bootstrap.getContext())); } } 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 getInternalArtifactFactory(String factoryName) { return getArtifactFactory(factoryName); } public ArtifactFactory getArtifactFactory(String factoryName) { return (ArtifactFactory)name2factory.get(factoryName); } public Document createArtifactWithFactory( String factoryName, CallMeta callMeta, Document data ) throws ArtifactDatabaseException { ArtifactFactory factory = getArtifactFactory(factoryName); if (factory == null) { throw new ArtifactDatabaseException(NO_SUCH_FACTORY); } Artifact artifact = factory.createArtifact( backend.newIdentifier(), context, data); 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); } public String [][] serviceNamesAndDescriptions() { return serviceNamesAndDescription; } public Document process( String serviceName, Document input, CallMeta callMeta ) throws ArtifactDatabaseException { Service service = (Service)name2service.get(serviceName); if (service == null) { throw new ArtifactDatabaseException(NO_SUCH_SERVICE); } return service.process(input, context, callMeta); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: