Sam Adams avatar Sam Adams committed 45cfc44

Migrated to packages to chempound.net

Comments (0)

Files changed (241)

chemistry-common/pom.xml

     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>uk.ac.cam.ch.wwmm.chempound.chemistry</groupId>
+        <groupId>net.chempound.chemistry</groupId>
         <artifactId>chemistry</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
     <dependencies>
 
         <dependency>
-            <groupId>uk.ac.cam.ch.wwmm.chempound</groupId>
+            <groupId>net.chempound</groupId>
             <artifactId>chempound-rdf-cml</artifactId>
         </dependency>
 

chemistry-common/src/main/java/net/chempound/chemistry/Cml2RdfConverter.java

+package net.chempound.chemistry;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.hp.hpl.jena.rdf.model.*;
+import nu.xom.Element;
+import nu.xom.Elements;
+import nu.xom.Node;
+import org.xmlcml.cml.base.CMLConstants;
+import org.xmlcml.cml.base.CMLElement;
+import org.xmlcml.cml.base.CMLUtil;
+import org.xmlcml.cml.element.CMLParameter;
+import org.xmlcml.cml.element.CMLProperty;
+import org.xmlcml.cml.element.CMLScalar;
+import org.xmlcml.cml.interfacex.HasDictRef;
+
+import javax.xml.namespace.QName;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Sam Adams
+ */
+public class Cml2RdfConverter {
+
+    protected void addParameters(final Model model, final Resource parentNode, final List<CMLParameter> parameters) {
+        for (final CMLParameter parameter : parameters) {
+            final QName dictRef = getDictRefUri(parameter);
+
+            final Property prop = getProperty(model, dictRef);
+            final CMLScalar scalar = (CMLScalar) parameter.getFirstCMLChild(CMLScalar.TAG);
+            if (scalar != null) {
+                final RDFNode rdfNode = CmlRdfUtils.createResource(scalar, model);
+                if (rdfNode.isResource()) {
+                    // Ignore duplicate complex types
+                    if (parentNode.hasProperty(prop)) {
+                        continue;
+                    }
+                }
+                parentNode.addProperty(prop, rdfNode);
+            }
+        }
+    }
+
+    protected void addCmlProperties(final Model model, final Resource resource, final List<CMLProperty> nodes) {
+        for (final CMLProperty property : nodes) {
+            final Elements elements = property.getChildElements();
+            if (elements.size() == 1) {
+                final Element child = elements.get(0);
+                addProperty(model, resource, property, child);
+            }
+        }
+    }
+
+    protected void addProperty(final Model model, final Resource resource, final CMLProperty property, final Element value) {
+        if (value instanceof CMLScalar) {
+            final QName dictRef = getDictRefUri(property);
+            if (dictRef != null) {
+                final Property prop = getProperty(model, dictRef);
+                addScalar(model, resource, prop, (CMLScalar) value);
+            } else {
+                System.err.println("** Missing dictRef **");
+                System.err.println(property.toXML());
+                System.err.println("*********************");
+            }
+        } else {
+            final QName dictRef = getDictRefUri(property);
+            if (dictRef != null) {
+                final Property prop = getHasProperty(model, dictRef);
+                resource.addLiteral(prop, true);
+            } else {
+                System.err.println("** Missing dictRef **");
+                System.err.println(property.toXML());
+                System.err.println("*********************");
+            }
+        }
+    }
+
+
+    protected void addScalar(final Model model, final Resource resource, final Property property, final CMLScalar value) {
+        final RDFNode rdfNode = createScalarValueResource(model, property, value);
+        resource.addProperty(property, rdfNode);
+    }
+
+    protected RDFNode createScalarValueResource(final Model model, final Property property, final CMLScalar value) {
+        final RDFNode rdfNode = CmlRdfUtils.createResource(value, model);
+        return rdfNode;
+    }
+
+    protected Property getProperty(final Model model, final QName dictRef) {
+        final String uri = getPropertyUri(dictRef.getNamespaceURI(), dictRef.getLocalPart());
+        return model.createProperty(uri);
+    }
+
+    protected final String getPropertyUri(final QName dictRef) {
+        return getPropertyUri(dictRef.getNamespaceURI(), dictRef.getLocalPart());
+    }
+
+    protected String getPropertyUri(final String namespaceURI, final String localPart) {
+        if (namespaceURI.endsWith("#") || namespaceURI.endsWith("/")) {
+            return namespaceURI + localPart;
+        } else {
+            return namespaceURI + '#' + localPart;
+        }
+    }
+
+    protected Property getHasProperty(final Model model, final QName dictRef) {
+        String localPart = dictRef.getLocalPart();
+        localPart = "has"+Character.toUpperCase(localPart.charAt(0)) + localPart.substring(1);
+        final String uri = getPropertyUri(dictRef.getNamespaceURI(), localPart);
+        return model.createProperty(uri);
+    }
+
+
+    public <T extends HasDictRef> Multimap<String, T> generateDictRefMap(final Elements elements, final Class<T> type) {
+        final List<Element> nodes = new ArrayList<Element>();
+        for (int i = 0; i < elements.size(); i++) {
+            nodes.add(elements.get(i));
+        }
+        return generateDictRefMap(nodes, type);
+    }
+
+    protected <T extends HasDictRef> Multimap<String, T> generateDictRefMap(final List<Element> nodes, final Class<T> type) {
+        final Multimap<String,T> map = ArrayListMultimap.create();
+        for (final Element node : nodes) {
+            final T element = type.cast(node);
+            final QName dictRef = getDictRefUri(element);
+            if (dictRef != null) {
+                map.put(getPropertyUri(dictRef), element);
+            }
+        }
+        return map;
+    }
+
+
+    protected QName getDictRefUri(final String dictRef, final CMLElement context) {
+        final int i = dictRef.indexOf(':');
+        final String prefix = dictRef.substring(0, i);
+        final String localName = dictRef.substring(i+1);
+        final String uri = context.getNamespaceURI(prefix);
+        if (uri == null) {
+            System.out.println("!! No dictRef URI: "+dictRef);
+            return null;
+        }
+        return new QName(uri, localName, prefix);
+    }
+
+    protected QName getDictRefUri(final HasDictRef element) {
+        final String dictRef = element.getDictRef();
+        final CMLElement context = (CMLElement) element;
+        if (dictRef != null) {
+            return getDictRefUri(dictRef, context);
+        }
+        return null;
+    }
+
+    protected List<CMLProperty> findCmlProperties(final Element context) {
+        final List<CMLProperty> properties = new ArrayList<CMLProperty>();
+        final List<Node> list = CMLUtil.getQueryNodes(context, "./cml:property | ./cml:propertyList/cml:property", CMLConstants.CML_XPATH);
+        for (final Node node : list) {
+            properties.add((CMLProperty)node);
+        }
+        return properties;
+    }
+
+    protected List<CMLParameter> findCmlParameters(final Element context) {
+        final List<CMLParameter> properties = new ArrayList<CMLParameter>();
+        final List<Node> list = CMLUtil.getQueryNodes(context, "./cml:parameter | ./cml:parameterList/cml:parameter", CMLConstants.CML_XPATH);
+        for (final Node node : list) {
+            properties.add((CMLParameter)node);
+        }
+        return properties;
+    }
+
+
+
+}

