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 }