// Path: src/main/java/de/fesere/hypermedia/cj/model/builder/DataEntryFactory.java
// public final class DataEntryFactory {
// 
//     public static DataEntry create(String name, Object value, String prompt) {
// 
//         if(StringUtils.isBlank(name)){
//             return createNone();
//         }
// 
//         if(value == null) {
//            throw new MalformedDataValueException("value of '"+name+"' can not be null");
//         }
// 
//         Class type = value.getClass();
// 
//         if (TypeUtils.isString(type)) {
//             return new StringDataEntry(name, (String) value, prompt);
//         } else if (TypeUtils.isNumber(type)) {
//             return new NumberDataEntry(name, (Number) value, prompt);
//         } else if (TypeUtils.isBoolean(type)) {
//             return new BooleanDataEntry(name, (Boolean) value, prompt);
//         } else {
//            throw new SerializationException("'"+name+"' of type " + type + " can not be converted to DataEntry");
//         }
//     }
// 
//     public static DataEntry create(String name, Object value) {
//         return create(name, value, null);
//     }
// 
//     private static DataEntry createNone() {
//         return new NoneDataEntry("none");
//     }
// 
//     public static DataEntry createNull(String name, String prompt) {
//         return new NullDataEntry(name,prompt);
//     }
// 
//     public static DataEntry createNull(String name) {
//         return createNull(name, null);
//     }
// 
//     public static DataEntry createEmpty(String name, String prompt) {
//         return new StringDataEntry(name, "", prompt);
//     }
// 
//     public static DataEntry createEmpty(String name) {
//         return new StringDataEntry(name);
//     }
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/serialization/Wrapped.java
// public interface Wrapped {
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/transformer/DataEntryTransformer.java
// public class DataEntryTransformer<T> implements ReadTransformation<T> {
// 
// 
//     private ReadTransformation<T> innerTransformer;
// 
//     public DataEntryTransformer(ReadTransformation<T> innerTransformer) {
//         this.innerTransformer = innerTransformer;
//     }
// 
// 
//     public T  transform(List<DataEntry> dataEntryList) {
//         Item item = new Item(dataEntryList);
//         return transform(item);
//     }
// 
//     @Override
//     public T transform(Item item) {
//         return innerTransformer.transform(item) ;
//     }
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/transformer/ReadTransformation.java
// public interface ReadTransformation<T> {
// 
//     T transform(Item item);
// }


import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import de.fesere.hypermedia.cj.model.builder.DataEntryFactory;
import de.fesere.hypermedia.cj.serialization.Wrapped;
import de.fesere.hypermedia.cj.transformer.DataEntryTransformer;
import de.fesere.hypermedia.cj.transformer.ReadTransformation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
package de.fesere.hypermedia.cj.model;




@JsonTypeName("template")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Template implements Wrapped {

    private List<DataEntry> data;

    public Template(@JsonProperty("data") List<DataEntry> data) {
        this.data = data;
    }

    public List<DataEntry> getData() {
        return new LinkedList<>(data);
    }

    public void fill(Item item) {
        List<DataEntry> filledDataEntries = new LinkedList<>();

        for(DataEntry entry : data) {
            String name = entry.getName();
            String prompt = entry.getPrompt();
            Object value = item.getObject(name);

            DataEntry filled = DataEntryFactory.create(name, value, prompt);
            filledDataEntries.add(filled);
        }

        this.data = filledDataEntries;
    }

// Path: src/main/java/de/fesere/hypermedia/cj/model/builder/DataEntryFactory.java
// public final class DataEntryFactory {
// 
//     public static DataEntry create(String name, Object value, String prompt) {
// 
//         if(StringUtils.isBlank(name)){
//             return createNone();
//         }
// 
//         if(value == null) {
//            throw new MalformedDataValueException("value of '"+name+"' can not be null");
//         }
// 
//         Class type = value.getClass();
// 
//         if (TypeUtils.isString(type)) {
//             return new StringDataEntry(name, (String) value, prompt);
//         } else if (TypeUtils.isNumber(type)) {
//             return new NumberDataEntry(name, (Number) value, prompt);
//         } else if (TypeUtils.isBoolean(type)) {
//             return new BooleanDataEntry(name, (Boolean) value, prompt);
//         } else {
//            throw new SerializationException("'"+name+"' of type " + type + " can not be converted to DataEntry");
//         }
//     }
// 
//     public static DataEntry create(String name, Object value) {
//         return create(name, value, null);
//     }
// 
//     private static DataEntry createNone() {
//         return new NoneDataEntry("none");
//     }
// 
//     public static DataEntry createNull(String name, String prompt) {
//         return new NullDataEntry(name,prompt);
//     }
// 
//     public static DataEntry createNull(String name) {
//         return createNull(name, null);
//     }
// 
//     public static DataEntry createEmpty(String name, String prompt) {
//         return new StringDataEntry(name, "", prompt);
//     }
// 
//     public static DataEntry createEmpty(String name) {
//         return new StringDataEntry(name);
//     }
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/serialization/Wrapped.java
// public interface Wrapped {
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/transformer/DataEntryTransformer.java
// public class DataEntryTransformer<T> implements ReadTransformation<T> {
// 
// 
//     private ReadTransformation<T> innerTransformer;
// 
//     public DataEntryTransformer(ReadTransformation<T> innerTransformer) {
//         this.innerTransformer = innerTransformer;
//     }
// 
// 
//     public T  transform(List<DataEntry> dataEntryList) {
//         Item item = new Item(dataEntryList);
//         return transform(item);
//     }
// 
//     @Override
//     public T transform(Item item) {
//         return innerTransformer.transform(item) ;
//     }
// }
// 
// Path: src/main/java/de/fesere/hypermedia/cj/transformer/ReadTransformation.java
// public interface ReadTransformation<T> {
// 
//     T transform(Item item);
// }


// Path: src/main/java/de/fesere/hypermedia/cj/model/Template.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import de.fesere.hypermedia.cj.model.builder.DataEntryFactory;
import de.fesere.hypermedia.cj.serialization.Wrapped;
import de.fesere.hypermedia.cj.transformer.DataEntryTransformer;
import de.fesere.hypermedia.cj.transformer.ReadTransformation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

package de.fesere.hypermedia.cj.model;




@JsonTypeName("template")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Template implements Wrapped {

    private List<DataEntry> data;

    public Template(@JsonProperty("data") List<DataEntry> data) {
        this.data = data;
    }

    public List<DataEntry> getData() {
        return new LinkedList<>(data);
    }

    public void fill(Item item) {
        List<DataEntry> filledDataEntries = new LinkedList<>();

        for(DataEntry entry : data) {
            String name = entry.getName();
            String prompt = entry.getPrompt();
            Object value = item.getObject(name);

            DataEntry filled = DataEntryFactory.create(name, value, prompt);
            filledDataEntries.add(filled);
        }

        this.data = filledDataEntries;
    }

    public <T> T convert(ReadTransformation<T> transformation) {