001 package org.maltparser.core.io.dataformat;
002
003 import org.maltparser.core.exception.MaltChainedException;
004 import org.maltparser.core.symbol.SymbolTable;
005 import org.maltparser.core.symbol.SymbolTableHandler;
006
007 /**
008 *
009 *
010 * @author Johan Hall
011 * @since 1.0
012 **/
013 public class ColumnDescription implements Comparable<ColumnDescription> {
014 // Categories
015 public static final int INPUT = 1;
016 public static final int HEAD = 2;
017 public static final int DEPENDENCY_EDGE_LABEL = 3;
018 public static final int PHRASE_STRUCTURE_EDGE_LABEL = 4;
019 public static final int PHRASE_STRUCTURE_NODE_LABEL = 5;
020 public static final int SECONDARY_EDGE_LABEL = 6;
021 public static final int IGNORE = 7;
022
023 // Types
024 public static final int STRING = 1;
025 public static final int INTEGER = 2;
026 public static final int BOOLEAN = 3;
027 public static final int REAL = 4;
028
029 private static int positionCounter = 0;
030 private int position;
031 private String name;
032 private int category;
033 private int type;
034 private String defaultOutput;
035 private SymbolTable symbolTable;
036 private String nullValueStrategy;
037 private boolean internal;
038 private int cachedHash;
039
040 public ColumnDescription(String name, String category, String type, String defaultOutput, SymbolTableHandler symbolTables, String nullValueStrategy, boolean internal) throws MaltChainedException {
041 setPosition(positionCounter++);
042 setName(name);
043 setCategory(category);
044 setType(type);
045 setDefaultOutput(defaultOutput);
046 setNullValueStrategy(nullValueStrategy);
047 setInternal(internal);
048 createSymbolTable(symbolTables);
049 }
050
051 public ColumnDescription(String name, int category, int type, String defaultOutput, SymbolTableHandler symbolTables, String nullValueStrategy, boolean internal) throws MaltChainedException {
052 setPosition(positionCounter++);
053 setName(name);
054 setCategory(category);
055 setType(type);
056 setDefaultOutput(defaultOutput);
057 setNullValueStrategy(nullValueStrategy);
058 setInternal(internal);
059 createSymbolTable(symbolTables);
060 }
061
062 private void createSymbolTable(SymbolTableHandler symbolTables) throws MaltChainedException {
063 if (type == ColumnDescription.STRING || type == ColumnDescription.INTEGER || type == ColumnDescription.BOOLEAN || type == ColumnDescription.REAL) {
064 symbolTable = symbolTables.addSymbolTable(name, category, nullValueStrategy);
065 } else {
066 symbolTable = null;
067 }
068 }
069
070 public int getPosition() {
071 return position;
072 }
073
074 public String getName() {
075 return name;
076 }
077
078 public int getCategory() {
079 return category;
080 }
081
082 public int getType() {
083 return type;
084 }
085
086 public String getDefaultOutput() {
087 return defaultOutput;
088 }
089
090 public SymbolTable getSymbolTable() {
091 return symbolTable;
092 }
093
094 public String getNullValueStrategy() {
095 return nullValueStrategy;
096 }
097
098 private void setNullValueStrategy(String nullValueStrategy) {
099 this.nullValueStrategy = nullValueStrategy;
100 }
101
102 public boolean isInternal() {
103 return internal;
104 }
105
106 private void setInternal(boolean internal) {
107 this.internal = internal;
108 }
109
110 private void setPosition(int position) throws MaltChainedException {
111 if (position >= 0) {
112 this.position = position;
113 } else {
114 throw new DataFormatException("Position value for column must be a non-negative value. ");
115 }
116 }
117
118 private void setName(String name) {
119 this.name = name.toUpperCase();
120 }
121
122 private void setCategory(String category) throws MaltChainedException {
123 if (category.toUpperCase().equals("INPUT")) {
124 this.category = ColumnDescription.INPUT;
125 } else if (category.toUpperCase().equals("HEAD")) {
126 this.category = ColumnDescription.HEAD;
127 } else if (category.toUpperCase().equals("OUTPUT")) {
128 this.category = ColumnDescription.DEPENDENCY_EDGE_LABEL;
129 } else if (category.toUpperCase().equals("DEPENDENCY_EDGE_LABEL")) {
130 this.category = ColumnDescription.DEPENDENCY_EDGE_LABEL;
131 } else if (category.toUpperCase().equals("PHRASE_STRUCTURE_EDGE_LABEL")) {
132 this.category = ColumnDescription.PHRASE_STRUCTURE_EDGE_LABEL;
133 } else if (category.toUpperCase().equals("PHRASE_STRUCTURE_NODE_LABEL")) {
134 this.category = ColumnDescription.PHRASE_STRUCTURE_NODE_LABEL;
135 } else if (category.toUpperCase().equals("SECONDARY_EDGE_LABEL")) {
136 this.category = ColumnDescription.SECONDARY_EDGE_LABEL;
137 } else if (category.toUpperCase().equals("IGNORE")) {
138 this.category = ColumnDescription.IGNORE;
139 } else {
140 throw new DataFormatException("The category '"+category+"' is not allowed. ");
141 }
142 }
143
144 private void setCategory(int category) throws MaltChainedException {
145 if (category >= INPUT && category <= IGNORE) {
146 this.category = category;
147 } else {
148 throw new DataFormatException("The category '"+category+"' is not allowed. ");
149 }
150 }
151
152 private void setType(String type) throws MaltChainedException {
153 if (type.toUpperCase().equals("STRING")) {
154 this.type = ColumnDescription.STRING;
155 } else if (type.toUpperCase().equals("INTEGER")) {
156 this.type = ColumnDescription.INTEGER;
157 } else if (type.toUpperCase().equals("BOOLEAN")) {
158 this.type = ColumnDescription.BOOLEAN;
159 } else if (type.toUpperCase().equals("REAL")) {
160 this.type = ColumnDescription.REAL;
161 } else if (type.toUpperCase().equals("ECHO")) {
162 // ECHO is removed, but if it occurs in the data format file it will be interpreted as an integer instead.
163 this.type = ColumnDescription.INTEGER;
164 // this.type = ColumnDescription.ECHO;
165 // } else if (type.toUpperCase().equals("IGNORE")) {
166 // this.type = ColumnDescription.IGNORE;
167 } else {
168 throw new DataFormatException("The column type '"+type+"' is not allowed. ");
169 }
170 }
171
172 private void setType(int type) throws MaltChainedException {
173 if (category >= STRING && category <= REAL) {
174 this.type = type;
175 } else {
176 throw new DataFormatException("The column type '"+type+"' is not allowed. ");
177 }
178 }
179 private void setDefaultOutput(String defaultOutput) {
180 this.defaultOutput = defaultOutput;
181 }
182
183 public int compareTo(ColumnDescription that) {
184 final int BEFORE = -1;
185 final int EQUAL = 0;
186 final int AFTER = 1;
187 if (this == that) return EQUAL;
188 if (this.position < that.position) return BEFORE;
189 if (this.position > that.position) return AFTER;
190 return EQUAL;
191 }
192
193 public boolean equals(Object obj) {
194 if (this == obj)
195 return true;
196 if (obj == null)
197 return false;
198 if (getClass() != obj.getClass())
199 return false;
200 ColumnDescription objC = (ColumnDescription)obj;
201 return type == objC.type && category == objC.category &&((name == null) ? objC.name == null : name.equals(objC.name));
202 }
203
204 public int hashCode() {
205 if (cachedHash == 0) {
206 int hash = 31*7 + type;
207 hash = 31*hash + category;
208 hash = 31*hash + (null == name ? 0 : name.hashCode());
209 cachedHash = hash;
210 }
211 return cachedHash;
212 }
213
214
215 public String toString() {
216 final StringBuilder sb = new StringBuilder();
217 sb.append(name);
218 sb.append('\t');
219 sb.append(category);
220 sb.append('\t');
221 sb.append(type);
222 if (defaultOutput != null) {
223 sb.append('\t');
224 sb.append(defaultOutput);
225 }
226 return sb.toString();
227 }
228 }