org.xmlcml.cml.chemdraw.components.CDXReactionStep Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chemdraw-converter Show documentation
Show all versions of chemdraw-converter Show documentation
Converts CDX and CDXML from and to CML
The newest version!
/**
* Copyright (C) 2001 Peter Murray-Rust ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xmlcml.cml.chemdraw.components;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.xmlcml.cml.base.CMLConstants;
import org.xmlcml.cml.base.CMLElement;
import org.xmlcml.cml.element.CMLLabel;
import org.xmlcml.cml.element.CMLMolecule;
import org.xmlcml.cml.element.CMLReaction;
import org.xmlcml.cml.element.CMLSpectator;
import nu.xom.Attribute;
import nu.xom.Element;
import nu.xom.Nodes;
/**
*
* @author pm286
*
*/
public class CDXReactionStep extends CDXObject {
static Logger LOG = Logger.getLogger(CDXReactionStep.class);
static {
LOG.setLevel(Level.INFO);
}
public final static int CODE = 0x800E;
public final static String NAME = "ReactionStep";
public final static String CDXNAME = "step";
// private CMLReaction reaction;
// private String[] reactionStepAtomMap = new String[0];
// private String[] reactionStepReactants = new String[0];
// private String[] reactionStepProducts = new String[0];
// private String[] reactionStepArrows = new String[0];
// private String[] reactionStepPlusses = new String[0];
// private String[] reactionObjectsAboveArrow = new String[0];
// private String[] reactionObjectsBelowArrow = new String[0];
public CDXReactionStep() {
super(CODE, NAME, CDXNAME);
}
/**
* copy node .
* @return Element
*/
public Element copy() {
return new CDXReactionStep(this);
}
/**
* copy constructor
* @param old
*/
public CDXReactionStep(CDXObject old) {
super(old);
}
/*--
Reaction Step Object
CDXML Name: step
CDX Constant Name: kCDXObj_ReactionStep
CDX Constant Value: 0x800E
Contained by objects: kCDXObj_Page, kCDXObj_Group, kCDXObj_ReactionScheme
First written/read in: ChemDraw 4.1
Description:
A Reaction Step describes one step in a reaction.
Technically, this object has no required objects or properties, but it is pretty useless without any reactants or products.
Subobjects:
(none)
Properties:
Value Name CDXML Name Type
n/a n/a id UINT16
A unique identifier for an object, used when other objects refer to it.
0x0C00 kCDXProp_ReactionStep_Atom_Map ReactionStepAtomMap CDXObjectIDArray
Represents pairs of mapped atom IDs; each pair is a reactant atom mapped to to a product atom.
0x0C01 kCDXProp_ReactionStep_Reactants ReactionStepReactants CDXObjectIDArray
An order list of reactants present in the Reaction Step.
0x0C02 kCDXProp_ReactionStep_Products ReactionStepProducts CDXObjectIDArray
An order list of products present in the Reaction Step.
0x0C03 kCDXProp_ReactionStep_Plusses ReactionStepPlusses CDXObjectIDArray
An ordered list of pluses used to separate components of the Reaction Step.
0x0C04 kCDXProp_ReactionStep_Arrows ReactionStepArrows CDXObjectIDArray
An ordered list of arrows used to separate components of the Reaction Step.
0x0C05 kCDXProp_ReactionStep_ObjectsAboveArrow ReactionStepObjectsAboveArrow CDXObjectIDArray
An order list of objects above the arrow in the Reaction Step.
0x0C06 kCDXProp_ReactionStep_ObjectsBelowArrow ReactionStepObjectsBelowArrow CDXObjectIDArray
An order list of objects below the arrow in the Reaction Step.
--*/
void getProductsAndReactants() {
// reactionStepAtomMap = processAttributes("ReactionStepAtomMap");
// reactionStepReactants = processAttributes("ReactionStepReactants");
// reactionStepProducts = processAttributes("ReactionStepProducts");
// reactionStepArrows = processAttributes("ReactionStepArrows");
// reactionStepPlusses = processAttributes("ReactionStepPlusses");
// reactionObjectsAboveArrow = processAttributes("ReactionObjectsAboveArrow");
// reactionObjectsBelowArrow = processAttributes("ReactionObjectsBelowArrow");
}
// may be useful
@SuppressWarnings("unused")
private String[] processAttributes(String attName) {
String s[] = new String[0];
String att = this.getAttributeValue(attName);
String prefix = (attName.equals("reactionStepArrows") ? "g" : "m");
if (att != null) {
int i = 0;
StringTokenizer st = new StringTokenizer(att, " ");
s = new String[st.countTokens()];
while (st.hasMoreTokens()) {
s[i++] = prefix + st.nextToken();
LOG.info(s[i-1]);
}
}
return s;
}
CMLReaction convertToCMLReaction() {
//
//
//
//
//
CMLReaction reaction = new CMLReaction();
this.copyAttributesTo(reaction);
return reaction;
}
public void process2CML(CMLElement cmlNode) {
/*
-
*/
// POINTS to... (this seems messy)
/*
-
*/
/*
makeProperty(0x0C00, "ReactionStep_Atom_Map", "ReactionStepAtomMap", "CDXObjectIDArray");
makeProperty(0x0C01, "ReactionStep_Reactants", "ReactionStepReactants", "CDXObjectIDArray");
makeProperty(0x0C02, "ReactionStep_Products", "ReactionStepProducts", "CDXObjectIDArray");
makeProperty(0x0C03, "ReactionStep_Plusses", "ReactionStepPlusses", "CDXObjectIDArray");
makeProperty(0x0C04, "ReactionStep_Arrows", "ReactionStepArrows", "CDXObjectIDArray");
makeProperty(0x0C05, "ReactionStep_ObjectsAboveArrow", "ReactionStepObjectsAboveArrow", "CDXObjectIDArray");
makeProperty(0x0C06, "ReactionStep_ObjectsBelowArrow", "ReactionStepObjectsBelowArrow", "CDXObjectIDArray");
makeProperty(0x0C07, "ReactionStep_Atom_Map_Manual", "ReactionStepAtomMapManual", "CDXObjectIDArray");
makeProperty(0x0C08, "ReactionStep_Atom_Map_Auto", "ReactionStepAtomMapAuto", "CDXObjectIDArray");
*/
Attribute reactionStepReactants = null;
Attribute reactionStepProducts = null;
Attribute reactionStepArrows = null;
Attribute reactionStepObjectsAboveArrow = null;
Attribute reactionStepObjectsBelowArrow = null;
for (int i = 0; i < this.getAttributeCount(); i++) {
Attribute attribute = this.getAttribute(i);
if (attribute.getLocalName().equals("ReactionStepReactants")) {
reactionStepReactants = attribute;
} else if (attribute.getLocalName().equals("ReactionStepProducts")) {
reactionStepProducts = attribute;
} else if (attribute.getLocalName().equals("ReactionStepArrows")) {
reactionStepArrows = attribute;
} else if (attribute.getLocalName().equals("ReactionStepObjectsAboveArrow")) {
reactionStepObjectsAboveArrow = attribute;
} else if (attribute.getLocalName().equals("ReactionStepObjectsBelowArrow")) {
reactionStepObjectsBelowArrow = attribute;
} else if (attribute.getLocalName().equals("ReactionStepPlusses") ||
attribute.getLocalName().equals("ReactionStepAtomMap") ||
attribute.getLocalName().equals("ReactionStepAtomMapManual") ||
attribute.getLocalName().equals("ReactionStepAtomMapAuto")) {
LOG.error("Cannot process "+attribute.getLocalName());
} else if (attribute.getLocalName().equals("id")) {
// skip
} else {
throw new RuntimeException("Unknown attribute on step: "+attribute.getLocalName());
}
}
// set up references
CMLReaction reaction = new CMLReaction();
cmlNode.appendChild(reaction);
List reactantMoleculeRefs = getMoleculeRefsFromId(reactionStepReactants);
for (CMLMolecule reactantMoleculeRef : reactantMoleculeRefs) {
reaction.addReactant(reactantMoleculeRef);
}
List productMoleculeRefs = getMoleculeRefsFromId(reactionStepProducts);
for (CMLMolecule productMoleculeRef : productMoleculeRefs) {
reaction.addProduct(productMoleculeRef);
}
// not sure what to do with this. Perhaps grab graphics attributes
CDXGraphic arrowsGraphic = getArrowsTargetNoop(reactionStepArrows);
addSpectatorRef(reactionStepObjectsAboveArrow, reaction);
addSpectatorRef(reactionStepObjectsBelowArrow, reaction);
}
public static void processReactionStep(CMLReaction reaction) {
/*
-
*/
// POINTS to... (this seems messy)
/*
-
*/
/*
makeProperty(0x0C00, "ReactionStep_Atom_Map", "ReactionStepAtomMap", "CDXObjectIDArray");
makeProperty(0x0C01, "ReactionStep_Reactants", "ReactionStepReactants", "CDXObjectIDArray");
makeProperty(0x0C02, "ReactionStep_Products", "ReactionStepProducts", "CDXObjectIDArray");
makeProperty(0x0C03, "ReactionStep_Plusses", "ReactionStepPlusses", "CDXObjectIDArray");
makeProperty(0x0C04, "ReactionStep_Arrows", "ReactionStepArrows", "CDXObjectIDArray");
makeProperty(0x0C05, "ReactionStep_ObjectsAboveArrow", "ReactionStepObjectsAboveArrow", "CDXObjectIDArray");
makeProperty(0x0C06, "ReactionStep_ObjectsBelowArrow", "ReactionStepObjectsBelowArrow", "CDXObjectIDArray");
makeProperty(0x0C07, "ReactionStep_Atom_Map_Manual", "ReactionStepAtomMapManual", "CDXObjectIDArray");
makeProperty(0x0C08, "ReactionStep_Atom_Map_Auto", "ReactionStepAtomMapAuto", "CDXObjectIDArray");
*/
resolveRefs(reaction.getReactantList().getMolecules());
resolveRefs(reaction.getProductList().getMolecules());
resolveSpectatorRefs(reaction.getSpectatorList().getMolecules());
}
private static void resolveRefs(List molecules) {
for (CMLMolecule molecule : molecules) {
// this is a mess
String ref = molecule.getAttributeValue("ref");
ref = CDXUtil.ensureNumericID(ref);
// Nodes moleculeNodes = molecule.query("//*[@id='"+ref+"' or @*[local-name()='group' and .='"+ref+"']]");
// Nodes moleculeNodes = molecule.query("//cml:molecule[@*[local-name()='group' and .='"+ref+"']]", CMLConstants.CML_XPATH);
Nodes moleculeNodes = molecule.query("//cml:molecule[@*[local-name()='group' and contains(concat(' ', ., ' '), ' "+ref+" ')]]", CMLConstants.CML_XPATH);
if (moleculeNodes.size() == 0) {
// ((CMLElement)molecule.query("/*").get(0)).debug("DOC");
LOG.warn("Cannot find molecule ref: "+ref);
molecule.setTitle("UNRESOLVED");
} else {
CMLElement element = (CMLElement) moleculeNodes.get(0);
CMLMolecule oldMolecule = (CMLMolecule)element;
molecule.setTitle("RESOLVED");
// newMolecule.detach();
// molecule.getParent().replaceChild(molecule, newMolecule);
}
}
}
private void addSpectatorRef(Attribute attribute, CMLReaction reaction) {
String refValue = getObjectsTextRef(attribute);
if (refValue != null) {
// there may be several values
String[] refs = refValue.split(" ");
for (String ref : refs) {
CMLSpectator spectator = new CMLSpectator();
spectator.addAttribute(new Attribute("ref", ref));
spectator.addAttribute(new Attribute("type", attribute.getLocalName()));
reaction.addSpectator(spectator);
}
}
}
// currently a no-op
private CDXGraphic getArrowsTargetNoop(Attribute attribute) {
// String id = getXMLID(attribute);
// Nodes arrowsNodes = this.query("//*[@id='"+id+"']");
// CDXObject arrowsObject = (arrowsNodes.size() == 1) ? (CDXObject) arrowsNodes.get(0) : null;
// if (arrowsObject == null || !(arrowsObject instanceof CDXGraphic)) {
// CMLUtil.debug((Element)this.query("/*").get(0), "STEP? "+id);
// throw new RuntimeException("Cannot find target of arrow "+id);
// }
// return (CDXGraphic) arrowsObject;
return null;
}
private String getObjectsTextRef(Attribute attribute) {
return getXMLID(attribute);
}
private static void resolveSpectatorRefs(List spectators) {
for (CMLMolecule spectator : spectators) {
String ref = CDXUtil.ensureNumericID(spectator.getAttributeValue("ref"));
String[] refs = ref.split(" ");
// for
Nodes nodes = spectator.query("//*[@id='"+ref+"']");
if (nodes.size() == 0) {
throw new RuntimeException("Cannot find spectator ref: "+ref);
}
String text = null;
if (nodes.get(0) instanceof CMLLabel) {
CMLLabel label = (CMLLabel) nodes.get(0);
text = label.getCMLValue();
}
spectator.setTitle(text);
}
}
private List getMoleculeRefsFromId(Attribute reactionStepAttribute) {
String idd = getXMLID(reactionStepAttribute);
List moleculeList = new ArrayList();
if (idd != null) {
String[] ids = idd.split(" ");
for (String id : ids) {
CMLMolecule molecule = new CMLMolecule();
molecule.setRef(id);
moleculeList.add(molecule);
}
}
return moleculeList;
}
private static String getXMLID(Attribute attribute) {
return (attribute == null) ? null :
CDXUtil.ensureXMLID(attribute.getValue());
}
};