package org.modelmap.core;

import java.awt.image.SampleModel;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.Generated;

interface FieldModel extends Iterable<Map.Entry<FieldId, Object>> {

    <T> T get(FieldId fieldId);

    <T> void set(FieldId fieldId, T value);

}

@Generated(value = "org.modelmap.gen.ModelMapGenMojo", comments = "generated from org.modelmap.sample.model" +
                ".SampleModel")
class SampleModelWrapper implements FieldModel {

    private final SampleModel model;

    public SampleModelWrapper(SampleModel model) {
        this.model = model;
    }

    @Override
    public <T> T get(FieldId fieldId) {
        // key-value mapping code here
        return null;
    }

    @Override
    public <T> void set(FieldId fieldId, T value) {
        // key-value mapping code here
    }

    @Override
    public Iterator<Map.Entry<FieldId, Object>> iterator() {
        return null;
    }
}



package org.modelmap.core;

import static java.util.stream.Collectors.toList;

import java.util.*;
import java.util.stream.Stream;

/**
 * An model that maps {@code FieldId} to values. Each {@code FieldId} can map to at most one value.
 */
public interface FieldModel extends Iterable<Map.Entry<FieldId, Object>> {

    /**
     * @param fieldId the {@code FieldId} to read
     * @return the the {@code FieldId} value
     */
    <T> T get(FieldId fieldId);

    /**
     * @param fieldId the {@code FieldId} to update
     * @param value the new {@code FieldId} value
     */
    <T> void set(FieldId fieldId, T value);

    /**
     * return a sequential {@code Stream} with all key-value pairs
     */
    Stream<Map.Entry<FieldId, Object>> stream();

    /**
     * {@inheritDoc}
     */
    Spliterator<Map.Entry<FieldId, Object>> spliterator();

    /**
     * return a parallel {@code Stream} with all key-value pairs
     */
    Stream<Map.Entry<FieldId, Object>> parallelStream();

    /**
     * @return the {@code FieldInfo} FieldInfo for all this model {@code FieldId}
     */
    FieldInfo[] getFieldInfos();

    /**
     * @return all {@code FieldId}, with a not-null value
     */
    default List<FieldId> getFieldIds() {
        return Arrays.stream(getFieldInfos()).map(FieldInfo::id).collect(toList());
    }

    /**
     * Copy all the values for the {@code FieldModel} <code>source</code>
     *
     * @param source the source field model
     */
    default void setAll(FieldModel source) {
        Arrays.stream(getFieldInfos())
                        .filter(info -> source.get(info.id()) != null)
                        .forEach(info -> set(info.id(), source.get(info.id())));
    }

    /**
     * For all the {@code FieldId}, set their value to <code>null</code>
     */
    default void clear() {
        Arrays.stream(getFieldInfos())
                        .filter(info -> get(info.id()) != null)
                        .forEach(info -> set(info.id(), null));
    }

    /**
     * For all the {@code FieldId} tagged with the specified {@code TagId}, set their value to <code>null</code>
     */
    default void clear(TagId tag) {
        Arrays.stream(getFieldInfos())
                        .filter(info -> info.id().hasTag(tag) && get(info.id()) != null)
                        .forEach(info -> set(info.id(), null));
    }

}

revert change