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    import railo.runtime.type.util.KeyConstants;
020    
021    public class KeyImpl implements Collection.Key,Castable,Comparable,Sizeable,Externalizable {
022            //public static HashMap<String,RefIntegerImpl> log=new HashMap<String,RefIntegerImpl>();
023            
024    
025            public static final Collection.Key ACTION=KeyConstants._action;
026            public static final Key CFID=KeyConstants._cfid;
027            public static final Key CFTOKEN=KeyConstants._cftoken;
028            public static final Key DETAIL=KeyConstants._detail;
029            public static final Key ID=KeyConstants._id;
030            public static final Key RETURN_FORMAT =KeyConstants._returnFormat;
031            public static final Key NAME=KeyConstants._name;
032            public static final Key NAME_UC=KeyConstants._NAME;
033            public static final Key DATA=KeyConstants._data;
034            public static final Key S3=KeyConstants._s3;
035            public static final Key SIZE=KeyConstants._size;
036            public static final Key SUPER=KeyConstants._super;
037            public static final Key SUPER_UC=KeyConstants._SUPER;
038            public static final Key TEMPLATE=KeyConstants._template;
039            public static final Key THIS=KeyConstants._this;
040            public static final Key THIS_UC=KeyConstants._THIS;
041            public static final Key TIME=KeyConstants._time;
042            public static final Key TYPE=KeyConstants._type;
043            public static final Key HINT =          KeyConstants._hint;
044            public static final Key REQUIRED =      KeyConstants._required;
045            public static final Key DEFAULT =               KeyConstants._default;
046            public static final Key DATA_SOURCE =           KeyConstants._datasource;
047            
048    
049            public static final Key ARGUMENT_COLLECTION = KeyConstants._argumentCollection;
050            public static final Key ACCESS =                KeyConstants._access;
051            public static final Key OUTPUT =                KeyConstants._output;
052            public static final Key RETURN_TYPE =   KeyConstants._returntype;
053            public static final Key DESCRIPTION =   KeyConstants._description;
054            public static final Key OWNER =         KeyConstants._owner;
055            public static final Key DISPLAY_NAME = KeyConstants._displayname;
056            public static final Key PARAMETERS =    KeyConstants._parameters;
057            
058    
059            public static final Key VALUE = KeyConstants._value;
060            public static final Key PATH = KeyConstants._path;
061            public static final Key ENTRY = KeyConstants._entry;
062            public static final Key KEY = KeyConstants._key;
063            public static final Key LINE = KeyConstants._line;
064            public static final Key COLUMN = KeyConstants._column;
065            public static final Key ARGUMENTS = KeyConstants._arguments;
066            public static final Key STATUS = KeyConstants._status;
067            public static final Key THREAD = KeyConstants._thread;
068            public static final Key VARIABLES = KeyConstants._variables;
069            public static final Key FIELD_NAMES = KeyConstants._fieldnames;
070            public static final Key LOCAL = KeyConstants._local;
071            public static final Key SERVER = KeyConstants._server;
072            public static final Key EXCEPTIONS = KeyConstants._exceptions;
073            public static final Key BODY = KeyConstants._body;
074            public static final Key TITLE = KeyConstants._title;
075            public static final Key URL = KeyConstants._url;
076            public static final Key LABEL = KeyConstants._label;
077            public static final Key TOTAL = KeyConstants._total;
078            
079            
080            
081            
082            //private boolean intern;
083            private String key;
084            private String lcKey;
085            private String ucKey;
086            //private int hashcode;
087            
088            public KeyImpl() {
089                    // DO NOT USE, JUST FOR UNSERIALIZE
090            }
091            
092            
093            public void writeExternal(ObjectOutput out) throws IOException {
094                    out.writeObject(key);
095                    out.writeObject(lcKey);
096                    out.writeObject(ucKey);
097                    //out.writeBoolean(intern);
098            }
099            public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {
100                    key=(String) in.readObject();
101                    lcKey=((String) in.readObject());
102                    ucKey=(String) in.readObject();
103                    //intern= in.readBoolean();
104                    //if(intern)lcKey=lcKey.intern();
105            }
106            
107            
108            protected KeyImpl(String key) {
109                    this.key=key;
110                    this.lcKey=key.toLowerCase();
111                    //RefIntegerImpl count=log.get(key);
112                    //if(count!=null) count.plus(1);
113                    //else log.put(key, new RefIntegerImpl(1));
114                    
115            }
116            
117            /*public static void print(){
118                    //Iterator<Entry<String, RefIntegerImpl>> it = log.entrySet().iterator();
119                    String[] keys = log.keySet().toArray(new String[log.size()]);
120                    Arrays.sort(keys);
121                    int total=0,big=0;
122                    for(int i=0;i<keys.length;i++){
123                            RefIntegerImpl value = log.get(keys[i]);
124                            if(value.toInt()>10 && keys[i].length()<=10 && keys[i].indexOf('.')==-1 && keys[i].indexOf('-')==-1) {
125                                    print.e("public static final Key "+keys[i]+"=KeyImpl.intern(\""+keys[i]+"\");");
126                                    big++;
127                            }
128                            total++;
129                    }
130                    print.e("total:"+total);
131                    print.e("big:"+big);
132            }*/
133            
134            
135            
136            /*private KeyImpl(String key, boolean intern) {
137                    this.key=key;
138                    this.lcKey=intern?key.toLowerCase():key.toLowerCase();
139                    this.intern=intern;
140            }*/     
141            
142            /**
143             * for dynamic loading of key objects
144             * @param string
145             * @return
146             */
147            public static Collection.Key init(String key) {
148                    return new KeyImpl(key);
149            }
150            
151    
152            /**
153             * used for static iniatisation of a key object (used by compiler)
154             * @param string
155             * @return
156             */
157            public synchronized static Collection.Key getInstance(String key) {
158                    return new KeyImpl(key);
159            }
160            
161    
162            public synchronized static Collection.Key intern(String key) {
163                    /*Long l= keys.get(key);
164                    String st=ExceptionUtil.getStacktrace(new Exception("Stack trace"), false);
165                    String[] arr = railo.runtime.type.List.listToStringArray(st,'\n');
166                    if(l!=null) {
167                            if(arr[2].indexOf("/Users/mic/")==-1)
168                                    keys.put(key, l.longValue()+1);
169                    }
170                    else {
171    
172                            if(arr[2].indexOf("/Users/mic/")==-1)
173                                    keys.put(key, 1L);
174                    }*/
175                    return new KeyImpl(key);
176            }
177            
178            /*public static void dump(){
179                    Iterator<Entry<String, Long>> it = keys.entrySet().iterator();
180                    while(it.hasNext()){
181                            Entry<String, Long> e = it.next();
182                            if(e.getValue()>1)print.o(e.getKey()+":"+e.getValue());
183                    }
184            }*/
185            
186            /**
187             * @see railo.runtime.type.Collection.Key#charAt(int)
188             */
189            public char charAt(int index) {
190                    return key.charAt(index);
191            }
192    
193            /**
194             * @see railo.runtime.type.Collection.Key#lowerCharAt(int)
195             */
196            public char lowerCharAt(int index) {
197                    return lcKey.charAt(index);
198            }
199            
200            public char upperCharAt(int index) {
201                    return getUpperString().charAt(index);
202            }
203    
204            /**
205             * @see railo.runtime.type.Collection.Key#getLowerString()
206             */
207            public String getLowerString() {
208                    return lcKey;
209            }
210            
211            public String getUpperString() {
212                    if(ucKey==null)ucKey=StringUtil.toUpperCase(key);
213                    return ucKey;
214            }
215    
216            /**
217             * @see java.lang.Object#toString()
218             */
219            public String toString() {
220                    return key;
221            }
222    
223            /**
224             * @see railo.runtime.type.Collection.Key#getString()
225             */
226            public String getString() {
227                    return key;
228            }
229    
230            /**
231             *
232             * @see java.lang.Object#equals(java.lang.Object)
233             */
234            public boolean equals(Object other) {//call++;
235                    
236                    
237                    if(other instanceof KeyImpl)    {
238                            /*if(intern && ((KeyImpl)other).intern) {//eq++;
239                                    return lcKey==(((KeyImpl)other).lcKey);
240                            }*/
241                            return lcKey.equals((((KeyImpl)other).lcKey));
242                            
243                    }
244                    if(other instanceof String)     {
245                            return key.equalsIgnoreCase((String)other);
246                    }
247                    if(other instanceof Key)        {
248                            return lcKey.equalsIgnoreCase(((Key)other).getLowerString());
249                    }
250                    return false;
251            }
252    
253            /**
254             * @see railo.runtime.type.Collection.Key#equalsIgnoreCase(railo.runtime.type.Collection.Key)
255             */
256            public boolean equalsIgnoreCase(Key key) {
257                    return equals(key);
258            }
259    
260            /**
261             * @see java.lang.Object#hashCode()
262             */
263            public int hashCode() {
264                    return lcKey.hashCode();
265            }
266    
267            /**
268             * @see railo.runtime.type.Collection.Key#getId()
269             */
270            public int getId() {
271                    return hashCode();
272            }
273    
274            /**
275             * @see railo.runtime.op.Castable#castToBooleanValue()
276             */
277            public boolean castToBooleanValue() throws PageException {
278                    return Caster.toBooleanValue(key);
279            }
280        
281        /**
282         * @see railo.runtime.op.Castable#castToBoolean(java.lang.Boolean)
283         */
284        public Boolean castToBoolean(Boolean defaultValue) {
285            return Caster.toBoolean(key,defaultValue);
286        }
287    
288            /**
289             * @see railo.runtime.op.Castable#castToDateTime()
290             */
291            public DateTime castToDateTime() throws PageException {
292                    return Caster.toDatetime(key,null);
293            }
294        
295        /**
296         * @see railo.runtime.op.Castable#castToDateTime(railo.runtime.type.dt.DateTime)
297         */
298        public DateTime castToDateTime(DateTime defaultValue) {
299            return DateCaster.toDateAdvanced(key,true,null,defaultValue);
300        }
301    
302            /**
303             * @see railo.runtime.op.Castable#castToDoubleValue()
304             */
305            public double castToDoubleValue() throws PageException {
306                    return Caster.toDoubleValue(key);
307            }
308        
309        /**
310         * @see railo.runtime.op.Castable#castToDoubleValue(double)
311         */
312        public double castToDoubleValue(double defaultValue) {
313            return Caster.toDoubleValue(key,defaultValue);
314        }
315    
316            /**
317             * @see railo.runtime.op.Castable#castToString()
318             */
319            public String castToString() throws PageException {
320                    return key;
321            }
322    
323            /**
324             * @see railo.runtime.op.Castable#castToString(java.lang.String)
325             */
326            public String castToString(String defaultValue) {
327                    return key;
328            }
329    
330            /**
331             * @see railo.runtime.op.Castable#compare(boolean)
332             */
333            public int compareTo(boolean b) throws PageException {
334                    return Operator.compare(key, b);
335            }
336    
337            /**
338             * @see railo.runtime.op.Castable#compareTo(railo.runtime.type.dt.DateTime)
339             */
340            public int compareTo(DateTime dt) throws PageException {
341                    return Operator.compare(key, (Date)dt);
342            }
343    
344            /**
345             * @see railo.runtime.op.Castable#compareTo(double)
346             */
347            public int compareTo(double d) throws PageException {
348                    return Operator.compare(key, d);
349            }
350    
351            /**
352             * @see railo.runtime.op.Castable#compareTo(java.lang.String)
353             */
354            public int compareTo(String str) throws PageException {
355                    return Operator.compare(key, str);
356            }
357            
358    
359            public int compareTo(Object o) {
360                    try {
361                            return Operator.compare(key, o);
362                    } catch (PageException e) {
363                            ClassCastException cce = new ClassCastException(e.getMessage());
364                            cce.setStackTrace(e.getStackTrace());
365                            throw cce;
366                            
367                    }
368            }
369            
370    
371            public static Array toUpperCaseArray(Key[] keys) {
372                    ArrayImpl arr=new ArrayImpl();
373                    for(int i=0;i<keys.length;i++) {
374                            arr._append(((KeyImpl)keys[i]).getUpperString());
375                    }
376                    return arr;
377            }
378            public static Array toLowerCaseArray(Key[] keys) {
379                    ArrayImpl arr=new ArrayImpl();
380                    for(int i=0;i<keys.length;i++) {
381                            arr._append(((KeyImpl)keys[i]).getLowerString());
382                    }
383                    return arr;
384            }
385            
386            public static Array toArray(Key[] keys) {
387                    ArrayImpl arr=new ArrayImpl();
388                    for(int i=0;i<keys.length;i++) {
389                            arr._append(((KeyImpl)keys[i]).getString());
390                    }
391                    return arr;
392            }
393    
394            public static String toUpperCaseList(Key[] array, String delimeter) {
395                    if(array.length==0) return "";
396                    StringBuffer sb=new StringBuffer(((KeyImpl)array[0]).getUpperString());
397                    
398                    if(delimeter.length()==1) {
399                            char c=delimeter.charAt(0);
400                            for(int i=1;i<array.length;i++) {
401                                    sb.append(c);
402                                    sb.append(((KeyImpl)array[i]).getUpperString());
403                            }
404                    }
405                    else {
406                            for(int i=1;i<array.length;i++) {
407                                    sb.append(delimeter);
408                                    sb.append(((KeyImpl)array[i]).getUpperString());
409                            }
410                    }
411                    return sb.toString();
412            }
413    
414            public static String toList(Key[] array, String delimeter) {
415                    if(array.length==0) return "";
416                    StringBuffer sb=new StringBuffer(((KeyImpl)array[0]).getString());
417                    
418                    if(delimeter.length()==1) {
419                            char c=delimeter.charAt(0);
420                            for(int i=1;i<array.length;i++) {
421                                    sb.append(c);
422                                    sb.append(((KeyImpl)array[i]).getString());
423                            }
424                    }
425                    else {
426                            for(int i=1;i<array.length;i++) {
427                                    sb.append(delimeter);
428                                    sb.append(((KeyImpl)array[i]).getString());
429                            }
430                    }
431                    return sb.toString();
432            }
433    
434            public static String toLowerCaseList(Key[] array, String delimeter) {
435                    if(array.length==0) return "";
436                    StringBuffer sb=new StringBuffer(((KeyImpl)array[0]).getLowerString());
437                    
438                    if(delimeter.length()==1) {
439                            char c=delimeter.charAt(0);
440                            for(int i=1;i<array.length;i++) {
441                                    sb.append(c);
442                                    sb.append(((KeyImpl)array[i]).getLowerString());
443                            }
444                    }
445                    else {
446                            for(int i=1;i<array.length;i++) {
447                                    sb.append(delimeter);
448                                    sb.append(((KeyImpl)array[i]).getLowerString());
449                            }
450                    }
451                    return sb.toString();
452            }
453    
454            public static Collection.Key toKey(Object obj, Collection.Key defaultValue) {
455                    if(obj instanceof Collection.Key) return (Collection.Key) obj;
456                    String str = Caster.toString(obj,null);
457                    if(str==null) return defaultValue;
458                    return init(str);
459            }
460    
461            public static Collection.Key toKey(Object obj) throws CasterException {
462                    if(obj instanceof Collection.Key) return (Collection.Key) obj;
463                    String str = Caster.toString(obj,null);
464                    if(str==null) throw new CasterException(obj,Collection.Key.class);
465                    return init(str);
466            }
467    
468    
469            public long sizeOf() {
470                    return 
471                    SizeOf.size(this.key)+
472                    SizeOf.size(this.lcKey)+
473                    SizeOf.size(this.ucKey)+
474                    SizeOf.REF_SIZE;
475            }
476            
477    }