1 package uk.ac.cam.ch.wwmm.opsin; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.LinkedHashSet; 6 import java.util.List; 7 import java.util.Set; 8 9 /** 10 * A "struct" to hold the results of fragment building. 11 * @author dl387 12 * 13 */ 14 class BuildResults { 15 /**Holds the atoms that are currently marked as radicals. An atom may be listed twice for say diyl 16 * Typically these will be utilised by a word rule e.g. the ethyl of ethyl ethanoate has one 17 * Also holds the order of the bond that will be created when it is used (valency) 18 * setExplicitly says whether the outAtom absolutely definitely refers to that atom or not. 19 * e.g. propyl is stored as prop-1-yl with this set to false while prop-2-yl has it set to true 20 * These OutAtoms are the same objects as are present in the fragments*/ 21 private final List<OutAtom> outAtoms = new ArrayList<OutAtom>(); 22 23 /**The atoms that may be used to from things like esters*/ 24 private final List<FunctionalAtom> functionalAtoms = new ArrayList<FunctionalAtom>(); 25 26 /**A list of fragments that have been evaluated to form this BuildResults. They are in the order they would be found in the XML*/ 27 private final Set<Fragment> fragments = new LinkedHashSet<Fragment>(); 28 29 /**A BuildResults is constructed from a list of Fragments. 30 * This constructor creates this list from the groups present in an XML word/bracket/sub element. 31 * @param wordSubOrBracket*/ BuildResults(Element wordSubOrBracket)32 BuildResults(Element wordSubOrBracket) { 33 List<Element> groups = OpsinTools.getDescendantElementsWithTagName(wordSubOrBracket, XmlDeclarations.GROUP_EL); 34 for (Element group : groups) { 35 Fragment frag = group.getFrag(); 36 fragments.add(frag); 37 for (int i = 0, l = frag.getOutAtomCount(); i < l; i++) { 38 outAtoms.add(frag.getOutAtom(i)); 39 } 40 int functionalAtomCount = frag.getFunctionalAtomCount(); 41 if (functionalAtomCount > 0){ 42 Element parent = group.getParent(); 43 if (parent.getName().equals(XmlDeclarations.ROOT_EL) || 44 OpsinTools.getNextGroup(group) == null) { 45 for (int i = 0; i < functionalAtomCount; i++) { 46 functionalAtoms.add(frag.getFunctionalAtom(i)); 47 } 48 } 49 } 50 } 51 } 52 53 /** 54 * Construct a blank buildResults 55 */ BuildResults()56 BuildResults() {} 57 58 /** 59 * Returns a read only view of the fragments in this BuildResults 60 * @return 61 */ getFragments()62 Set<Fragment> getFragments(){ 63 return Collections.unmodifiableSet(fragments); 64 } 65 getFragmentCount()66 int getFragmentCount(){ 67 return fragments.size(); 68 } 69 getOutAtom(int i)70 OutAtom getOutAtom(int i) { 71 return outAtoms.get(i); 72 } 73 getOutAtomCount()74 int getOutAtomCount() { 75 return outAtoms.size(); 76 } 77 removeOutAtom(int i)78 OutAtom removeOutAtom(int i) { 79 OutAtom outAtom = outAtoms.get(i); 80 outAtom.getAtom().getFrag().removeOutAtom(outAtom); 81 return outAtoms.remove(i); 82 } 83 removeAllOutAtoms()84 void removeAllOutAtoms() { 85 for (int i = outAtoms.size() -1; i >=0 ; i--) { 86 removeOutAtom(i); 87 } 88 } 89 90 /** 91 * Returns the atom corresponding to position i in the functionalAtoms list 92 * @param i index 93 * @return atom 94 */ getFunctionalAtom(int i)95 Atom getFunctionalAtom(int i) { 96 return functionalAtoms.get(i).getAtom(); 97 } 98 removeFunctionalAtom(int i)99 FunctionalAtom removeFunctionalAtom(int i) { 100 FunctionalAtom functionalAtom = functionalAtoms.get(i); 101 functionalAtom.getAtom().getFrag().removeFunctionalAtom(functionalAtom); 102 return functionalAtoms.remove(i); 103 } 104 getFunctionalAtomCount()105 int getFunctionalAtomCount(){ 106 return functionalAtoms.size(); 107 } 108 109 /** 110 * Returns the first OutAtom 111 * @return OutAtom 112 */ getFirstOutAtom()113 OutAtom getFirstOutAtom() { 114 return outAtoms.get(0); 115 } 116 117 /** 118 * Returns the atom corresponding to the given id assuming the atom the id corresponds to is within the list of fragment in this Buildresults 119 * @param id index 120 * @return atom 121 * @throws StructureBuildingException 122 */ getAtomByIdOrThrow(int id)123 Atom getAtomByIdOrThrow(int id) throws StructureBuildingException { 124 for (Fragment fragment : fragments) { 125 Atom outAtom =fragment.getAtomByID(id); 126 if (outAtom != null){ 127 return outAtom; 128 } 129 } 130 throw new StructureBuildingException("No fragment contained this id: " + id); 131 } 132 mergeBuildResults(BuildResults otherBR)133 void mergeBuildResults(BuildResults otherBR) { 134 outAtoms.addAll(otherBR.outAtoms); 135 functionalAtoms.addAll(otherBR.functionalAtoms); 136 fragments.addAll(otherBR.fragments); 137 } 138 139 /** 140 * Returns the sum of the charges of the fragments in the buildResults 141 * @return 142 */ getCharge()143 int getCharge() { 144 int totalCharge = 0; 145 for (Fragment frag : fragments) { 146 totalCharge += frag.getCharge(); 147 } 148 return totalCharge; 149 } 150 } 151