001 package railo.runtime.type; 002 003 import java.io.Externalizable; 004 import java.io.IOException; 005 import java.io.ObjectInput; 006 import java.io.ObjectOutput; 007 import java.util.Date; 008 009 import railo.commons.lang.SizeOf; 010 import railo.commons.lang.StringUtil; 011 import railo.runtime.exp.CasterException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.op.Castable; 014 import railo.runtime.op.Caster; 015 import railo.runtime.op.Operator; 016 import railo.runtime.op.date.DateCaster; 017 import railo.runtime.type.Collection.Key; 018 import railo.runtime.type.dt.DateTime; 019 020 public class KeyImpl implements Collection.Key,Castable,Comparable,Sizeable,Externalizable { 021 022 //private boolean intern; 023 private String key; 024 private String lcKey; 025 private String ucKey; 026 //private int hashcode; 027 028 public KeyImpl() { 029 // DO NOT USE, JUST FOR UNSERIALIZE 030 } 031 032 033 public void writeExternal(ObjectOutput out) throws IOException { 034 out.writeObject(key); 035 out.writeObject(lcKey); 036 out.writeObject(ucKey); 037 //out.writeBoolean(intern); 038 } 039 public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException { 040 key=(String) in.readObject(); 041 lcKey=((String) in.readObject()); 042 ucKey=(String) in.readObject(); 043 //intern= in.readBoolean(); 044 //if(intern)lcKey=lcKey.intern(); 045 } 046 047 048 protected KeyImpl(String key) { 049 this.key=key; 050 this.lcKey=key.toLowerCase(); 051 //RefIntegerImpl count=log.get(key); 052 //if(count!=null) count.plus(1); 053 //else log.put(key, new RefIntegerImpl(1)); 054 055 } 056 057 /*public static void print(){ 058 //Iterator<Entry<String, RefIntegerImpl>> it = log.entrySet().iterator(); 059 String[] keys = log.keySet().toArray(new String[log.size()]); 060 Arrays.sort(keys); 061 int total=0,big=0; 062 for(int i=0;i<keys.length;i++){ 063 RefIntegerImpl value = log.get(keys[i]); 064 if(value.toInt()>10 && keys[i].length()<=10 && keys[i].indexOf('.')==-1 && keys[i].indexOf('-')==-1) { 065 print.e("public static final Key "+keys[i]+"=KeyImpl.intern(\""+keys[i]+"\");"); 066 big++; 067 } 068 total++; 069 } 070 print.e("total:"+total); 071 print.e("big:"+big); 072 }*/ 073 074 075 076 /*private KeyImpl(String key, boolean intern) { 077 this.key=key; 078 this.lcKey=intern?key.toLowerCase():key.toLowerCase(); 079 this.intern=intern; 080 }*/ 081 082 /** 083 * for dynamic loading of key objects 084 * @param string 085 * @return 086 */ 087 public static Collection.Key init(String key) { 088 return new KeyImpl(key); 089 } 090 091 092 public static Collection.Key _const(String key) { 093 return new KeyImpl(key); 094 } 095 096 097 /** 098 * used for static iniatisation of a key object (used by compiler) 099 * @param string 100 * @return 101 */ 102 public synchronized static Collection.Key getInstance(String key) { 103 //if(KeyConstants.getFieldName(key)!=null)print.ds(key); 104 return new KeyImpl(key); 105 } 106 107 108 public synchronized static Collection.Key intern(String key) { 109 //if(KeyConstants.getFieldName(key)!=null)print.ds(key); 110 /*Long l= keys.get(key); 111 String st=ExceptionUtil.getStacktrace(new Exception("Stack trace"), false); 112 String[] arr = railo.runtime.type.List.listToStringArray(st,'\n'); 113 if(l!=null) { 114 if(arr[2].indexOf("/Users/mic/")==-1) 115 keys.put(key, l.longValue()+1); 116 } 117 else { 118 119 if(arr[2].indexOf("/Users/mic/")==-1) 120 keys.put(key, 1L); 121 }*/ 122 return new KeyImpl(key); 123 } 124 125 /*public static void dump(){ 126 Iterator<Entry<String, Long>> it = keys.entrySet().iterator(); 127 while(it.hasNext()){ 128 Entry<String, Long> e = it.next(); 129 if(e.getValue()>1)print.o(e.getKey()+":"+e.getValue()); 130 } 131 }*/ 132 133 @Override 134 public char charAt(int index) { 135 return key.charAt(index); 136 } 137 138 @Override 139 public char lowerCharAt(int index) { 140 return lcKey.charAt(index); 141 } 142 143 public char upperCharAt(int index) { 144 return getUpperString().charAt(index); 145 } 146 147 @Override 148 public String getLowerString() { 149 return lcKey; 150 } 151 152 public String getUpperString() { 153 if(ucKey==null)ucKey=StringUtil.toUpperCase(key); 154 return ucKey; 155 } 156 157 @Override 158 public String toString() { 159 return key; 160 } 161 162 @Override 163 public String getString() { 164 return key; 165 } 166 167 @Override 168 public boolean equals(Object other) {//call++; 169 if(this==other) return true; 170 if(other instanceof KeyImpl) { 171 return lcKey.equals((((KeyImpl)other).lcKey)); 172 } 173 if(other instanceof String) { 174 return key.equalsIgnoreCase((String)other); 175 } 176 if(other instanceof Key) { 177 return lcKey.equalsIgnoreCase(((Key)other).getLowerString()); 178 } 179 return false; 180 } 181 182 183 @Override 184 public boolean equalsIgnoreCase(Key other) { 185 if(this==other) return true; 186 if(other instanceof KeyImpl) { 187 return lcKey.equals((((KeyImpl)other).lcKey)); 188 } 189 return lcKey.equalsIgnoreCase(other.getLowerString()); 190 } 191 192 193 194 @Override 195 public int hashCode() { 196 return lcKey.hashCode(); 197 } 198 199 @Override 200 public int getId() { 201 return hashCode(); 202 } 203 204 @Override 205 public boolean castToBooleanValue() throws PageException { 206 return Caster.toBooleanValue(key); 207 } 208 209 @Override 210 public Boolean castToBoolean(Boolean defaultValue) { 211 return Caster.toBoolean(key,defaultValue); 212 } 213 214 @Override 215 public DateTime castToDateTime() throws PageException { 216 return Caster.toDatetime(key,null); 217 } 218 219 @Override 220 public DateTime castToDateTime(DateTime defaultValue) { 221 return DateCaster.toDateAdvanced(key,true,null,defaultValue); 222 } 223 224 @Override 225 public double castToDoubleValue() throws PageException { 226 return Caster.toDoubleValue(key); 227 } 228 229 @Override 230 public double castToDoubleValue(double defaultValue) { 231 return Caster.toDoubleValue(key,defaultValue); 232 } 233 234 @Override 235 public String castToString() throws PageException { 236 return key; 237 } 238 239 @Override 240 public String castToString(String defaultValue) { 241 return key; 242 } 243 244 @Override 245 public int compareTo(boolean b) throws PageException { 246 return Operator.compare(key, b); 247 } 248 249 @Override 250 public int compareTo(DateTime dt) throws PageException { 251 return Operator.compare(key, (Date)dt); 252 } 253 254 @Override 255 public int compareTo(double d) throws PageException { 256 return Operator.compare(key, d); 257 } 258 259 @Override 260 public int compareTo(String str) throws PageException { 261 return Operator.compare(key, str); 262 } 263 264 265 public int compareTo(Object o) { 266 try { 267 return Operator.compare(key, o); 268 } catch (PageException e) { 269 ClassCastException cce = new ClassCastException(e.getMessage()); 270 cce.setStackTrace(e.getStackTrace()); 271 throw cce; 272 273 } 274 } 275 276 277 public static Array toUpperCaseArray(Key[] keys) { 278 ArrayImpl arr=new ArrayImpl(); 279 for(int i=0;i<keys.length;i++) { 280 arr._append(((KeyImpl)keys[i]).getUpperString()); 281 } 282 return arr; 283 } 284 public static Array toLowerCaseArray(Key[] keys) { 285 ArrayImpl arr=new ArrayImpl(); 286 for(int i=0;i<keys.length;i++) { 287 arr._append(((KeyImpl)keys[i]).getLowerString()); 288 } 289 return arr; 290 } 291 292 public static Array toArray(Key[] keys) { 293 ArrayImpl arr=new ArrayImpl(); 294 for(int i=0;i<keys.length;i++) { 295 arr._append(((KeyImpl)keys[i]).getString()); 296 } 297 return arr; 298 } 299 300 public static String toUpperCaseList(Key[] array, String delimiter) { 301 if(array.length==0) return ""; 302 StringBuffer sb=new StringBuffer(((KeyImpl)array[0]).getUpperString()); 303 304 if(delimiter.length()==1) { 305 char c=delimiter.charAt(0); 306 for(int i=1;i<array.length;i++) { 307 sb.append(c); 308 sb.append(((KeyImpl)array[i]).getUpperString()); 309 } 310 } 311 else { 312 for(int i=1;i<array.length;i++) { 313 sb.append(delimiter); 314 sb.append(((KeyImpl)array[i]).getUpperString()); 315 } 316 } 317 return sb.toString(); 318 } 319 320 public static String toList(Key[] array, String delimiter) { 321 if(array.length==0) return ""; 322 StringBuilder sb=new StringBuilder(((KeyImpl)array[0]).getString()); 323 324 if(delimiter.length()==1) { 325 char c=delimiter.charAt(0); 326 for(int i=1;i<array.length;i++) { 327 sb.append(c); 328 sb.append((array[i]).getString()); 329 } 330 } 331 else { 332 for(int i=1;i<array.length;i++) { 333 sb.append(delimiter); 334 sb.append((array[i]).getString()); 335 } 336 } 337 return sb.toString(); 338 } 339 340 public static String toLowerCaseList(Key[] array, String delimiter) { 341 if(array.length==0) return ""; 342 StringBuffer sb=new StringBuffer(((KeyImpl)array[0]).getLowerString()); 343 344 if(delimiter.length()==1) { 345 char c=delimiter.charAt(0); 346 for(int i=1;i<array.length;i++) { 347 sb.append(c); 348 sb.append(((KeyImpl)array[i]).getLowerString()); 349 } 350 } 351 else { 352 for(int i=1;i<array.length;i++) { 353 sb.append(delimiter); 354 sb.append(((KeyImpl)array[i]).getLowerString()); 355 } 356 } 357 return sb.toString(); 358 } 359 360 public static Collection.Key toKey(Object obj, Collection.Key defaultValue) { 361 if(obj instanceof Collection.Key) return (Collection.Key) obj; 362 String str = Caster.toString(obj,null); 363 if(str==null) return defaultValue; 364 return init(str); 365 } 366 367 public static Collection.Key toKey(Object obj) throws CasterException { 368 if(obj instanceof Collection.Key) return (Collection.Key) obj; 369 String str = Caster.toString(obj,null); 370 if(str==null) throw new CasterException(obj,Collection.Key.class); 371 return init(str); 372 } 373 374 375 public long sizeOf() { 376 return 377 SizeOf.size(this.key)+ 378 SizeOf.size(this.lcKey)+ 379 SizeOf.size(this.ucKey)+ 380 SizeOf.REF_SIZE; 381 } 382 383 @Override 384 public int length() { 385 return key.length(); 386 } 387 388 389 public static Key[] toKeyArray(String[] arr) { 390 if(arr==null) return null; 391 392 Key[] keys=new Key[arr.length]; 393 for(int i=0;i<keys.length;i++){ 394 keys[i]=init(arr[i]); 395 } 396 return keys; 397 } 398 }