chemistry-common/src/main/java/net/chempound/chemistry/CmlRdfUtils.java

+package net.chempound.chemistry;
+
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.vocabulary.RDF;
+import org.joda.time.DateTime;
+import org.xmlcml.cml.base.CMLElement;
+import org.xmlcml.cml.element.CMLScalar;
+import org.xmlcml.cml.interfacex.HasDictRef;
+import net.chempound.rdf.cml.CmlRdf;
+
+/**
+ * @author Sam Adams
+ */
+public class CmlRdfUtils {
+
+    public static RDFNode createResource(final CMLScalar scalar, final Model model) {
+        final RDFNode valueNode = createValueNode(scalar, model);
+        final RDFNode unitsNode = createUnitsNode(scalar, model);
+        final RDFNode errorNode = createErrorNode(scalar, model);
+
+        // Force bNode creation for non-string
+        if (unitsNode == null && errorNode == null) {
+            if ("xsd:string".equals(scalar.getDataType())) {
+                return valueNode;
+            }
+        }
+
+        final Resource bnode = model.createResource();
+        bnode.addProperty(RDF.value, valueNode);
+        if (unitsNode != null) {
+            bnode.addProperty(CmlRdf.units, unitsNode);
+        }
+        if (errorNode != null) {
+            bnode.addProperty(CmlRdf.errorValue, errorNode);
+        }
+        return bnode;
+    }
+
+    public static RDFNode createValueNode(final CMLScalar scalar, final Model model) {
+        final String dataType = scalar.getDataType();
+        if ("xsd:string".equals(dataType)) {
+            return model.createTypedLiteral(scalar.getString().trim());
+        }
+        if ("xsd:double".equals(dataType)) {
+            return model.createTypedLiteral(scalar.getDouble());
+        }
+        if ("xsd:integer".equals(dataType)) {
+            return model.createTypedLiteral(scalar.getInt());
+        }
+        if ("xsd:boolean".equals(dataType)) {
+            return model.createTypedLiteral(scalar.getBoolean());
+        }
+        if ("xsd:date".equals(dataType)) {
+            final DateTime dt = scalar.getDate();
+            return model.createTypedLiteral(dt.toDate());
+        }
+        throw new IllegalArgumentException("Unsupported data type: "+dataType);
+    }
+
+    public static RDFNode createUnitsNode(final CMLScalar scalar, final Model model) {
+        final String units = scalar.getUnits();
+        if (units != null) {
+            final String uri = getDictRefUri(units, scalar);
+            if (uri != null) {
+                return model.createResource(uri);
+            }
+        }
+        return null;
+    }
+
+    public static RDFNode createErrorNode(final CMLScalar scalar, final Model model) {
+        if (scalar.getErrorValueAttribute() != null) {
+            return model.createTypedLiteral(scalar.getErrorValue());
+        }
+        return null;
+    }
+
+    public static String getDictRefUri(final String dictRef, final CMLElement context) {
+        final int i = dictRef.indexOf(':');
+        final String prefix = dictRef.substring(0, i);
+        final String localName = dictRef.substring(i+1);
+        final String uri = context.getNamespaceURI(prefix);
+        if (uri == null) {
+            // TODO
+            return null;
+//            throw new IllegalArgumentException("prefix '"+prefix+"' undefined");
+        }
+        return uri + localName;
+    }
+
+    public static String getDictRefUri(final HasDictRef element) {
+        final String dictRef = element.getDictRef();
+        final CMLElement context = (CMLElement) element;
+        if (dictRef != null) {
+            return getDictRefUri(dictRef, context);
+        }
+        return null;
+    }
+
+}

chemistry-common/src/main/java/net/chempound/chemistry/inchi/InchiTool.java

