Beispiel #1
0
  /**
   * 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;
  }