package org.apache.felix.ipojo.everest.impl;

import org.apache.felix.ipojo.everest.services.ResourceMetadata;

import java.util.HashMap;
import java.util.Map;

/**
 * We recommend resource metadata to be immutable.
 * Here is a basic implementation.
 */
public class ImmutableResourceMetadata  extends HashMap<String, Object> implements ResourceMetadata {

    public static ImmutableResourceMetadata of(ResourceMetadata metadata) {
        return of((Map<String, Object>) metadata);
    }

    public static ImmutableResourceMetadata of(Map<String , ?> metadata) {
        ImmutableResourceMetadata irm = new ImmutableResourceMetadata();
        for (Map.Entry<String, ?> entry : metadata.entrySet()) {
            irm._put(entry.getKey(), entry.getValue());
        }
        return irm;
    }

    /**
     * A private delegate on the super put method.
     * @param key the key
     * @param value the value
     */
    private void _put(String key, Object value) {
        super.put(key, value);
    }

    public <T> T get(String key, Class<? extends T> clazz) {
        Object obj = get(key);

        if (obj == null) {
            return null;
        }

        if (clazz.isInstance(obj)) {
            return clazz.cast(obj);
        } else {
            throw new IllegalArgumentException("The metadata '" + key + "' is not a '" + clazz.getName() + "' (found " +
                    "type: '" + obj.getClass().getName() + "')");
        }

    }

    /**
     * Resource metadata are immutable, not supported.
     */
    public Object put(String key, Object value) {
        throw new UnsupportedOperationException("Immutable metadata");
    }

    /**
     * Resource metadata are immutable, not supported.
     */
    public Object remove(Object key) {
        throw new UnsupportedOperationException("Immutable metadata");
    }

    /**
     * Resource metadata are immutable, not supported.
     */
    public void putAll(Map m) {
        throw new UnsupportedOperationException("Immutable metadata");
    }

    /**
     * Resource metadata are immutable, not supported.
     */
    public void clear() {
        throw new UnsupportedOperationException("Immutable metadata");
    }

    public static class Builder {

        Map<String, Object> accumulator = new HashMap<String, Object>();

        public Builder() {}

        public Builder(ResourceMetadata metadata) {
            if (metadata != null) {
                accumulator.putAll(metadata);
            }
        }

        public Builder set(String k, Object v) {
            accumulator.put(k ,v);
            return this;
        }

        public ImmutableResourceMetadata build() {
            return of(accumulator);
        }

    }
}

@@ -98,44 +98,75 @@
 urce
-Metadata;%0A%0Aimport java.util.HashMap;
+;%0Aimport org.apache.felix.ipojo.everest.services.ResourceMetadata;%0A
 %0Aimp
@@ -179,19 +179,17 @@
 va.util.
-Map
+*
 ;%0A%0A/**%0A 
@@ -2746,10 +2746,1395 @@
 %0A%0A    %7D%0A
+%0A    public static List%3CResourceMetadata%3E list(List%3CResource%3E resources) %7B%0A        if (resources == null) %7B%0A            return Collections.emptyList();%0A        %7D else %7B%0A            List%3CResourceMetadata%3E list = new ArrayList%3CResourceMetadata%3E();%0A            for (Resource res : resources) %7B%0A                list.add(res.getMetadata());%0A            %7D%0A            return list;%0A        %7D%0A    %7D%0A%0A    public static Map%3CString, ResourceMetadata%3E map(List%3CResource%3E resources, String id) %7B%0A        if (resources == null) %7B%0A            return Collections.emptyMap();%0A        %7D else %7B%0A            Map%3CString, ResourceMetadata%3E map = new HashMap%3CString, ResourceMetadata%3E();%0A            for (Resource res : resources) %7B%0A                map.put(res.getMetadata().get(id).toString(), res.getMetadata());%0A            %7D%0A            return map;%0A        %7D%0A    %7D%0A%0A    public static interface KeyBuilder %7B%0A        public String key(Resource resource);%0A    %7D%0A%0A    public static Map%3CString, ResourceMetadata%3E map(List%3CResource%3E resources, KeyBuilder builder) %7B%0A        if (resources == null) %7B%0A            return Collections.emptyMap();%0A        %7D else %7B%0A            Map%3CString, ResourceMetadata%3E map = new HashMap%3CString, ResourceMetadata%3E();%0A            for (Resource res : resources) %7B%0A                map.put(builder.key(res), res.getMetadata());%0A            %7D%0A            return map;%0A        %7D%0A    %7D%0A%0A
 %7D%0A

Add list and map in ImmutableResourceMetadata