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 }