001package com.hfg.bio;
002
003import com.hfg.setting.SettingXML;
004import com.hfg.util.CompareUtil;
005import com.hfg.xml.XMLTag;
006import com.hfg.xml.XMLTaggable;
007
008import java.io.Serializable;
009import java.util.ArrayList;
010import java.util.List;
011
012//------------------------------------------------------------------------------
013/**
014 * Enum-like sequence strand class
015 *
016 * @author J. Alex Taylor, hairyfatguy.com
017 */
018//------------------------------------------------------------------------------
019// com.hfg XML/HTML Coding Library
020//
021// This library is free software; you can redistribute it and/or
022// modify it under the terms of the GNU Lesser General Public
023// License as published by the Free Software Foundation; either
024// version 2.1 of the License, or (at your option) any later version.
025//
026// This library is distributed in the hope that it will be useful,
027// but WITHOUT ANY WARRANTY; without even the implied warranty of
028// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
029// Lesser General Public License for more details.
030//
031// You should have received a copy of the GNU Lesser General Public
032// License along with this library; if not, write to the Free Software
033// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
034//
035// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
036// jataylor@hairyfatguy.com
037//------------------------------------------------------------------------------
038
039public final class Strand implements Serializable, XMLTaggable, Comparable
040{
041
042   private char   mSymbol;
043   private String mName;
044   private int    mIndex;
045
046   private static List sList = new ArrayList(3);
047
048   public static final Strand FORWARD    = new Strand('+', "Forward");
049   public static final Strand PLUS       = Strand.FORWARD;
050   public static final Strand SENSE      = Strand.FORWARD;
051   public static final Strand REVERSE    = new Strand('-', "Reverse");
052   public static final Strand MINUS      = Strand.REVERSE;
053   public static final Strand ANITSENSE  = Strand.REVERSE;
054
055
056   //###########################################################################
057   // CONSTRUCTORS
058   //###########################################################################
059
060   //--------------------------------------------------------------------------
061   private Strand(char inSymbol, String inName)
062   {
063      mSymbol = inSymbol;
064      mName = inName;
065      mIndex = sList.size();
066      sList.add(this);
067   }
068
069   //###########################################################################
070   // PUBLIC METHODS
071   //###########################################################################
072
073   //--------------------------------------------------------------------------
074   public final char getSymbol()
075   {
076      return mSymbol;
077   }
078
079   //--------------------------------------------------------------------------
080   public final String getName()
081   {
082      return mName;
083   }
084
085   //--------------------------------------------------------------------------
086   @Override
087   public final String toString()
088   {
089      return mName;
090   }
091
092   //--------------------------------------------------------------------------
093   @Override
094   public final int hashCode()
095   {
096      return super.hashCode();
097   }
098
099   //--------------------------------------------------------------------------
100   @Override
101   public final boolean equals(Object inObj2)
102   {
103      return (0 == compareTo(inObj2));
104   }
105
106   //--------------------------------------------------------------------------
107   @Override
108   public int compareTo(Object inObj2)
109   {
110      int result = -1;
111
112      if (inObj2 != null
113            && inObj2 instanceof Strand)
114      {
115         Strand strand2 = (Strand) inObj2;
116
117         result = CompareUtil.compare(mIndex, strand2.mIndex);
118      }
119
120      return result;
121   }
122
123   //--------------------------------------------------------------------------
124   public XMLTag toXMLTag()
125   {
126      XMLTag tag = new XMLTag(HfgBioXML.STRAND_TAG);
127      tag.setAttribute(SettingXML.CLASS_ATT, getClass().getName());
128      tag.setAttribute(SettingXML.ENUM_ATT, "true");
129      tag.setContent(getName());
130
131      return tag;
132   }
133
134   //--------------------------------------------------------------------------
135   public static Strand[] values()
136   {
137      return new Strand[] { Strand.FORWARD, Strand.REVERSE };
138   }
139
140   //--------------------------------------------------------------------------
141   public static Strand valueOf(String inValue)
142   {
143      Strand strand = null;
144
145      if (inValue != null)
146      {
147         if (inValue.equalsIgnoreCase("+")
148             || inValue.equalsIgnoreCase("plus")
149             || inValue.equalsIgnoreCase("sense")
150             || inValue.equalsIgnoreCase("f")
151             || inValue.equalsIgnoreCase("forward"))
152         {
153            strand = Strand.FORWARD;
154         }
155         else if (inValue.equalsIgnoreCase("-")
156             || inValue.equalsIgnoreCase("minus")
157             || inValue.equalsIgnoreCase("antisense")
158             || inValue.equalsIgnoreCase("r")
159             || inValue.equalsIgnoreCase("reverse"))
160         {
161            strand = Strand.REVERSE;
162         }
163         else
164         {
165            throw new RuntimeException("'" + inValue + "' is not a recognized Strand value.");
166         }
167      }
168
169      return strand;
170   }
171
172   //--------------------------------------------------------------------------
173   /**
174    * This method is called after de-serialization, allowing the object
175    * to nominate a replacement object to be used in the output
176    * graph instead of this object. We don't want multiple objects of each type
177    * to exist in a target VM, so instances replace themselves with
178    * local objects.
179    */
180   private Object readResolve()
181   {
182      return sList.get(mIndex);
183   }
184}