protected Object internalCreate()

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;
    }