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