001    package railo.runtime.reflection.storage;
002    
003    import java.lang.reflect.Field;
004    import java.util.WeakHashMap;
005    
006    import org.apache.commons.collections.map.ReferenceMap;
007    
008    import railo.runtime.type.Struct;
009    import railo.runtime.type.StructImpl;
010    
011    /**
012     * Method Storage Class
013     */
014    public final class WeakFieldStorage {
015            private WeakHashMap map=new WeakHashMap(ReferenceMap.SOFT,ReferenceMap.SOFT);
016            
017            /**
018             * returns all fields matching given criteria or null if field does exist
019             * @param clazz clazz to get field from
020             * @param fieldname Name of the Field to get
021             * @return matching Fields as Array
022             */
023            public synchronized Field[] getFields(Class clazz,String fieldname) {
024                    Object o=map.get(clazz);
025                    Struct fieldMap;
026                    if(o==null) {
027                            fieldMap=store(clazz);
028                    }
029                    else fieldMap=(Struct) o;
030                    
031                    o=fieldMap.get(fieldname,null);
032                    if(o==null) return null;
033                    return (Field[]) o;
034                    
035            }
036    
037    
038            /**
039             * store a class with his methods
040             * @param clazz
041             * @return returns stored Struct
042             */
043            private StructImpl store(Class clazz) {
044                    Field[] fieldsArr=clazz.getFields();
045                    StructImpl fieldsMap=new StructImpl();
046                    for(int i=0;i<fieldsArr.length;i++) {
047                            storeField(fieldsArr[i],fieldsMap);
048                    }
049                    map.put(clazz,fieldsMap);
050                    return fieldsMap;
051            }
052    
053            /**
054             * stores a single method
055             * @param field
056             * @param fieldsMap
057             */
058            private void storeField(Field field, StructImpl fieldsMap) {
059                    String fieldName=field.getName();
060                    Object o=fieldsMap.get(fieldName,null);         
061                    Field[] args;
062                    if(o==null) {
063                            args=new Field[1];
064                            fieldsMap.setEL(fieldName,args);
065                    }
066                    else {
067                            Field[] fs = (Field[]) o;
068                            args = new Field[fs.length+1];
069                            for(int i=0;i<fs.length;i++) {
070                                fs[i].setAccessible(true);
071                                    args[i]=fs[i];
072                            }
073                            fieldsMap.setEL(fieldName,args);
074                    }
075                    args[args.length-1]=field;
076            }
077    
078    }