001 /**
002 * LTAG-spinal API, an interface to the treebank format introduced by Libin Shen.
003 * Copyright (C) 2007 Lucas Champollion
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 *
018 */
019 package edu.upenn.cis.spinal;
020
021 import java.util.*;
022
023 /**
024 * Implements a way of referring unambiguously to a particular
025 * node in a tree. A Gorn address a<SUB>1</SUB>, a<SUB>2</SUB>,...a<SUB>n-1</SUB>, a<SUB>n</SUB> denotes the
026 * a<SUB>n</SUB>th child of the a<SUB>n-1</SUB>th child of .... the
027 * a<SUB>2</SUB>th child of the root. The root itself is always represented as
028 * zero. Gorn addresses are used in the LTAG-spinal
029 * annotation to specify attachment sites in spinal nodes.
030 * @author Lucas Champollion
031 */
032 public class GornAddress extends ArrayList {
033
034 /**
035 * The symbol used to separate elements of the Gorn address from one another.
036 */
037 public static final String SEPARATOR = ".";
038
039 /**
040 * The separator in regex format.
041 */
042 private static final String SEPARATOR_REGEX = "\\.";
043
044
045 /**
046 * Creates a Gorn address from a string representation.
047 * @param s a string that consists of a series of 1 or more integers separated by dots,
048 * such as <code>0</code> or <code>0.1.1</code>
049 * @throws java.lang.NumberFormatException if the string cannot be parsed
050 * into numbers
051 */
052 public GornAddress(String s) throws NumberFormatException {
053 super();
054 String[] parts = s.split(SEPARATOR_REGEX);
055 for (int i=0; i<parts.length;i++) {
056 this.add(new Integer(parts[i]));
057 }
058 }
059
060 /**
061 * Returns the canonical representation of this Gorn address -- a series of
062 * integers separated by dots.
063 * @return a string like <code>0</code> or <code>0.1.1</code>
064 */
065 public String toString() {
066
067 return this.toString(SEPARATOR);
068 }
069
070 /**
071 * Returns a custom representation of this Gorn address -- a series of
072 * integers separated by a user-supplied argument.
073 *
074 * @param separator the string used to separate the integers
075 * @return a string like <code>0</code> or <code>0_1_1</code> (if <code>_</code>
076 * is provided as the separator)
077 */
078 public String toString(String separator) {
079 StringBuffer s = new StringBuffer(10);
080
081 Iterator iter = this.iterator();
082 while (iter.hasNext()) {
083 Integer current = (Integer) iter.next();
084 s.append(current.toString());
085 s.append(separator);
086 }
087 String result = s.toString();
088 if (result.endsWith(separator)) {
089 result = result.substring(0, result.length()-1);
090 }
091 return result;
092 }
093
094 /**
095 * Returns a hash code based on the canonical representation as indicated
096 * by the {@link #toString()} value.
097 * @return a hash code
098 */
099 public int hashCode() {
100 return this.toString().hashCode();
101 }
102
103
104 /**
105 * Returns if this is equal to another <code>GornAddress</code>.
106 * Two Gorn addresses are equal iff their
107 * canonical representation as indicated by {@link #toString()} is identical.
108 *
109 * @param o the other object
110 * @return a boolean value
111 */
112 public boolean equals(Object o) {
113 if (o instanceof GornAddress) {
114 return this.toString().equals(o.toString());
115 } else {
116 return super.equals(o);
117 }
118 }
119
120 }