+package net.chempound.chemistry.inchi;
+
+import net.sf.jniinchi.*;
+import nu.xom.Node;
+import org.apache.log4j.Logger;
+import org.xmlcml.cml.base.CMLUtil;
+import org.xmlcml.cml.element.CMLAtom;
+import org.xmlcml.cml.element.CMLBond;
+import org.xmlcml.cml.element.CMLIdentifier;
+import org.xmlcml.cml.element.CMLMolecule;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.xmlcml.cml.base.CMLConstants.CML_XPATH;
+
+/**
+ * <p>
+ * Tool for the creation of InChIs from CML molecules.
+ * </p>
+ * 
+ * @author Nick Day
+ * @author Sam Adams
+ * @version 0.2
+ */
+public class InchiTool {
+
+	private static final Logger LOG = Logger.getLogger(InchiTool.class);
+	
+	/**
+	 * <p>
+	 * Generate the InChI for the objects molecule using the InChI program
+	 * options provided as a parameter.
+	 * </p>
+	 *
+	 * @param options - the InChI program options to be used for generation.
+	 *
+	 * @return the InChI string for the objects molecule. Returns null if there
+	 * was a problem during generation.
+	 */
+	public static String generateInchi(final CMLMolecule molecule, final String options) {
+        if (molecule == null) {
+            throw new IllegalArgumentException("Null argument: molecule");
+        }
+        try {
+            final JniInchiInput input = getInchiInput(molecule, options);
+            final JniInchiOutput output = JniInchiWrapper.getInchi(input);
+            if (output.getReturnStatus() == INCHI_RET.OKAY) {
+                return output.getInchi();
+            }
+            if (output.getReturnStatus() == INCHI_RET.WARNING) {
+                LOG.warn("Warning generating InChI: "+output.getMessage());
+                return output.getInchi();
+            }
+            throw new RuntimeException("Error generating InChI: "+output.getMessage());
+        } catch (JniInchiException e) {
+            throw new RuntimeException(e);
+        }
+	}
+
+    public static String generateInchiKey(final String inchi) {
+        if (inchi == null) {
+            throw new IllegalArgumentException("Null argument: inchi");
+        }
+        try {
+            final JniInchiOutputKey output = JniInchiWrapper.getInchiKey(inchi);
+            return output.getKey();
+        } catch (JniInchiException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+	/**
+	 * <p>
+	 * Creates a complete <code>JniInchiInput</code> object representing
+	 * the structure in the object CML molecule.  NOTE that this method
+	 * assumes that the provided CMLMolecule has 3D coordinates for all
+	 * atoms, and allows the InChI tool to calculate the stereochemical
+	 * flags instead of having to input them explicitly.
+	 * </p>
+	 *
+	 * @param options - the InChI program options to be used in creating
+	 * the InChI input.
+	 *
+	 * @return a complete <code>JniInchiInput</code> object representing
+	 * the structure in the object CML molecule.
+	 *
+	 * @throws net.sf.jniinchi.JniInchiException if there is an error is generating the
+	 * <code>JniInchiInput</code>.
+	 */
+	private static JniInchiInput getInchiInput(final CMLMolecule molecule, final String options) throws JniInchiException {
+		final JniInchiInput input = new JniInchiInput(options);
+		final Map<String, JniInchiAtom> jniAtomList = new HashMap<String, JniInchiAtom>(molecule.getAtomCount());
+		for (final CMLAtom atom : molecule.getAtoms()) {
+            final JniInchiAtom inchiAtom = new JniInchiAtom(atom.getX3(), atom.getY3(), atom.getZ3(), atom.getElementType());
+            inchiAtom.setImplicitH(0);
+            final JniInchiAtom a1 = input.addAtom(inchiAtom);
+			jniAtomList.put(atom.getId(), a1);
+		}
+		for (final CMLBond bond : molecule.getBonds()) {
+			final String[] atomRefs = bond.getAtomRefs2();
+			final JniInchiAtom a0 = jniAtomList.get(atomRefs[0]);
+			final JniInchiAtom a1 = jniAtomList.get(atomRefs[1]);
+			input.addBond(new JniInchiBond(a0, a1, getBondType(bond)));
+		}
+		return input;
+	}
+
+	/**
+	 * <p>
+	 * Gets the bond type for the provided CML bond.
+	 * </p>
+	 *
+	 * @param bond whose type you want to returned.
+	 *
+	 * @return bond type of the provided bond.
+	 */
+	private static INCHI_BOND_TYPE getBondType(final CMLBond bond) {
+		final String order = bond.getOrder();
+		if ("1".equals(order) || "S".equals(order)) {
+			return INCHI_BOND_TYPE.SINGLE;
+		} else if ("2".equals(order) || "D".equals(order)) {
+			return INCHI_BOND_TYPE.DOUBLE;
+		} else if ("3".equals(order) || "T".equals(order)) {
+			return INCHI_BOND_TYPE.TRIPLE;
+		} else {
+			return INCHI_BOND_TYPE.ALTERN;
+		}
+	}
+
+
+    public static void attachIdentifiers(final Node root) {
+        for (final Node node : CMLUtil.getQueryNodes(root, "//cml:molecule", CML_XPATH)) {
+            final CMLMolecule mol = (CMLMolecule) node;
+            final String inchi = InchiTool.generateInchi(mol, null);
+            attachInchi(mol, inchi);
+            final String inchiKey = InchiTool.generateInchiKey(inchi);
+            attachInchiKey(mol, inchiKey);
+        }
+    }
+
+    public static void attachInchi(final CMLMolecule mol, final String inchi) {
+        final CMLIdentifier identifier = new CMLIdentifier();
+        identifier.setConvention("iupac:inchi");
+        identifier.setCMLValue(inchi);
+        mol.appendChild(identifier);
+    }
+
+    public static void attachInchiKey(final CMLMolecule mol, final String inchiKey) {
+        final CMLIdentifier identifier = new CMLIdentifier();
+        identifier.setConvention("iupac:inchiKey");
+        identifier.setCMLValue(inchiKey);
+        mol.appendChild(identifier);
+    }
+
+}

chemistry-common/src/main/java/uk/ac/cam/ch/wwmm/chempound/chemistry/Cml2RdfConverter.java

-package uk.ac.cam.ch.wwmm.chempound.chemistry;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import com.hp.hpl.jena.rdf.model.*;
-import nu.xom.Element;
-import nu.xom.Elements;
-import nu.xom.Node;
-import org.xmlcml.cml.base.CMLConstants;
-import org.xmlcml.cml.base.CMLElement;
-import org.xmlcml.cml.base.CMLUtil;
-import org.xmlcml.cml.element.CMLParameter;
-import org.xmlcml.cml.element.CMLProperty;
-import org.xmlcml.cml.element.CMLScalar;
-import org.xmlcml.cml.interfacex.HasDictRef;
-
-import javax.xml.namespace.QName;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Sam Adams
- */
-public class Cml2RdfConverter {
-
-    protected void addParameters(final Model model, final Resource parentNode, final List<CMLParameter> parameters) {
-        for (final CMLParameter parameter : parameters) {
-            final QName dictRef = getDictRefUri(parameter);
-
-            final Property prop = getProperty(model, dictRef);
-            final CMLScalar scalar = (CMLScalar) parameter.getFirstCMLChild(CMLScalar.TAG);
-            if (scalar != null) {
-                final RDFNode rdfNode = CmlRdfUtils.createResource(scalar, model);
-                if (rdfNode.isResource()) {
-                    // Ignore duplicate complex types
-                    if (parentNode.hasProperty(prop)) {
-                        continue;
-                    }
-                }
-                parentNode.addProperty(prop, rdfNode);
-            }
-        }
-    }
-
-    protected void addCmlProperties(final Model model, final Resource resource, final List<CMLProperty> nodes) {
-        for (final CMLProperty property : nodes) {
-            final Elements elements = property.getChildElements();
-            if (elements.size() == 1) {
-                final Element child = elements.get(0);
-                addProperty(model, resource, property, child);
-            }
-        }
-    }
-
-    protected void addProperty(final Model model, final Resource resource, final CMLProperty property, final Element value) {
-        if (value instanceof CMLScalar) {
-            final QName dictRef = getDictRefUri(property);
-            if (dictRef != null) {
-                final Property prop = getProperty(model, dictRef);
-                addScalar(model, resource, prop, (CMLScalar) value);
-            } else {
-                System.err.println("** Missing dictRef **");
-                System.err.println(property.toXML());
-                System.err.println("*********************");
-            }
-        } else {
-            final QName dictRef = getDictRefUri(property);
-            if (dictRef != null) {
-                final Property prop = getHasProperty(model, dictRef);
-                resource.addLiteral(prop, true);
-            } else {
-                System.err.println("** Missing dictRef **");
-                System.err.println(property.toXML());
-                System.err.println("*********************");
-            }
-        }
-    }
-
-
-    protected void addScalar(final Model model, final Resource resource, final Property property, final CMLScalar value) {
-        final RDFNode rdfNode = createScalarValueResource(model, property, value);
-        resource.addProperty(property, rdfNode);
-    }
-
-    protected RDFNode createScalarValueResource(final Model model, final Property property, final CMLScalar value) {
-        final RDFNode rdfNode = CmlRdfUtils.createResource(value, model);
-        return rdfNode;
-    }
-
-    protected Property getProperty(final Model model, final QName dictRef) {
-        final String uri = getPropertyUri(dictRef.getNamespaceURI(), dictRef.getLocalPart());
-        return model.createProperty(uri);
-    }
-
-    protected final String getPropertyUri(final QName dictRef) {
-        return getPropertyUri(dictRef.getNamespaceURI(), dictRef.getLocalPart());
-    }
-
-    protected String getPropertyUri(final String namespaceURI, final String localPart) {
-        if (namespaceURI.endsWith("#") || namespaceURI.endsWith("/")) {
-            return namespaceURI + localPart;
-        } else {
-            return namespaceURI + '#' + localPart;
-        }
-    }
-
-    protected Property getHasProperty(final Model model, final QName dictRef) {
-        String localPart = dictRef.getLocalPart();
-        localPart = "has"+Character.toUpperCase(localPart.charAt(0)) + localPart.substring(1);
-        final String uri = getPropertyUri(dictRef.getNamespaceURI(), localPart);
-        return model.createProperty(uri);
-    }
-
-
-    public <T extends HasDictRef> Multimap<String, T> generateDictRefMap(final Elements elements, final Class<T> type) {
-        final List<Element> nodes = new ArrayList<Element>();
-        for (int i = 0; i < elements.size(); i++) {
-            nodes.add(elements.get(i));
-        }
-        return generateDictRefMap(nodes, type);
-    }
-
-    protected <T extends HasDictRef> Multimap<String, T> generateDictRefMap(final List<Element> nodes, final Class<T> type) {
-        final Multimap<String,T> map = ArrayListMultimap.create();
-        for (final Element node : nodes) {
-            final T element = type.cast(node);
-            final QName dictRef = getDictRefUri(element);
-            if (dictRef != null) {
-                map.put(getPropertyUri(dictRef), element);
-            }
-        }
-        return map;
-    }
-
-
-    protected QName getDictRefUri(final String dictRef, final CMLElement context) {
-        final int i = dictRef.indexOf(':');
-        final String prefix = dictRef.substring(0, i);
-        final String localName = dictRef.substring(i+1);
-        final String uri = context.getNamespaceURI(prefix);
-        if (uri == null) {
-            System.out.println("!! No dictRef URI: "+dictRef);
-            return null;
-        }
-        return new QName(uri, localName, prefix);
-    }
-
-    protected QName getDictRefUri(final HasDictRef element) {
-        final String dictRef = element.getDictRef();
-        final CMLElement context = (CMLElement) element;
-        if (dictRef != null) {
-            return getDictRefUri(dictRef, context);
-        }
-        return null;
-    }
-
-    protected List<CMLProperty> findCmlProperties(final Element context) {
-        final List<CMLProperty> properties = new ArrayList<CMLProperty>();
-        final List<Node> list = CMLUtil.getQueryNodes(context, "./cml:property | ./cml:propertyList/cml:property", CMLConstants.CML_XPATH);
-        for (final Node node : list) {
-            properties.add((CMLProperty)node);
-        }
-        return properties;
-    }
-
-    protected List<CMLParameter> findCmlParameters(final Element context) {
-        final List<CMLParameter> properties = new ArrayList<CMLParameter>();
-        final List<Node> list = CMLUtil.getQueryNodes(context, "./cml:parameter | ./cml:parameterList/cml:parameter", CMLConstants.CML_XPATH);
-        for (final Node node : list) {
-            properties.add((CMLParameter)node);
-        }
-        return properties;
-    }
-
-
-
-}

chemistry-common/src/main/java/uk/ac/cam/ch/wwmm/chempound/chemistry/CmlRdfUtils.java

-package uk.ac.cam.ch.wwmm.chempound.chemistry;
-
-import com.hp.hpl.jena.rdf.model.Model;
-import com.hp.hpl.jena.rdf.model.RDFNode;
-import com.hp.hpl.jena.rdf.model.Resource;
-import com.hp.hpl.jena.vocabulary.RDF;
-import org.joda.time.DateTime;
-import org.xmlcml.cml.base.CMLElement;
-import org.xmlcml.cml.element.CMLScalar;
-import org.xmlcml.cml.interfacex.HasDictRef;
-import uk.ac.cam.ch.wwmm.chempound.rdf.cml.CmlRdf;
-
-/**
- * @author Sam Adams
- */
-public class CmlRdfUtils {
-
-    public static RDFNode createResource(final CMLScalar scalar, final Model model) {
-        final RDFNode valueNode = createValueNode(scalar, model);
-        final RDFNode unitsNode = createUnitsNode(scalar, model);
-        final RDFNode errorNode = createErrorNode(scalar, model);
-
-        // Force bNode creation for non-string
-        if (unitsNode == null && errorNode == null) {
-            if ("xsd:string".equals(scalar.getDataType())) {
-                return valueNode;
-            }
-        }
-
-        final Resource bnode = model.createResource();
-        bnode.addProperty(RDF.value, valueNode);
-        if (unitsNode != null) {
-            bnode.addProperty(CmlRdf.units, unitsNode);
-        }
-        if (errorNode != null) {
-            bnode.addProperty(CmlRdf.errorValue, errorNode);
-        }
-        return bnode;
-    }
-
-    public static RDFNode createValueNode(final CMLScalar scalar, final Model model) {
-        final String dataType = scalar.getDataType();
-        if ("xsd:string".equals(dataType)) {
-            return model.createTypedLiteral(scalar.getString().trim());
-        }
-        if ("xsd:double".equals(dataType)) {
-            return model.createTypedLiteral(scalar.getDouble());
-        }
-        if ("xsd:integer".equals(dataType)) {
-            return model.createTypedLiteral(scalar.getInt());
-        }
-        if ("xsd:boolean".equals(dataType)) {
-            return model.createTypedLiteral(scalar.getBoolean());
-        }
-        if ("xsd:date".equals(dataType)) {
-            final DateTime dt = scalar.getDate();
-            return model.createTypedLiteral(dt.toDate());
-        }
-        throw new IllegalArgumentException("Unsupported data type: "+dataType);
-    }
-
-    public static RDFNode createUnitsNode(final CMLScalar scalar, final Model model) {
-        final String units = scalar.getUnits();
-        if (units != null) {
-            final String uri = getDictRefUri(units, scalar);
-            if (uri != null) {
-                return model.createResource(uri);
-            }
-        }
-        return null;
-    }
-
-    public static RDFNode createErrorNode(final CMLScalar scalar, final Model model) {
-        if (scalar.getErrorValueAttribute() != null) {
-            return model.createTypedLiteral(scalar.getErrorValue());
-        }
-        return null;
-    }
-
-    public static String getDictRefUri(final String dictRef, final CMLElement context) {
-        final int i = dictRef.indexOf(':');
-        final String prefix = dictRef.substring(0, i);
-        final String localName = dictRef.substring(i+1);
-        final String uri = context.getNamespaceURI(prefix);
-        if (uri == null) {
-            // TODO
-            return null;
-//            throw new IllegalArgumentException("prefix '"+prefix+"' undefined");
-        }
-        return uri + localName;
-    }
-
-    public static String getDictRefUri(final HasDictRef element) {
-        final String dictRef = element.getDictRef();
-        final CMLElement context = (CMLElement) element;
-        if (dictRef != null) {
-            return getDictRefUri(dictRef, context);
-        }
-        return null;
-    }
-
-}

chemistry-common/src/main/java/uk/ac/cam/ch/wwmm/chempound/chemistry/inchi/InchiTool.java

-package uk.ac.cam.ch.wwmm.chempound.chemistry.inchi;
-
-import net.sf.jniinchi.*;
-import nu.xom.Node;
-import org.apache.log4j.Logger;
-import org.xmlcml.cml.base.CMLUtil;
-import org.xmlcml.cml.element.CMLAtom;
-import org.xmlcml.cml.element.CMLBond;
-import org.xmlcml.cml.element.CMLIdentifier;
-import org.xmlcml.cml.element.CMLMolecule;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.xmlcml.cml.base.CMLConstants.CML_XPATH;
-
-/**
- * <p>
- * Tool for the creation of InChIs from CML molecules.
- * </p>
- * 
- * @author Nick Day
- * @author Sam Adams
- * @version 0.2
- */
-public class InchiTool {
-
-	private static final Logger LOG = Logger.getLogger(InchiTool.class);
-	
-	/**
-	 * <p>
-	 * Generate the InChI for the objects molecule using the InChI program
-	 * options provided as a parameter.
-	 * </p>
-	 *
-	 * @param options - the InChI program options to be used for generation.
-	 *
-	 * @return the InChI string for the objects molecule. Returns null if there
-	 * was a problem during generation.
-	 */
-	public static String generateInchi(final CMLMolecule molecule, final String options) {
-        if (molecule == null) {
-            throw new IllegalArgumentException("Null argument: molecule");
-        }
-        try {
-            final JniInchiInput input = getInchiInput(molecule, options);
-            final JniInchiOutput output = JniInchiWrapper.getInchi(input);
-            if (output.getReturnStatus() == INCHI_RET.OKAY) {
-                return output.getInchi();
-            }
-            if (output.getReturnStatus() == INCHI_RET.WARNING) {
-                LOG.warn("Warning generating InChI: "+output.getMessage());
-                return output.getInchi();
-            }
-            throw new RuntimeException("Error generating InChI: "+output.getMessage());
-        } catch (JniInchiException e) {
-            throw new RuntimeException(e);
-        }
-	}
-
-    public static String generateInchiKey(final String inchi) {
-        if (inchi == null) {
-            throw new IllegalArgumentException("Null argument: inchi");
-        }
-        try {
-            final JniInchiOutputKey output = JniInchiWrapper.getInchiKey(inchi);
-            return output.getKey();
-        } catch (JniInchiException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-	/**
-	 * <p>
-	 * Creates a complete <code>JniInchiInput</code> object representing
-	 * the structure in the object CML molecule.  NOTE that this method
-	 * assumes that the provided CMLMolecule has 3D coordinates for all
-	 * atoms, and allows the InChI tool to calculate the stereochemical
-	 * flags instead of having to input them explicitly.
-	 * </p>
-	 *
-	 * @param options - the InChI program options to be used in creating
-	 * the InChI input.
-	 *
-	 * @return a complete <code>JniInchiInput</code> object representing
-	 * the structure in the object CML molecule.
-	 *
-	 * @throws net.sf.jniinchi.JniInchiException if there is an error is generating the
-	 * <code>JniInchiInput</code>.
-	 */
-	private static JniInchiInput getInchiInput(final CMLMolecule molecule, final String options) throws JniInchiException {
-		final JniInchiInput input = new JniInchiInput(options);
-		final Map<String, JniInchiAtom> jniAtomList = new HashMap<String, JniInchiAtom>(molecule.getAtomCount());
-		for (final CMLAtom atom : molecule.getAtoms()) {
-            final JniInchiAtom inchiAtom = new JniInchiAtom(atom.getX3(), atom.getY3(), atom.getZ3(), atom.getElementType());
-            inchiAtom.setImplicitH(0);
-            final JniInchiAtom a1 = input.addAtom(inchiAtom);
-			jniAtomList.put(atom.getId(), a1);
-		}
-		for (final CMLBond bond : molecule.getBonds()) {
-			final String[] atomRefs = bond.getAtomRefs2();
-			final JniInchiAtom a0 = jniAtomList.get(atomRefs[0]);
-			final JniInchiAtom a1 = jniAtomList.get(atomRefs[1]);
-			input.addBond(new JniInchiBond(a0, a1, getBondType(bond)));
-		}
-		return input;
-	}
-
-	/**
-	 * <p>
-	 * Gets the bond type for the provided CML bond.
-	 * </p>
-	 *
-	 * @param bond whose type you want to returned.
-	 *
-	 * @return bond type of the provided bond.
-	 */
-	private static INCHI_BOND_TYPE getBondType(final CMLBond bond) {
-		final String order = bond.getOrder();
-		if ("1".equals(order) || "S".equals(order)) {
-			return INCHI_BOND_TYPE.SINGLE;
-		} else if ("2".equals(order) || "D".equals(order)) {
-			return INCHI_BOND_TYPE.DOUBLE;
-		} else if ("3".equals(order) || "T".equals(order)) {
-			return INCHI_BOND_TYPE.TRIPLE;
-		} else {
-			return INCHI_BOND_TYPE.ALTERN;
-		}
-	}
-
-
-    public static void attachIdentifiers(final Node root) {
-        for (final Node node : CMLUtil.getQueryNodes(root, "//cml:molecule", CML_XPATH)) {
-            final CMLMolecule mol = (CMLMolecule) node;
-            final String inchi = InchiTool.generateInchi(mol, null);
-            attachInchi(mol, inchi);
-            final String inchiKey = InchiTool.generateInchiKey(inchi);
-            attachInchiKey(mol, inchiKey);
-        }
-    }
-
-    public static void attachInchi(final CMLMolecule mol, final String inchi) {
-        final CMLIdentifier identifier = new CMLIdentifier();
-        identifier.setConvention("iupac:inchi");
-        identifier.setCMLValue(inchi);
-        mol.appendChild(identifier);
-    }
-
-    public static void attachInchiKey(final CMLMolecule mol, final String inchiKey) {
-        final CMLIdentifier identifier = new CMLIdentifier();
-        identifier.setConvention("iupac:inchiKey");
-        identifier.setCMLValue(inchiKey);
-        mol.appendChild(identifier);
-    }
-
-}

chemistry-common/src/test/java/net/chempound/chemistry/inchi/InchiToolTest.java

+package net.chempound.chemistry.inchi;
+
+import nu.xom.Document;
+import nu.xom.ParsingException;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.xmlcml.cml.base.CMLBuilder;
+import org.xmlcml.cml.element.CMLMolecule;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Sam Adams
+ */
+public class InchiToolTest {
+
+    @Test
+    public void testCH4() throws Exception {
+        CMLMolecule molecule = load("/ch4.cml");
+        String inchi = InchiTool.generateInchi(molecule, "");
+        assertEquals("InChI=1S/CH4/h1H4", inchi);
+    }
+
+    @Test
+    public void testCH2() throws Exception {
+        CMLMolecule molecule = load("/ch2.cml");
+        String inchi = InchiTool.generateInchi(molecule, "");
+        assertEquals("InChI=1S/CH2/h1H2", inchi);
+    }
+
+    private CMLMolecule load(String filepath) throws ParsingException, IOException {
+        Document doc;
+        CMLBuilder builder = new CMLBuilder();
+        InputStream in = getClass().getResourceAsStream(filepath);
+        try {
+            doc = builder.build(in);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+        return (CMLMolecule) doc.getRootElement();
+    }
+
+}

chemistry-common/src/test/java/uk/ac/cam/ch/wwmm/chempound/chemistry/inchi/InchiToolTest.java

-package uk.ac.cam.ch.wwmm.chempound.chemistry.inchi;
-
-import nu.xom.Document;
-import nu.xom.ParsingException;
-import nu.xom.ValidityException;
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.xmlcml.cml.base.CMLBuilder;
-import org.xmlcml.cml.element.CMLMolecule;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author Sam Adams
- */
-public class InchiToolTest {
-
-    @Test
-    public void testCH4() throws Exception {
-        CMLMolecule molecule = load("/ch4.cml");
-        String inchi = InchiTool.generateInchi(molecule, "");
-        assertEquals("InChI=1S/CH4/h1H4", inchi);
-    }
-
-    @Test
-    public void testCH2() throws Exception {
-        CMLMolecule molecule = load("/ch2.cml");
-        String inchi = InchiTool.generateInchi(molecule, "");
-        assertEquals("InChI=1S/CH2/h1H2", inchi);
-    }
-
-    private CMLMolecule load(String filepath) throws ParsingException, IOException {
-        Document doc;
-        CMLBuilder builder = new CMLBuilder();
-        InputStream in = getClass().getResourceAsStream(filepath);
-        try {
-            doc = builder.build(in);
-        } finally {
-            IOUtils.closeQuietly(in);
-        }
-        return (CMLMolecule) doc.getRootElement();
-    }
-
-}

chemistry-importer/pom.xml

     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>uk.ac.cam.ch.wwmm.chempound.chemistry</groupId>
+        <groupId>net.chempound.chemistry</groupId>
         <artifactId>chemistry</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
 
     <dependencies>
         <dependency>
-            <groupId>uk.ac.cam.ch.wwmm.chempound.chemistry</groupId>
+            <groupId>net.chempound.chemistry</groupId>
             <artifactId>chemistry-common</artifactId>
         </dependency>
 
         <dependency>
-            <groupId>uk.ac.cam.ch.wwmm.chempound</groupId>
+            <groupId>net.chempound</groupId>
             <artifactId>chempound-api</artifactId>
         </dependency>
 

chemistry-importer/src/main/java/net/chempound/chemistry/CmlImporter.java

+package net.chempound.chemistry;
+
+import nu.xom.Document;
+import nu.xom.Element;
+import nu.xom.ParsingException;
+import nu.xom.Serializer;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.xmlcml.cml.base.CMLBuilder;
+import org.xmlcml.cml.element.CMLMolecule;
+import sea36.image.jmol.ImageGeneratorJmol;
+import net.chempound.ContentImporter;
+import net.chempound.storage.InMemoryResource;
+import net.chempound.storage.LocalResource;
+import net.chempound.util.MimeType;
+
+import java.io.*;
+
+/**
+ * @author Sam Adams
+ */
+public abstract class CmlImporter extends ContentImporter {
+
+    public static final MimeType CHEMICAL_CML = new MimeType("chemical/x-cml", "Chemical Markup Language");
+
+    private int imageDimension = 400;
+    private int thumbnailDimension = 100;
+
+    protected LocalResource imageResource;
+    protected LocalResource thumbnailResource;
+
+
+    public int getImageDimension() {
+        return imageDimension;
+    }
+
+    public void setImageDimension(final int imageDimension) {
+        this.imageDimension = imageDimension;
+    }
+
+    public int getThumbnailDimension() {
+        return thumbnailDimension;
+    }
+
+    public void setThumbnailDimension(final int thumbnailDimension) {
+        this.thumbnailDimension = thumbnailDimension;
+    }
+
+
+
+    protected void createImages(final LocalResource resource, final String ext, final File imageFile, final File thumbnailFile) throws IOException {
+        final File tempFile = File.createTempFile("mol", ext);
+        try {
+            write(resource, tempFile);
+
+            final ImageGeneratorJmol imageGen = new ImageGeneratorJmol();
+            try {
+                imageGen.loadMolecule(tempFile);
+
+                createImage(imageFile, imageGen);
+                createThumbnail(thumbnailFile, imageGen);
+
+            } finally {
+                imageGen.shutdown();
+            }
+        } finally {
+            FileUtils.deleteQuietly(tempFile);
+        }
+    }
+
+    protected void createImages(final CMLMolecule molecule, final File imageFile, final File thumbnailFile) throws IOException {
+        final File tempFile = File.createTempFile("mol", "cml");
+        try {
+            write(molecule, tempFile);
+
+            final ImageGeneratorJmol imageGen = new ImageGeneratorJmol();
+            try {
+                imageGen.loadMolecule(tempFile);
+                imageGen.setShowAxes(true);
+                imageGen.createImage(imageFile, getImageDimension(), getImageDimension());
+
+                imageGen.setShowAxes(false);
+                imageGen.setFrankOn(false);
+                imageGen.createImage(thumbnailFile, getThumbnailDimension(), getThumbnailDimension());
+            } finally {
+                imageGen.shutdown();
+            }
+        } finally {
+            FileUtils.deleteQuietly(tempFile);
+        }
+    }
+
+    protected void createThumbnail(final File thumbnailFile, final ImageGeneratorJmol imageGen) {
+        imageGen.setShowAxes(false);
+        imageGen.setShowUnitCell(false);
+        imageGen.setFrankOn(false);
+        imageGen.createImage(thumbnailFile, getThumbnailDimension(), getThumbnailDimension());
+    }
+
+    protected void createImage(final File imageFile, final ImageGeneratorJmol imageGen) {
+        imageGen.setShowAxes(true);
+        imageGen.setShowUnitCell(true);
+        imageGen.createImage(imageFile, getImageDimension(), getImageDimension());
+    }
+
+
+    protected static void write(final Element element, final File file) throws IOException {
+        final Element copy = (Element) element.copy();
+        write(new Document(copy), file);
+    }
+
+    protected static void write(final Document doc, final File file) throws IOException {
+        final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
+        try {
+            final Serializer ser = new Serializer(out);
+            ser.write(doc);
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+    }
+
+    protected static void write(final LocalResource resource, final File file) throws IOException {
+        final FileOutputStream out = new FileOutputStream(file);
+        try {
+            final InputStream in = resource.openInputStream();
+            try {
+                IOUtils.copy(in, out);
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+    }
+
+    protected static LocalResource createCmlResource(final Element cml, final String path) throws IOException {
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final Serializer ser = new Serializer(buffer);
+        final Document doc = cml.getDocument() != null ? cml.getDocument() : new Document(cml);
+        ser.write(doc);
+        final byte[] bytes = buffer.toByteArray();
+        return new InMemoryResource(path, CHEMICAL_CML, bytes);
+    }
+
+    protected static LocalResource createImageResource(final File file, final String path) throws IOException {
+        final byte[] buffer = FileUtils.readFileToByteArray(file);
+        return new InMemoryResource(path, MimeType.IMAGE_PNG, buffer);
+    }
+
+
+    protected static LocalResource createCmlResource(final Document doc, final String path) throws IOException {
+        final byte[] bytes = writeDocument(doc);
+        return new InMemoryResource(path, CHEMICAL_CML, bytes);
+    }
+
+
+    public static Document reloadCml(final Element cml) throws IOException, ParsingException {
+        final Document doc = cml.getDocument() == null ? new Document(cml) : cml.getDocument();
+        return reloadCml(doc);
+    }
+
+    public static Document reloadCml(final Document doc) throws IOException, ParsingException {
+        final byte[] buffer = writeDocument(doc);
+        return readCml(buffer);
+    }
+
+    public static Document readCml(final byte[] buffer) throws IOException, ParsingException {
+        final CMLBuilder builder = new CMLBuilder();
+        return builder.build(new ByteArrayInputStream(buffer));
+    }
+
+    public static byte[] writeDocument(final Document doc) throws IOException {
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        final Serializer ser = new Serializer(buffer);
+        ser.write(doc);
+        return buffer.toByteArray();
+    }
+
+
+}

chemistry-importer/src/main/java/uk/ac/cam/ch/wwmm/chempound/chemistry/CmlImporter.java

-package uk.ac.cam.ch.wwmm.chempound.chemistry;
-
-import nu.xom.Document;
-import nu.xom.Element;
-import nu.xom.ParsingException;
-import nu.xom.Serializer;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.xmlcml.cml.base.CMLBuilder;
-import org.xmlcml.cml.element.CMLMolecule;
-import sea36.image.jmol.ImageGeneratorJmol;
-import uk.ac.cam.ch.wwmm.chempound.ContentImporter;
-import uk.ac.cam.ch.wwmm.chempound.storage.InMemoryResource;
-import uk.ac.cam.ch.wwmm.chempound.storage.LocalResource;
-import uk.ac.cam.ch.wwmm.chempound.util.MimeType;
-
-import java.io.*;
-
-/**
- * @author Sam Adams
- */
-public abstract class CmlImporter extends ContentImporter {
-
-    public static final MimeType CHEMICAL_CML = new MimeType("chemical/x-cml", "Chemical Markup Language");
-
-    private int imageDimension = 400;
-    private int thumbnailDimension = 100;
-
-    protected LocalResource imageResource;
-    protected LocalResource thumbnailResource;
-
-
-    public int getImageDimension() {
-        return imageDimension;
-    }
-
-    public void setImageDimension(final int imageDimension) {
-        this.imageDimension = imageDimension;
-    }
-
-    public int getThumbnailDimension() {
-        return thumbnailDimension;
-    }
-
-    public void setThumbnailDimension(final int thumbnailDimension) {
-        this.thumbnailDimension = thumbnailDimension;
-    }
-
-
-
-    protected void createImages(final LocalResource resource, final String ext, final File imageFile, final File thumbnailFile) throws IOException {
-        final File tempFile = File.createTempFile("mol", ext);
-        try {
-            write(resource, tempFile);
-
-            final ImageGeneratorJmol imageGen = new ImageGeneratorJmol();
-            try {
-                imageGen.loadMolecule(tempFile);
-
-                createImage(imageFile, imageGen);
-                createThumbnail(thumbnailFile, imageGen);
-
-            } finally {
-                imageGen.shutdown();
-            }
-        } finally {
-            FileUtils.deleteQuietly(tempFile);
-        }
-    }
-
-    protected void createImages(final CMLMolecule molecule, final File imageFile, final File thumbnailFile) throws IOException {
-        final File tempFile = File.createTempFile("mol", "cml");
-        try {
-            write(molecule, tempFile);
-
-            final ImageGeneratorJmol imageGen = new ImageGeneratorJmol();
-            try {
-                imageGen.loadMolecule(tempFile);
-                imageGen.setShowAxes(true);
-                imageGen.createImage(imageFile, getImageDimension(), getImageDimension());
-
-                imageGen.setShowAxes(false);
-                imageGen.setFrankOn(false);
-                imageGen.createImage(thumbnailFile, getThumbnailDimension(), getThumbnailDimension());
-            } finally {
-                imageGen.shutdown();
-            }
-        } finally {
-            FileUtils.deleteQuietly(tempFile);
-        }
-    }
-
-    protected void createThumbnail(final File thumbnailFile, final ImageGeneratorJmol imageGen) {
-        imageGen.setShowAxes(false);
-        imageGen.setShowUnitCell(false);
-        imageGen.setFrankOn(false);
-        imageGen.createImage(thumbnailFile, getThumbnailDimension(), getThumbnailDimension());
-    }
-
-    protected void createImage(final File imageFile, final ImageGeneratorJmol imageGen) {
-        imageGen.setShowAxes(true);
-        imageGen.setShowUnitCell(true);
-        imageGen.createImage(imageFile, getImageDimension(), getImageDimension());
-    }
-
-
-    protected static void write(final Element element, final File file) throws IOException {
-        final Element copy = (Element) element.copy();
-        write(new Document(copy), file);
-    }
-
-    protected static void write(final Document doc, final File file) throws IOException {
-        final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
-        try {
-            final Serializer ser = new Serializer(out);
-            ser.write(doc);
-        } finally {
-            IOUtils.closeQuietly(out);
-        }
-    }
-
-    protected static void write(final LocalResource resource, final File file) throws IOException {
-        final FileOutputStream out = new FileOutputStream(file);
-        try {
-            final InputStream in = resource.openInputStream();
-            try {
-                IOUtils.copy(in, out);
-            } finally {
-                IOUtils.closeQuietly(in);
-            }
-        } finally {
-            IOUtils.closeQuietly(out);
-        }
-    }
-
-    protected static LocalResource createCmlResource(final Element cml, final String path) throws IOException {
-        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        final Serializer ser = new Serializer(buffer);
-        final Document doc = cml.getDocument() != null ? cml.getDocument() : new Document(cml);
-        ser.write(doc);
-        final byte[] bytes = buffer.toByteArray();
-        return new InMemoryResource(path, CHEMICAL_CML, bytes);
-    }
-
-    protected static LocalResource createImageResource(final File file, final String path) throws IOException {
-        final byte[] buffer = FileUtils.readFileToByteArray(file);
-        return new InMemoryResource(path, MimeType.IMAGE_PNG, buffer);
-    }
-
-
-    protected static LocalResource createCmlResource(final Document doc, final String path) throws IOException {
-        final byte[] bytes = writeDocument(doc);
-        return new InMemoryResource(path, CHEMICAL_CML, bytes);
-    }
-
-
-    public static Document reloadCml(final Element cml) throws IOException, ParsingException {
-        final Document doc = cml.getDocument() == null ? new Document(cml) : cml.getDocument();
-        return reloadCml(doc);
-    }
-
-    public static Document reloadCml(final Document doc) throws IOException, ParsingException {
-        final byte[] buffer = writeDocument(doc);
-        return readCml(buffer);
-    }
-
-    public static Document readCml(final byte[] buffer) throws IOException, ParsingException {
-        final CMLBuilder builder = new CMLBuilder();
-        return builder.build(new ByteArrayInputStream(buffer));
-    }
-
-    public static byte[] writeDocument(final Document doc) throws IOException {
-        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        final Serializer ser = new Serializer(buffer);
-        ser.write(doc);
-        return buffer.toByteArray();
-    }
-
-
-}

chemistry-jmol-plugin/pom.xml

     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>uk.ac.cam.ch.wwmm.chempound.chemistry</groupId>
+        <groupId>net.chempound.chemistry</groupId>
         <artifactId>chemistry</artifactId>
         <version>0.1-SNAPSHOT</version>
     </parent>
     <dependencies>
 
         <dependency>
-            <groupId>uk.ac.cam.ch.wwmm.chempound</groupId>
+            <groupId>net.chempound</groupId>
             <artifactId>chempound-webapi</artifactId>
         </dependency>