Commits

Sam Adams  committed 3aea4a0

Refactoring chemical importers to share more code

  • Participants
  • Parent commits 97efdfe

Comments (0)

Files changed (8)

File compchem-handler/src/main/java/net/chempound/compchem/display/CompChemSplashPageWriter.java

 import net.chempound.compchem.rdf.CompChemCalculation;
 import net.chempound.rdf.CPTerms;
 import net.chempound.services.FreemarkerService;
+import net.chempound.webapp.output.AbstractSplashPageWriter;
 import net.chempound.webapp.output.SplashPageWriter;
 import org.apache.commons.io.IOUtils;
 
 /**
  * @author Sam Adams
  */
-public class CompChemSplashPageWriter implements SplashPageWriter {
+public class CompChemSplashPageWriter extends AbstractSplashPageWriter {
 
     private static final String style;
     private static final String headers;
         }
     }
 
-    private final FreemarkerService freemarker;
-
     @Inject
     public CompChemSplashPageWriter(final FreemarkerService freemarker) {
-        this.freemarker = freemarker;
+        super(freemarker);
+    }
+
+    @Override
+    protected Class<? extends Resource> getResourceType() {
+        return CompChemCalculation.class;
+    }
+
+    @Override
+    protected String getTemplateName() {
+        return "/plugins/compchem/comp.ftl";
     }
 
     @Override
     public String write(final Model model, final URI aggregationUri, final Map<String, Object> map) throws IOException, TemplateException {
-
         map.put("style", style);
         map.put("headers", headers);
 
-        final Map<String,Object> o = new HashMap<String, Object>();
-
-        final Resource r = model.getResource(aggregationUri.toString());
-
-        final CompChemCalculation entry = r.as(CompChemCalculation.class);
-
         final BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
         final TemplateHashModel staticModels = wrapper.getStaticModels();
 
-        o.put("uri", aggregationUri.toString());
+        final Resource r = model.getResource(aggregationUri.toString());
+        final CompChemCalculation entry = r.as(CompChemCalculation.class);
 
-        o.put("calculation", new BeanModel(entry, wrapper));
+        map.put("uri", aggregationUri.toString());
 
-        o.put("CP", staticModels.get(CPTerms.class.getName()));
-        o.put("DC", staticModels.get(DCTerms.class.getName()));
+        map.put("calculation", new BeanModel(entry, wrapper));
 
-        final StringWriter buffer = new StringWriter();
+        map.put("CP", staticModels.get(CPTerms.class.getName()));
+        map.put("DC", staticModels.get(DCTerms.class.getName()));
 
-        final Template template = freemarker.getTemplate("/plugins/compchem/comp.ftl");
-        template.process(o, buffer);
-
-        return buffer.toString();
+        return super.write(model, aggregationUri, map);
     }
 
 }

File compchem-importer/src/main/java/net/chempound/compchem/CmlComp2RdfConverter.java

         // TODO - handle mult job deposits; here we just assume we want the final job
         for (final CMLModule job : jobs) {
 
-            final Elements modules = job.getChildCMLElements("module");
-            final Multimap<String, CMLModule> dictMap = generateDictRefMap(modules, CMLModule.class);
-            for (final String s : dictMap.keys()) {
-                LOG.debug("module: " + s);
-            }
+            final Multimap<String, CMLModule> modules = generateDictRefMap(job.getChildCMLElements("module"), CMLModule.class);
 
-            final CMLModule initialisation = Iterables.getLast(dictMap.get(CMLCOMP_INITIALIZATION));
-            final CMLModule environment = Iterables.getLast(dictMap.get(CMLCOMP_ENVIRONMENT));
-            final CMLModule finalization = Iterables.getLast(dictMap.get(CMLCOMP_FINALIZATION));
+            final CMLModule initialisation = Iterables.getLast(modules.get(CMLCOMP_INITIALIZATION));
+            final CMLModule environment = Iterables.getLast(modules.get(CMLCOMP_ENVIRONMENT));
+            final CMLModule finalization = Iterables.getLast(modules.get(CMLCOMP_FINALIZATION));
 
             final List<CMLParameter> envParams = findCmlParameters(environment);
+            addParameters(model, thisCalculation, envParams);
+
             final List<CMLParameter> initParams = findCmlParameters(initialisation);
+            addParameters(model, thisCalculation, initParams);
+
             final List<CMLProperty> properties = findCmlProperties(finalization);
-
-            addParameters(model, thisCalculation, envParams);
-            addParameters(model, thisCalculation, initParams);
             addCmlProperties(model, thisCalculation, properties);
 
             if (finalization.query("cml:molecule/cml:atomArray/cml:atom/cml:property[@dictRef = 'cc:mulliken']", CML_XPATH).size() != 0) {
                 thisCalculation.addLiteral(CompChem.hasMullikenPops, true);
             }
-
         }
 
         // Find molecule
                 LOG.debug("module: " + s);
             }
 
