+ @Override
+ public void setProperty(Object key, Object value)
+ {
+ if (alignmentProperties == null)
+ {
+ alignmentProperties = new Hashtable();
+ }
+
+ alignmentProperties.put(key, value);
+ }
+
+ @Override
+ public Object getProperty(Object key)
+ {
+ if (alignmentProperties != null)
+ {
+ return alignmentProperties.get(key);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public Hashtable getProperties()
+ {
+ return alignmentProperties;
+ }
+
+ /**
+ * Adds the given mapping to the stored set. Note this may be held on the
+ * dataset alignment.
+ */
+ @Override
+ public void addCodonFrame(AlignedCodonFrame codons)
+ {
+ List<AlignedCodonFrame> acfs = getCodonFrames();
+ if (codons != null && acfs != null && !acfs.contains(codons))
+ {
+ acfs.add(codons);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI)
+ */
+ @Override
+ public List<AlignedCodonFrame> getCodonFrame(SequenceI seq)
+ {
+ if (seq == null)
+ {
+ return null;
+ }
+ List<AlignedCodonFrame> cframes = new ArrayList<AlignedCodonFrame>();
+ for (AlignedCodonFrame acf : getCodonFrames())
+ {
+ if (acf.involvesSequence(seq))
+ {
+ cframes.add(acf);
+ }
+ }
+ return cframes;
+ }
+
+ /**
+ * Sets the codon frame mappings (replacing any existing mappings). Note the
+ * mappings are set on the dataset alignment instead if there is one.
+ *
+ * @see jalview.datamodel.AlignmentI#setCodonFrames()
+ */
+ @Override
+ public void setCodonFrames(List<AlignedCodonFrame> acfs)
+ {
+ if (dataset != null)
+ {
+ dataset.setCodonFrames(acfs);
+ }
+ else
+ {
+ this.codonFrameList = acfs;
+ }
+ }
+
+ /**
+ * Returns the set of codon frame mappings. Any changes to the returned set
+ * will affect the alignment. The mappings are held on (and read from) the
+ * dataset alignment if there is one.
+ *
+ * @see jalview.datamodel.AlignmentI#getCodonFrames()
+ */
+ @Override
+ public List<AlignedCodonFrame> getCodonFrames()
+ {
+ return dataset != null ? dataset.getCodonFrames() : codonFrameList;
+ }
+
+ /**
+ * Removes the given mapping from the stored set. Note that the mappings are
+ * held on the dataset alignment if there is one.
+ */
+ @Override
+ public boolean removeCodonFrame(AlignedCodonFrame codons)
+ {
+ List<AlignedCodonFrame> acfs = getCodonFrames();
+ if (codons == null || acfs == null)
+ {
+ return false;
+ }
+ return acfs.remove(codons);
+ }
+
+ @Override
+ public void append(AlignmentI toappend)
+ {
+ if (toappend == this)
+ {
+ System.err.println("Self append may cause a deadlock.");
+ }
+ // TODO test this method for a future 2.5 release
+ // currently tested for use in jalview.gui.SequenceFetcher
+ boolean samegap = toappend.getGapCharacter() == getGapCharacter();
+ char oldc = toappend.getGapCharacter();
+ boolean hashidden = toappend.getHiddenSequences() != null
+ && toappend.getHiddenSequences().hiddenSequences != null;
+ // get all sequences including any hidden ones
+ List<SequenceI> sqs = (hashidden) ? toappend.getHiddenSequences()
+ .getFullAlignment().getSequences() : toappend.getSequences();
+ if (sqs != null)
+ {
+ synchronized (sqs)
+ {
+ for (SequenceI addedsq : sqs)
+ {
+ if (!samegap)
+ {
+ char[] oldseq = addedsq.getSequence();
+ for (int c = 0; c < oldseq.length; c++)
+ {
+ if (oldseq[c] == oldc)
+ {
+ oldseq[c] = gapCharacter;
+ }
+ }
+ }
+ addSequence(addedsq);
+ }
+ }
+ }
+ AlignmentAnnotation[] alan = toappend.getAlignmentAnnotation();
+ for (int a = 0; alan != null && a < alan.length; a++)