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 }