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() {

http://dive4elements.wald.intevation.org