001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.reflection.storage; 020 021import java.lang.reflect.Field; 022import java.util.WeakHashMap; 023 024import lucee.runtime.type.Struct; 025import lucee.runtime.type.StructImpl; 026 027import org.apache.commons.collections.map.ReferenceMap; 028 029/** 030 * Method Storage Class 031 */ 032public final class WeakFieldStorage { 033 private WeakHashMap map=new WeakHashMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 034 035 /** 036 * returns all fields matching given criteria or null if field does exist 037 * @param clazz clazz to get field from 038 * @param fieldname Name of the Field to get 039 * @return matching Fields as Array 040 */ 041 public synchronized Field[] getFields(Class clazz,String fieldname) { 042 Object o=map.get(clazz); 043 Struct fieldMap; 044 if(o==null) { 045 fieldMap=store(clazz); 046 } 047 else fieldMap=(Struct) o; 048 049 o=fieldMap.get(fieldname,null); 050 if(o==null) return null; 051 return (Field[]) o; 052 053 } 054 055 056 /** 057 * store a class with his methods 058 * @param clazz 059 * @return returns stored Struct 060 */ 061 private StructImpl store(Class clazz) { 062 Field[] fieldsArr=clazz.getFields(); 063 StructImpl fieldsMap=new StructImpl(); 064 for(int i=0;i<fieldsArr.length;i++) { 065 storeField(fieldsArr[i],fieldsMap); 066 } 067 map.put(clazz,fieldsMap); 068 return fieldsMap; 069 } 070 071 /** 072 * stores a single method 073 * @param field 074 * @param fieldsMap 075 */ 076 private void storeField(Field field, StructImpl fieldsMap) { 077 String fieldName=field.getName(); 078 Object o=fieldsMap.get(fieldName,null); 079 Field[] args; 080 if(o==null) { 081 args=new Field[1]; 082 fieldsMap.setEL(fieldName,args); 083 } 084 else { 085 Field[] fs = (Field[]) o; 086 args = new Field[fs.length+1]; 087 for(int i=0;i<fs.length;i++) { 088 fs[i].setAccessible(true); 089 args[i]=fs[i]; 090 } 091 fieldsMap.setEL(fieldName,args); 092 } 093 args[args.length-1]=field; 094 } 095 096}