/** * Adds a LonePair to this Atom. * * @param atomID The atom number to which the LonePair is added in [0,..] */ public void addSingleElectron(int atomID) { ISingleElectron singleElectron = getBuilder().newInstance(ISingleElectron.class, atoms[atomID]); singleElectron.addListener(this); addSingleElectron(singleElectron); /* no notifyChanged() here because addSingleElectron() does it already */ }
/** * Removes the single electron at the given position from the AtomContainer. * * @param position The position of the SingleElectron to be removed. */ public ISingleElectron removeSingleElectron(int position) { ISingleElectron se = singleElectrons[position]; se.removeListener(this); for (int i = position; i < singleElectronCount - 1; i++) { singleElectrons[i] = singleElectrons[i + 1]; } singleElectrons[singleElectronCount - 1] = null; singleElectronCount--; notifyChanged(); return se; }
/** * Clones this AtomContainer object and its content. * * @return The cloned object * @see #shallowCopy */ public IAtomContainer clone() throws CloneNotSupportedException { // this is pretty wasteful as we need to delete most the data // we can't simply create an empty instance as the sub classes (e.g. AminoAcid) // would have a ClassCastException when they invoke clone IAtomContainer clone = (IAtomContainer) super.clone(); // remove existing elements - we need to set the stereo elements list as list.clone() doesn't // work as expected and will also remove all elements from the original clone.setStereoElements(new ArrayList<IStereoElement>(stereoElements.size())); clone.removeAllElements(); // create a mapping of the original atoms/bonds to the cloned atoms/bonds // we need this mapping to correctly clone bonds, single/paired electrons // and stereo elements // - the expected size stop the map be resized - method from Google Guava Map<IAtom, IAtom> atomMap = new HashMap<IAtom, IAtom>(atomCount >= 3 ? atomCount + atomCount / 3 : atomCount + 1); Map<IBond, IBond> bondMap = new HashMap<IBond, IBond>(bondCount >= 3 ? bondCount + bondCount / 3 : bondCount + 1); // clone atoms IAtom[] atoms = new IAtom[this.atomCount]; for (int i = 0; i < atoms.length; i++) { atoms[i] = (IAtom) this.atoms[i].clone(); atomMap.put(this.atoms[i], atoms[i]); } clone.setAtoms(atoms); // clone bonds using a the mappings from the original to the clone IBond[] bonds = new IBond[this.bondCount]; for (int i = 0; i < bonds.length; i++) { IBond original = this.bonds[i]; IBond bond = (IBond) original.clone(); int n = bond.getAtomCount(); IAtom[] members = new IAtom[n]; for (int j = 0; j < n; j++) { members[j] = atomMap.get(original.getAtom(j)); } bond.setAtoms(members); bondMap.put(this.bonds[i], bond); bonds[i] = bond; } clone.setBonds(bonds); // clone lone pairs (we can't use an array to buffer as there is no setLonePairs()) for (int i = 0; i < lonePairCount; i++) { ILonePair original = this.lonePairs[i]; ILonePair pair = (ILonePair) original.clone(); if (pair.getAtom() != null) pair.setAtom(atomMap.get(original.getAtom())); clone.addLonePair(pair); } // clone single electrons (we can't use an array to buffer as there is no setSingleElectrons()) for (int i = 0; i < singleElectronCount; i++) { ISingleElectron original = this.singleElectrons[i]; ISingleElectron electron = (ISingleElectron) original.clone(); if (electron.getAtom() != null) electron.setAtom(atomMap.get(original.getAtom())); clone.addSingleElectron(electron); } // map each stereo element to a new instance in the clone for (IStereoElement element : stereoElements) { clone.addStereoElement(element.map(atomMap, bondMap)); } return clone; }