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    }