001 package railo.runtime.op; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 import java.util.Date; 006 import java.util.HashMap; 007 import java.util.Iterator; 008 import java.util.List; 009 import java.util.ListIterator; 010 import java.util.Map; 011 012 import railo.commons.lang.ClassException; 013 import railo.commons.lang.ClassUtil; 014 import railo.commons.lang.StringUtil; 015 import railo.runtime.converter.JavaConverter; 016 import railo.runtime.exp.PageException; 017 import railo.runtime.type.Collection; 018 import railo.runtime.type.CollectionPlus; 019 import railo.runtime.type.Duplicable; 020 import railo.runtime.type.UDF; 021 022 023 /** 024 * 025 * 026 * To change the template for this generated type comment go to 027 * Window - Preferences - Java - Code Generation - Code and Comments 028 */ 029 public final class Duplicator { 030 031 /** 032 * primitive value duplication (do nothing, value type must not be duplicated) 033 * @param _boolean boolean value to duplicate 034 * @return duplicated value 035 */ 036 public static boolean duplicate(boolean _boolean) { 037 return _boolean; 038 } 039 040 /** 041 * primitive value duplication (do nothing, value type must not be duplicated) 042 * @param _byte byte value to duplicate 043 * @return duplicated value 044 */ 045 public static byte duplicate(byte _byte) { 046 return _byte; 047 } 048 049 /** 050 * primitive value duplication (do nothing, value type must not be duplicated) 051 * @param _short byte value to duplicate 052 * @return duplicated value 053 */ 054 public static short duplicate(short _short) { 055 return _short; 056 } 057 058 /** 059 * primitive value duplication (do nothing, value type must not be duplicated) 060 * @param _int byte value to duplicate 061 * @return duplicated value 062 */ 063 public static int duplicate(int _int) { 064 return _int; 065 } 066 067 /** 068 * primitive value duplication (do nothing, value type must not be duplicated) 069 * @param _long byte value to duplicate 070 * @return duplicated value 071 */ 072 public static long duplicate(long _long) { 073 return _long; 074 } 075 076 /** 077 * primitive value duplication (do nothing, value type must not be duplicated) 078 * @param _double byte value to duplicate 079 * @return duplicated value 080 */ 081 public static double duplicate(double _double) { 082 return _double; 083 } 084 085 /** 086 * reference type value duplication 087 * @param object object to duplicate 088 * @return duplicated value 089 */ 090 091 public static Object duplicate(Object object, boolean deepCopy) { 092 if(object == null) return null; 093 if(object instanceof Number) return object; 094 if(object instanceof String) return object; 095 if(object instanceof Date) return ((Date)object).clone(); 096 if(object instanceof Boolean) return object; 097 098 099 100 Object copy = ThreadLocalDuplication.get(object); 101 if(copy!=null){ 102 return copy; 103 } 104 105 106 if(object instanceof CollectionPlus)return ((CollectionPlus)object).duplicate(deepCopy,ThreadLocalDuplication.getMap()); 107 if(object instanceof Collection)return ((Collection)object).duplicate(deepCopy); 108 if(object instanceof Duplicable)return ((Duplicable)object).duplicate(deepCopy); 109 if(object instanceof UDF) return ((UDF)object).duplicate(); 110 if(object instanceof List) return duplicateList((List)object,deepCopy); 111 if(object instanceof Map) return duplicateMap((Map)object,deepCopy); 112 if(object instanceof Serializable) { 113 try { 114 String ser = JavaConverter.serialize((Serializable)object); 115 return JavaConverter.deserialize(ser); 116 117 } catch (Throwable t) {} 118 } 119 120 121 return object; 122 } 123 124 public static List duplicateList(List list, boolean deepCopy) { 125 List newList; 126 try { 127 newList=(List) ClassUtil.loadInstance(list.getClass()); 128 } catch (ClassException e) { 129 newList=new ArrayList(); 130 } 131 return duplicateList(list, newList, deepCopy); 132 } 133 134 public static List duplicateList(List list,List newList, boolean deepCopy) { 135 ListIterator it = list.listIterator(); 136 while(it.hasNext()) { 137 if(deepCopy) 138 newList.add(Duplicator.duplicate(it.next(),deepCopy)); 139 else 140 newList.add(it.next()); 141 } 142 return newList; 143 } 144 145 /** 146 * duplicate a map 147 * @param map 148 * @param doKeysLower 149 * @return duplicated Map 150 * @throws PageException 151 */ 152 public static Map duplicateMap(Map map, boolean doKeysLower,boolean deepCopy) throws PageException{ 153 if(doKeysLower) { 154 Map newMap; 155 try { 156 newMap=(Map) ClassUtil.loadInstance(map.getClass()); 157 } catch (ClassException e) { 158 newMap=new HashMap(); 159 } 160 ThreadLocalDuplication.set(map,newMap); 161 Iterator it=map.keySet().iterator(); 162 while(it.hasNext()) { 163 Object key=it.next(); 164 if(deepCopy)newMap.put(StringUtil.toLowerCase(Caster.toString(key)),duplicate(map.get(key), deepCopy)); 165 else newMap.put(StringUtil.toLowerCase(Caster.toString(key)),map.get(key)); 166 } 167 ThreadLocalDuplication.remove(map); 168 return newMap; 169 } 170 return duplicateMap(map,deepCopy); 171 } 172 173 public static Map duplicateMap(Map map,boolean deepCopy){ 174 Map other; 175 try { 176 other=(Map) ClassUtil.loadInstance(map.getClass()); 177 } catch (ClassException e) { 178 other=new HashMap(); 179 } 180 ThreadLocalDuplication.set(map,other); 181 duplicateMap(map,other, deepCopy); 182 ThreadLocalDuplication.remove(map); 183 return other; 184 } 185 186 public static Map duplicateMap(Map map,Map newMap,boolean deepCopy){ 187 188 189 Iterator it=map.keySet().iterator(); 190 while(it.hasNext()) { 191 Object key=it.next(); 192 if(deepCopy)newMap.put(key,duplicate(map.get(key),deepCopy)); 193 else newMap.put(key,map.get(key)); 194 } 195 return newMap; 196 } 197 } 198 199