in xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java [129:197]
protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
Class mapType = getType(expectedType);
if (!RecipeHelper.hasDefaultConstructor(mapType)) {
throw new ConstructionException("Type does not have a default constructor " + mapType.getName());
}
Object o;
try {
o = mapType.newInstance();
} catch (Exception e) {
throw new ConstructionException("Error while creating set instance: " + mapType.getName());
}
Map instance;
if (o instanceof Map) {
instance = (Map) o;
} else if (o instanceof Dictionary) {
instance = new DummyDictionaryAsMap((Dictionary) o);
} else {
throw new ConstructionException("Specified map type does not implement the Map interface: " + mapType.getName());
}
// get component type
Type keyType = Object.class;
Type valueType = Object.class;
Type[] typeParameters = RecipeHelper.getTypeParameters(Map.class, expectedType);
if (typeParameters != null && typeParameters.length == 2) {
if (typeParameters[0] instanceof Class) {
keyType = typeParameters[0];
}
if (typeParameters[1] instanceof Class) {
valueType = typeParameters[1];
}
}
// add to execution context if name is specified
if (getName() != null) {
ExecutionContext.getContext().addObject(getName(), instance);
}
// add map entries
boolean refAllowed = options.contains(Option.LAZY_ASSIGNMENT);
for (Object[] entry : entries) {
Object key = RecipeHelper.convert(keyType, entry[0], refAllowed, registry);
Object value = RecipeHelper.convert(valueType, entry[1], refAllowed, registry);
if (key instanceof Reference) {
// when the key reference and optional value reference are both resolved
// the key/value pair will be added to the map
Reference.Action action = new UpdateMap(instance, key, value);
((Reference) key).setAction(action);
if (value instanceof Reference) {
((Reference) value).setAction(action);
}
} else if (value instanceof Reference) {
// add a null place holder assigned to the key
//noinspection unchecked
instance.put(key, null);
// when value is resolved we will replace the null value with they real value
Reference.Action action = new UpdateValue(instance, key);
((Reference) value).setAction(action);
} else {
//noinspection unchecked
instance.put(key, value);
}
}
return instance;
}