-            final CMLModule initialisation = Iterables.getLast(dictMap.get(CMLCOMP_INITIALIZATION));
-            final CMLModule finalization = Iterables.getLast(dictMap.get(CMLCOMP_FINALIZATION));
-
-            CMLMolecule parentMol = (CMLMolecule) finalization.getFirstCMLChild("molecule");
-            if (parentMol == null) {
-                parentMol = (CMLMolecule) initialisation.getFirstCMLChild("molecule");
-            }
-            if (parentMol != null) {
+            final CMLMolecule molecule = findMolecule(dictMap);
+            if (molecule != null) {
                 final Resource thisMolecule = model.createResource("#molecule", CmlRdf.MolecularEntity);
-                attachIdentifiers(thisMolecule, model, parentMol);
-                attachFormula(thisMolecule, model, parentMol);
+                attachIdentifiers(thisMolecule, model, molecule);
+                attachFormula(thisMolecule, model, molecule);
                 thisCalculation.addProperty(CmlRdf.aboutMolecule, thisMolecule);
             }
             break;
 
     }
 
+    private CMLMolecule findMolecule(final Multimap<String, CMLModule> dictMap) {
+        final CMLModule initialisation = Iterables.getLast(dictMap.get(CMLCOMP_INITIALIZATION));
+        final CMLModule finalization = Iterables.getLast(dictMap.get(CMLCOMP_FINALIZATION));
+
+        CMLMolecule molecule = (CMLMolecule) finalization.getFirstCMLChild("molecule");
+        if (molecule == null) {
+            molecule = (CMLMolecule) initialisation.getFirstCMLChild("molecule");
+        }
+        return molecule;
+    }
+
     private void attachFormula(final Resource thisMolecule, final Model model, final CMLMolecule parentMol) {
         final Nodes nodes = parentMol.query("./cml:formula/@concise", CML_XPATH);
         if (nodes.size() != 0) {
         if ("daylight:smiles".equals(convention)) {
             return CmlRdf.smiles;
         }
-        return null;
+        throw new IllegalArgumentException("Unsupported identifer: "+convention);
     }
 
 }

File compchem-importer/src/main/java/net/chempound/compchem/CompChemImporter.java

 import net.chempound.rdf.DCTerms;
 import net.chempound.rdf.chempound.ChempoundAggregation;
 import net.chempound.storage.DepositResource;
+import net.chempound.storage.LocalResource;
 import nu.xom.Document;
 import nu.xom.Node;
 import nu.xom.Nodes;
-import org.apache.commons.io.FileUtils;
 import org.xmlcml.cml.base.CMLConstants;
 import org.xmlcml.cml.base.CMLUtil;
 import org.xmlcml.cml.element.CMLModule;
 import org.xmlcml.cml.element.CMLMolecule;
 
 import javax.inject.Inject;
