1 package com.thoughtworks.xstream.mapper; 2 3 import com.thoughtworks.xstream.alias.ClassMapper; 4 5 import java.util.Collections ; 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.Map ; 9 10 public class ImplicitCollectionMapper extends MapperWrapper { 11 12 public ImplicitCollectionMapper(ClassMapper wrapped) { 13 super(wrapped); 14 } 15 16 private Map classNameToMapper = Collections.synchronizedMap(new HashMap ()); 18 19 private ImplicitCollectionMapperForClass getMapper(Class definedIn) { 20 while (definedIn != null) { 21 ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass) classNameToMapper.get(definedIn); 22 if (mapper != null) { 23 return mapper; 24 } 25 definedIn = definedIn.getSuperclass(); 26 } 27 return null; 28 } 29 30 private ImplicitCollectionMapperForClass getOrCreateMapper(Class definedIn) { 31 ImplicitCollectionMapperForClass mapper = getMapper(definedIn); 32 if (mapper == null) { 33 mapper = new ImplicitCollectionMapperForClass(definedIn); 34 classNameToMapper.put(definedIn, mapper); 35 } 36 return mapper; 37 } 38 39 public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { 40 ImplicitCollectionMapperForClass mapper = getMapper(definedIn); 41 if (mapper != null) { 42 return mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName); 43 } else { 44 return null; 45 } 46 } 47 48 public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { 49 ImplicitCollectionMapperForClass mapper = getMapper(definedIn); 50 if (mapper != null) { 51 return mapper.getItemTypeForItemFieldName(itemFieldName); 52 } else { 53 return null; 54 } 55 } 56 57 public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { 58 ImplicitCollectionMapperForClass mapper = getMapper(itemType); 59 if (mapper != null) { 60 return mapper.getImplicitCollectionDefForFieldName(fieldName); 61 } else { 62 return null; 63 } 64 } 65 66 public void add(Class definedIn, String fieldName, Class itemType) { 67 add(definedIn, fieldName, null, itemType); 68 } 69 70 public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType) { 71 ImplicitCollectionMapperForClass mapper = getOrCreateMapper(definedIn); 72 mapper.add(new ImplicitCollectionMappingImpl(fieldName, itemType, itemFieldName)); 73 } 74 75 private static class ImplicitCollectionMapperForClass { 76 private Map namedItemTypeToDef = new HashMap (); private Map itemFieldNameToDef = new HashMap (); private Map fieldNameToDef = new HashMap (); 81 public ImplicitCollectionMapperForClass(Class definedIn) { 82 } 84 85 public String getFieldNameForItemTypeAndName(Class itemType, String itemFieldName) { 86 ImplicitCollectionMappingImpl unnamed = null; 87 for (Iterator iterator = namedItemTypeToDef.keySet().iterator(); iterator.hasNext();) { 88 NamedItemType itemTypeForFieldName = (NamedItemType) iterator.next(); 89 if (itemTypeForFieldName.itemType.isAssignableFrom(itemType)) { 90 ImplicitCollectionMappingImpl def = (ImplicitCollectionMappingImpl) namedItemTypeToDef.get(itemTypeForFieldName); 91 if (def.getItemFieldName() != null) { 92 if (def.getItemFieldName().equals(itemFieldName)) { 93 return def.getFieldName(); 94 } 95 } else { 96 unnamed = def; 97 if (itemFieldName == null) { 98 break; 99 } 100 } 101 } 102 } 103 return unnamed != null ? unnamed.getFieldName() : null; 104 } 105 106 public Class getItemTypeForItemFieldName(String itemFieldName) { 107 ImplicitCollectionMappingImpl def = getImplicitCollectionDefByItemFieldName(itemFieldName); 108 if (def != null) { 109 return def.getItemType(); 110 } else { 111 return null; 112 } 113 } 114 115 private ImplicitCollectionMappingImpl getImplicitCollectionDefByItemFieldName(String itemFieldName) { 116 if (itemFieldName == null) { 117 return null; 118 } else { 119 return (ImplicitCollectionMappingImpl) itemFieldNameToDef.get(itemFieldName); 120 } 121 } 122 123 public ImplicitCollectionMappingImpl getImplicitCollectionDefByFieldName(String fieldName) { 124 return (ImplicitCollectionMappingImpl) fieldNameToDef.get(fieldName); 125 } 126 127 public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(String fieldName) { 128 return (ImplicitCollectionMapping) fieldNameToDef.get(fieldName); 129 } 130 131 public void add(ImplicitCollectionMappingImpl def) { 132 fieldNameToDef.put(def.getFieldName(), def); 133 namedItemTypeToDef.put(def.createNamedItemType(), def); 134 if (def.getItemFieldName() != null) { 135 itemFieldNameToDef.put(def.getItemFieldName(), def); 136 } 137 } 138 139 } 140 141 private static class ImplicitCollectionMappingImpl implements ImplicitCollectionMapping { 142 private String fieldName; 143 private String itemFieldName; 144 private Class itemType; 145 146 ImplicitCollectionMappingImpl(String fieldName, Class itemType, String itemFieldName) { 147 this.fieldName = fieldName; 148 this.itemFieldName = itemFieldName; 149 this.itemType = itemType; 150 } 151 152 153 public boolean equals(Object obj) { 154 if (obj instanceof ImplicitCollectionMappingImpl) { 155 ImplicitCollectionMappingImpl b = (ImplicitCollectionMappingImpl) obj; 156 return fieldName.equals(b.fieldName) 157 && isEquals(itemFieldName, b.itemFieldName); 158 } else { 159 return false; 160 } 161 } 162 163 public NamedItemType createNamedItemType() { 164 return new NamedItemType(itemType, itemFieldName); 165 } 166 167 private static boolean isEquals(Object a, Object b) { 168 if (a == null) { 169 return b == null; 170 } else { 171 return a.equals(b); 172 } 173 } 174 175 public int hashCode() { 176 int hash = fieldName.hashCode(); 177 if (itemFieldName != null) { 178 hash += itemFieldName.hashCode() << 7; 179 } 180 return hash; 181 } 182 183 public String getFieldName() { 184 return fieldName; 185 } 186 187 public String getItemFieldName() { 188 return itemFieldName; 189 } 190 191 public Class getItemType() { 192 return itemType; 193 } 194 } 195 196 private static class NamedItemType { 197 Class itemType; 198 String itemFieldName; 199 200 NamedItemType(Class itemType, String itemFieldName) { 201 this.itemType = itemType; 202 this.itemFieldName = itemFieldName; 203 } 204 205 206 public boolean equals(Object obj) { 207 if (obj instanceof NamedItemType) { 208 NamedItemType b = (NamedItemType) obj; 209 return itemType.equals(b.itemType) 210 && isEquals(itemFieldName, b.itemFieldName); 211 } else { 212 return false; 213 } 214 } 215 216 private static boolean isEquals(Object a, Object b) { 217 if (a == null) { 218 return b == null; 219 } else { 220 return a.equals(b); 221 } 222 } 223 224 public int hashCode() { 225 int hash = itemType.hashCode() << 7; 226 if (itemFieldName != null) { 227 hash += itemFieldName.hashCode(); 228 } 229 return hash; 230 } 231 } 232 } 233 234 | Popular Tags |