--- /dev/null
+package jalview.analysis;
+
+/**
+ * implements a weak hash map based on the first four characters of the given
+ * string, normalised to lower case
+ *
+ * @author jprocter
+ *
+ */
+class SeqIdName
+{
+ String id, origid;
+
+ SeqIdName(String s)
+ {
+ if (s != null)
+ {
+ id = new String(s).toLowerCase();
+ origid = new String(s);
+ }
+ else
+ {
+ id = "";
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return ((id.length() >= 4) ? id.substring(0, 4).hashCode() : id
+ .hashCode());
+ }
+
+ @Override
+ public boolean equals(Object s)
+ {
+ if (s == null)
+ {
+ return false;
+ }
+ if (s instanceof SeqIdName)
+ {
+ return this.equals((SeqIdName) s);
+ }
+ else
+ {
+ if (s instanceof String)
+ {
+ return this.equals((String) s);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * matches if one ID properly contains another at a whitespace boundary.
+ * TODO: (JBPNote) These are not efficient. should use char[] for speed
+ * todo: (JBPNote) Set separator characters appropriately
+ *
+ * @param s
+ * SeqIdName
+ * @return boolean
+ */
+ public boolean equals(SeqIdName s)
+ {
+ // TODO: JAL-732 patch for cases when name includes a list of IDs, and the
+ // match contains one ID flanked
+ if (id.length() > s.id.length())
+ {
+ return check_wordmatch(id, s.id);
+ }
+ else
+ {
+ return check_wordmatch(s.id, id);
+ }
+ }
+
+ private boolean check_wordmatch(String longer, String shorter)
+ {
+ boolean elen = longer.length() == shorter.length();
+ int sp = longer.indexOf(shorter);
+ if (sp == -1)
+ {
+ return false;
+ }
+
+ if (sp == 0)
+ {
+ // end of match is word boundary
+ return elen ? true : (SequenceIdMatcher.WORD_SEP.indexOf(longer.charAt(shorter
+ .length() + sp)) > -1);
+ }
+ if (SequenceIdMatcher.WORD_SEP.indexOf(longer.charAt(sp - 1)) > -1)
+ {
+ if (sp + shorter.length() == longer.length())
+ {
+ return true;
+ }
+ else
+ {
+ // end of match is word boundary
+ return elen ? false
+ : sp + shorter.length() == longer.length() ? true
+ : (SequenceIdMatcher.WORD_SEP.indexOf(longer.charAt(shorter
+ .length() + sp)) > -1);
+ }
+ }
+ else
+ {
+ // prefix of match is not a word boundary
+ return false;
+ }
+ }
+
+ public boolean equals(String s)
+ {
+ s = s.toLowerCase(); // TODO: employ faster to lower case operation
+ if (id.length() > s.length())
+ {
+ return check_wordmatch(id, s);
+ }
+ else
+ {
+ return check_wordmatch(s, id);
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return id;
+ }
+
+ public boolean equalsCase(String s)
+ {
+ if (origid.length() > s.length())
+ {
+ return check_wordmatch(origid, s);
+ }
+ else
+ {
+ return check_wordmatch(s, origid);
+ }
+ }
+
+ public boolean equalsCase(SeqIdName sid)
+ {
+ return equalsCase(sid.origid);
+ }
+}
\ No newline at end of file