-import java.io.File;
 import java.io.IOException;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.List;
 
 import static org.xmlcml.cml.base.CMLConstants.CML_XPATH;
 
 public class CompChemImporter extends CmlImporter {
 
-    private final ImageGenerator imageGenerator;
-    private final InChIGenerator inchiGenerator;
+    private String id;
 
-    private String id;
+    protected LocalResource cmlResource;
 
     @Inject
     public CompChemImporter(final ImageGenerator imageGenerator, final InChIGenerator inchiGenerator) {
-        this.imageGenerator = imageGenerator;
-        this.inchiGenerator = inchiGenerator;
+        super(imageGenerator, inchiGenerator);
     }
 
-
     public String getId() {
         return id;
     }
         this.id = id;
     }
 
+    public DepositRequest generateDepositRequest() throws Exception {
+        final Document doc = generateCml();
+        return generateDepositRequest(doc);
+    }
 
-    protected DepositRequest generateLoadRequest(final List<DepositResource> resources, final Document doc) throws Exception {
-        final DepositRequest loadRequest = new DefaultDepositRequest();
-        loadRequest.setSlug(getId());
+    public DepositRequest generateDepositRequest(final Document doc) throws Exception {
+        final String cmlPath = getId() == null ? "output.cml" : getId() + ".cml";
+        cmlResource = createCmlResource(doc, cmlPath);
+
+        final List<DepositResource> resources = new ArrayList<DepositResource>();
+        addResources(resources);
+
+        final DepositRequest request = generateLoadRequest(doc, resources);
+        return request;
+    }
+
+    protected void addResources(final List<DepositResource> resources) {
+        resources.add(cmlResource);
+    }
+
+    protected Document generateCml() throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    private DepositRequest generateLoadRequest(final Document doc, final List<DepositResource> resources) throws Exception {
+        final DepositRequest depositRequest = new DefaultDepositRequest();
+        depositRequest.setSlug(getId());
         for (final DepositResource resource : resources) {
-            loadRequest.addResource(resource);
+            depositRequest.addResource(resource);
         }
 
         final CMLModule jobList = getJobList(doc);
         final CmlComp2RdfConverter converter = new CmlComp2RdfConverter();
         final Model model = converter.generateModel(jobList, URI.create(""));
 
-        loadRequest.getMetadataModel().add(model);
+        final LocalResource rdfResource = writeRdf(getId()+".rdf", model);
+        depositRequest.addResource(rdfResource);
 
         createImageResources(doc, getId());
 
-        final ChempoundAggregation item = loadRequest.getResourceMetadata();
-        addResources(loadRequest, item);
+        final ChempoundAggregation item = depositRequest.getResourceMetadata();
+//        addResources(depositRequest, item);
+        attachImages(depositRequest);
 
         addType(item);
 
-        return loadRequest;
+        return depositRequest;
     }
 
     protected void addResources(final DepositRequest loadRequest, final ChempoundAggregation item) {
     }
 
     protected void createImageResources(final Document doc, final String id) throws IOException {
-        final File imageFile = File.createTempFile("image", "png");
-        try {
-            final File thumbnailFile = File.createTempFile("image_tn", "png");
-            try {
-                final List<Node> nodes = CMLUtil.getQueryNodes(doc, "//cml:module[@dictRef='cc:initialization' or @dictRef='cc:finalization']/cml:molecule", CML_XPATH);
-                if (nodes.isEmpty()) {
-                    System.err.println("**\n**\n** No molecule found!\n**\n**\n**");
-                    throw new RuntimeException("No molecule found!");
-                }
-                final CMLMolecule mol = (CMLMolecule) nodes.get(nodes.size()-1);
-                imageGenerator.createImages(mol, imageFile, thumbnailFile);
-                imageResource = createImageResource(imageFile, id + ".png");
-                thumbnailResource = createImageResource(thumbnailFile, id + "_tn.png");
-            } finally {
-                FileUtils.deleteQuietly(thumbnailFile);
-            }
-        } finally {
-            FileUtils.deleteQuietly(imageFile);
+        final List<Node> nodes = CMLUtil.getQueryNodes(doc, "//cml:module[@dictRef='cc:initialization' or @dictRef='cc:finalization']/cml:molecule", CML_XPATH);
+        if (nodes.isEmpty()) {
+            System.err.println("**\n**\n** No molecule found!\n**\n**\n**");
+            throw new RuntimeException("No molecule found!");
         }
+        createImages((CMLMolecule) nodes.get(nodes.size() - 1), id);
     }
 
     protected void addType(final ChempoundAggregation item) {
         item.addProperty(DCTerms.type, type);
     }
 
-    protected void attachIdentifiers(final CMLMolecule molecule) {
-        inchiGenerator.attachIdentifiers(molecule);
-    }
-
 }

File compchem-importer/src/main/java/net/chempound/compchem/GaussianLogImporter.java

 import net.chempound.chemistry.InChIGenerator;
 import net.chempound.chemistry.cml.ChemicalMime;
 import net.chempound.compchem.rdf.ont.CompChem;
-import net.chempound.content.DepositRequest;
 import net.chempound.rdf.DCTerms;
 import net.chempound.rdf.chempound.ChempoundAggregation;
 import net.chempound.storage.DepositResource;
 import nu.xom.Document;
 import nu.xom.Element;
 import nu.xom.Node;
-import nu.xom.ParsingException;
 import org.apache.commons.io.IOUtils;
 import org.xmlcml.cml.base.CMLUtil;
 import org.xmlcml.cml.converters.compchem.gaussian.log.GaussianLog2XMLConverter;
 
 import javax.inject.Inject;
 import java.io.*;
-import java.util.ArrayList;
 import java.util.List;
 
 import static org.xmlcml.cml.base.CMLConstants.CML_XPATH;
 
     protected LocalResource inputFile;
     protected LocalResource logFile;
-    protected LocalResource cmlResource;
 
     public GaussianLogImporter() {
         this(new ImageGenerator(), new InChIGenerator());
     public void setInputFile(final File file, final String path) throws IOException {
         final BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
         try {
-            inputFile = new InMemoryResource(path, ChemicalMime.CHEMICAL_GAUSSIAN_INPUT, in);
+            setInputFile(in, path);
         } finally {
             IOUtils.closeQuietly(in);
         }
     public void setLogFile(final File file, final String path) throws IOException {
         final BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
         try {
-            logFile = new InMemoryResource(path, ChemicalMime.CHEMICAL_GAUSSIAN_LOG, in);
+            setLogFile(in, path);
         } finally {
             IOUtils.closeQuietly(in);
         }
     }
 
-
-    public DepositRequest generateDepositRequest() throws Exception {
+    @Override
+    protected Document generateCml() throws Exception {
         if (logFile == null) {
             throw new IllegalStateException("Logfile must be specifed");
         }
 
-        final Document doc = generateCml();
+        final Element cml = convertLogToCml(logFile);
+        final Document doc = reloadCml(cml);
+        List<Node> molecules = CMLUtil.getQueryNodes(doc, "//cml:molecule", CML_XPATH);
+        for (final Node node : molecules) {
+            attachIdentifiers((CMLMolecule) node);
+        }
+        return doc;
+    }
 
-        final String cmlPath = getId() == null ? "output.cml" : getId() + ".cml";
-        cmlResource = createCmlResource(doc, cmlPath);
-
-        final List<DepositResource> resources = new ArrayList<DepositResource>();
+    @Override
+    protected void addResources(final List<DepositResource> resources) {
         if (inputFile != null) {
             resources.add(inputFile);
         }
         resources.add(logFile);
-        resources.add(cmlResource);
-
-        final DepositRequest request = super.generateLoadRequest(resources, doc);
-
-        return request;
-    }
-
-    protected Document generateCml() throws IOException, ParsingException {
-        final Element cml = convertLogToCml(logFile);
-        final Document doc = reloadCml(cml);
-        for (final Node node : CMLUtil.getQueryNodes(doc, "//cml:molecule", CML_XPATH)) {
-            attachIdentifiers((CMLMolecule) node);
-        }
-        return doc;
+        super.addResources(resources);
     }
 
     @Override
     }
 
 
-    protected Element convertLogToCml(final LocalResource logFile) throws IOException {
+    private Element convertLogToCml(final LocalResource logFile) throws IOException {
         final InputStream in = logFile.openInputStream();
         try {
             return convertLogToCml(in);
         }
     }
 
-    protected Element convertLogToCml(final InputStream in) {
+    private Element convertLogToCml(final InputStream in) {
         final Element xml = convertLogToXml(in);
         final GaussianLogXML2CompchemConverter converter = new GaussianLogXML2CompchemConverter();
         return converter.convertToXML(xml);

File compchem-importer/src/main/java/net/chempound/compchem/NWChemLogImporter.java

 import net.chempound.chemistry.cml.ChemicalMime;
 import net.chempound.chemistry.inchi.InchiTool;
 import net.chempound.compchem.rdf.ont.CompChem;
-import net.chempound.content.DepositRequest;
 import net.chempound.rdf.DCTerms;
 import net.chempound.rdf.chempound.ChempoundAggregation;
 import net.chempound.storage.DepositResource;
 
 import javax.inject.Inject;
 import java.io.*;
-import java.util.ArrayList;
 import java.util.List;
 
 /**
 
     protected LocalResource inputFile;
     protected LocalResource logFile;
-    protected LocalResource cmlResource;
 
     public NWChemLogImporter() {
         this(new ImageGenerator(), new InChIGenerator());
     public void setInputFile(final File file, final String path) throws IOException {
         final BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
         try {
-            inputFile = new InMemoryResource(path, ChemicalMime.CHEMICAL_NWCHEM, in);
+            setInputFile(in, path);
         } finally {
             IOUtils.closeQuietly(in);
         }
     public void setLogFile(final File file, final String path) throws IOException {
         final BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
         try {
-            logFile = new InMemoryResource(path, ChemicalMime.CHEMICAL_NWCHEM, in);
+            setLogFile(in, path);
         } finally {
             IOUtils.closeQuietly(in);
         }
     }
 
 
-    public DepositRequest generateDepositRequest() throws Exception {
-        if (logFile == null) {
-            throw new IllegalStateException("Logfile must be specifed");
-        }
-
-        final Document doc = generateCml();
-
-        final String cmlPath = getId() == null ? "output.cml" : getId() + ".cml";
-        cmlResource = createCmlResource(doc, cmlPath);
-
-        final List<DepositResource> resources = new ArrayList<DepositResource>();
-        if (inputFile != null) {
-            resources.add(inputFile);
-        }
-        resources.add(logFile);
-        resources.add(cmlResource);
-
-        final DepositRequest request = super.generateLoadRequest(resources, doc);
-
-        return request;
-    }
-
+    @Override
     protected Document generateCml() throws IOException, ParsingException {
         final Element cml = convertLogToCml(logFile);
         final Document doc = reloadCml(cml);
     }
 
     @Override
+    protected void addResources(final List<DepositResource> resources) {
+        if (inputFile != null) {
+            resources.add(inputFile);
+        }
+        resources.add(logFile);
+        super.addResources(resources);
+    }
+
+    @Override
     protected void addType(final ChempoundAggregation item) {
         final Resource compChemType = item.getModel().getResource(CompChem.Calculation.getURI());
         item.addProperty(DCTerms.type, compChemType);
     }
 
 
-    protected Element convertLogToCml(final LocalResource logFile) throws IOException {
+    private Element convertLogToCml(final LocalResource logFile) throws IOException {
         final InputStream in = logFile.openInputStream();
         try {
             return convertLogToCml(in);
         }
     }
 
-    protected Element convertLogToCml(final InputStream in) {
+    private Element convertLogToCml(final InputStream in) {
         final Element xml = convertLogToXml(in);
         final NWChemLogXML2CompchemConverter converter = new NWChemLogXML2CompchemConverter();
         return converter.convertToXML(xml);

File compchem-importer/src/test/java/net/chempound/compchem/GaussianImporterTest.java

 package net.chempound.compchem;
 
+import com.hp.hpl.jena.rdf.arp.JenaReader;
 import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.RDFReader;
 import net.chempound.chemistry.ImageGenerator;
 import net.chempound.chemistry.InChIGenerator;
 import net.chempound.compchem.rdf.CompChemCalculation;
 import net.chempound.compchem.rdf.CompChemPersonalities;
 import net.chempound.content.DepositRequest;
 import net.chempound.rdf.ChempoundPersonalities;
+import net.chempound.rdf.IgnoringEmptyBaseUriErrorHandler;
+import net.chempound.storage.DepositResource;
+import net.chempound.util.MimeType;
+import org.apache.commons.io.IOUtils;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.io.IOException;
 import java.io.InputStream;
 
 import static org.junit.Assert.assertEquals;
         importer.setLogFile(in, "output.log");
         DepositRequest request = importer.generateDepositRequest();
 
-        Model model = request.getMetadataModel();
+        Model model = getRdfModel(request);
         CompChemCalculation calc = model.getResource("").as(CompChemCalculation.class);
 
         assertEquals("Gaussian 03", calc.getPackageName());
 
     }
 
+    private Model getRdfModel(final DepositRequest request) throws IOException {
+        for (final DepositResource resource : request.getAggregatedResources()) {
+            if (MimeType.APPLICATION_RDF_XML.equals(resource.getMimeType())) {
+                return loadRdf(resource);
+            }
+        }
+        return null;
+    }
+
+    private Model loadRdf(final DepositResource resource) throws IOException {
+        final InputStream in = resource.openInputStream();
+        try {
+            final RDFReader reader = new JenaReader();
+            reader.setErrorHandler(new IgnoringEmptyBaseUriErrorHandler());
+
+            final Model model = ModelFactory.createDefaultModel();
+            reader.read(model, in, "");
+
+            return model;
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
 }

File compchem-test-harness/pom.xml

         </dependency>
 
         <dependency>
+            <groupId>net.chempound.chemistry</groupId>
+            <artifactId>chemistry-import-testutils</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>net.chempound.compchem</groupId>
             <artifactId>compchem-handler</artifactId>
             <scope>test</scope>

File compchem-test-harness/src/test/java/net/chempound/compchem/CompChemIntegrationTest.java

 import net.chempound.DefaultChempoundModule;
 import net.chempound.chemistry.ImageGenerator;
 import net.chempound.chemistry.InChIGenerator;
+import net.chempound.chemistry.testutil.ImageGeneratorStubber;
 import net.chempound.config.BaseUri;
 import net.chempound.config.ChempoundConfiguration;
 import net.chempound.config.DefaultChempoundConfiguration;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.restlet.*;
 import org.restlet.data.Method;
 import org.restlet.data.Protocol;
 import org.restlet.data.Status;
 import org.swordapp.client.*;
+import org.xmlcml.cml.element.CMLIdentifier;
+import org.xmlcml.cml.element.CMLMolecule;
 
 import java.io.*;
 import java.net.URI;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
+import static net.chempound.chemistry.testutil.ImageGeneratorStubber.stubImageGenerator;
 import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 /**
  * @author sea36
     @Before
     public void init() throws Exception {
 
-        imageGenerator = mock(ImageGenerator.class);
+        imageGenerator = stubImageGenerator();
         inchiGenerator = mock(InChIGenerator.class);
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(final InvocationOnMock invocation) throws Throwable {
+                final CMLMolecule molecule = (CMLMolecule) invocation.getArguments()[0];
+
+                final CMLIdentifier inchi = new CMLIdentifier();
+                inchi.setConvention("iupac:inchi");
+                inchi.setCMLValue("InChI=1/TEST");
+                molecule.appendChild(inchi);
+
+                final CMLIdentifier inchiKey = new CMLIdentifier();
+                inchiKey.setConvention("iupac:inchiKey");
+                inchiKey.setCMLValue("TEST-TEST");
+                molecule.appendChild(inchiKey);
+
+                return null;
+            }
+        }).when(inchiGenerator).attachIdentifiers(any(CMLMolecule.class));
 
         workspace = createWorkspace();