Mercurial > dive4elements > framework
diff artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java @ 80:8447467cef86
Implementation to import artifacts from incoming xml documents (applied patch from issue208 by SLT).
artifacts/trunk@799 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Fri, 19 Mar 2010 09:34:40 +0000 |
parents | f69e5b87f05f |
children | e9c80fdfee13 |
line wrap: on
line diff
--- a/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java Tue Mar 16 16:03:06 2010 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/ArtifactDatabaseImpl.java Fri Mar 19 09:34:40 2010 +0000 @@ -7,6 +7,7 @@ import de.intevation.artifacts.ArtifactDatabaseException; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.ArtifactSerializer; import de.intevation.artifacts.CallContext; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.Service; @@ -19,11 +20,13 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; import org.apache.log4j.Logger; @@ -31,7 +34,7 @@ import org.w3c.dom.Element; /** - * @author Sascha L. Teichmann + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> */ public class ArtifactDatabaseImpl implements ArtifactDatabase, Id.Filter, Backend.FactoryLookup @@ -63,6 +66,27 @@ public static final String DIGEST_ALGORITHM = "SHA-1"; + public static final String XPATH_IMPORT_CHECKSUM = + "/art:action/art:data/@checksum"; + + public static final String XPATH_IMPORT_FACTORY = + "/art:action/art:data/@factory"; + + public static final String XPATH_IMPORT_DATA = + "/art:action/art:data/text()"; + + public static final String INVALID_CHECKSUM = + "Invalid checksum"; + + public static final String CHECKSUM_MISMATCH = + "Mismatching checksum"; + + public static final String NO_DATA = + "No data"; + + public static final String INVALID_ARTIFACT = + "Invalid artifact"; + public class CallContextImpl implements CallContext { @@ -485,14 +509,14 @@ md.update(artifact); md.update(secret); - String checksum = StringUtils.toHex(md.digest()); + String checksum = Hex.encodeHexString(md.digest()); XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator( document, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); - Element root = ec.create("result"); + Element root = ec.create("action"); document.appendChild(root); Element type = ec.create("type"); @@ -501,6 +525,7 @@ Element data = ec.create("data"); ec.addAttr(data, "checksum", checksum); + ec.addAttr(data, "factory", factoryName); data.setTextContent(Base64.encodeBase64String(artifact)); root.appendChild(data); @@ -508,10 +533,100 @@ return document; } - public Document importArtifact(Document data, CallMeta callMeta) + public Document importArtifact(Document input, CallMeta callMeta) throws ArtifactDatabaseException { - return null; + String factoryName = XMLUtils.xpathString( + input, + XPATH_IMPORT_FACTORY, + ArtifactNamespaceContext.INSTANCE); + + ArtifactFactory factory; + + if (factoryName == null + || (factoryName = factoryName.trim()).length() == 0 + || (factory = getArtifactFactory(factoryName)) == null) { + throw new ArtifactDatabaseException(NO_SUCH_FACTORY); + } + + String checksumString = XMLUtils.xpathString( + input, + XPATH_IMPORT_CHECKSUM, + ArtifactNamespaceContext.INSTANCE); + + byte [] checksum; + + if (checksumString == null + || (checksumString = checksumString.trim()).length() == 0 + || (checksum = StringUtils.decodeHex(checksumString)) == null + ) { + throw new ArtifactDatabaseException(INVALID_CHECKSUM); + } + + checksumString = null; + + String dataString = XMLUtils.xpathString( + input, + XPATH_IMPORT_DATA, + ArtifactNamespaceContext.INSTANCE); + + if (dataString == null + || (dataString = dataString.trim()).length() == 0) { + throw new ArtifactDatabaseException(NO_DATA); + } + + byte [] data = Base64.decodeBase64(dataString); + + dataString = null; + + MessageDigest md; + try { + md = MessageDigest.getInstance(DIGEST_ALGORITHM); + } + catch (NoSuchAlgorithmException nsae) { + logger.error(nsae.getLocalizedMessage(), nsae); + return XMLUtils.newDocument(); + } + + md.update(data); + md.update(exportSecret); + + byte [] digest = md.digest(); + + if (!Arrays.equals(checksum, digest)) { + throw new ArtifactDatabaseException(CHECKSUM_MISMATCH); + } + + ArtifactSerializer serializer = factory.getSerializer(); + + Artifact artifact = serializer.fromBytes(data); data = null; + + if (artifact == null) { + throw new ArtifactDatabaseException(INVALID_ARTIFACT); + } + + PersistentArtifact persistentArtifact; + + try { + persistentArtifact = backend.storeOrReplace( + 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(input, cc); + } + finally { + cc.postCall(); + } } public String [][] serviceNamesAndDescriptions() {