|
@@ -1,7 +1,9 @@
|
|
|
namespace Invercargill {
|
|
|
|
|
|
public delegate TProp PropertyGetter<TClass, TProp>(TClass object);
|
|
|
- public delegate void PropertySetter<TClass, TProp>(TClass object, TProp value) throws IndexError, ElementError;
|
|
|
+ public delegate void PropertySetter<TClass, TProp>(TClass object, TProp value) throws Error;
|
|
|
+ public delegate Tout PropertyGetterTransformer<Tin, Tout>(Tin object);
|
|
|
+ public delegate Tout PropertySetterTransformer<Tin, Tout>(Tin object) throws Error;
|
|
|
public delegate T ObjectConstructor<T>();
|
|
|
public class PropertyMapper<T> {
|
|
|
|
|
@@ -13,22 +15,28 @@ namespace Invercargill {
|
|
|
this.constructor = constructor;
|
|
|
}
|
|
|
|
|
|
- public void map_into(T object, KeyValues<string, Element> properties) throws IndexError, ElementError {
|
|
|
+ public void map_into(T object, KeyValues<string, Element> properties) throws Error {
|
|
|
foreach (var mapping in mappings) {
|
|
|
+ if(!mapping.mandatory && !properties.has(mapping.name)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
mapping.setter(object, properties[mapping.name]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public T materialise(Properties properties) throws IndexError, ElementError {
|
|
|
+ public T materialise(Properties properties) throws Error {
|
|
|
var obj = constructor();
|
|
|
map_into(obj, properties);
|
|
|
return obj;
|
|
|
}
|
|
|
|
|
|
public Properties map_from(T object) {
|
|
|
- var properties = new DictionaryProperties();
|
|
|
+ var properties = new PropertiesDictionary();
|
|
|
foreach (var mapping in mappings) {
|
|
|
- properties[mapping.name] = mapping.getter(object);
|
|
|
+ var val = mapping.getter(object);
|
|
|
+ if(mapping.mandatory || !val.is_null()) {
|
|
|
+ properties[mapping.name] = val;
|
|
|
+ }
|
|
|
}
|
|
|
return properties;
|
|
|
}
|
|
@@ -37,6 +45,7 @@ namespace Invercargill {
|
|
|
|
|
|
private class PropertyMapping<T> {
|
|
|
public string name;
|
|
|
+ public bool mandatory;
|
|
|
public PropertyGetter<T, Element> getter;
|
|
|
public PropertySetter<T, Element> setter;
|
|
|
}
|
|
@@ -51,10 +60,11 @@ namespace Invercargill {
|
|
|
constructor = () => Object.new(typeof(T));
|
|
|
}
|
|
|
|
|
|
- public PropertyMapperBuilder<T> map<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter) {
|
|
|
+ public PropertyMapperBuilder<T> map<TProp>(string name, owned PropertyGetter<T, TProp> getter, owned PropertySetter<T, TProp> setter, bool mandatory = true) {
|
|
|
if(typeof(TProp).is_a(typeof(Element))) {
|
|
|
add_mapping(new PropertyMapping<T>() {
|
|
|
name = name,
|
|
|
+ mandatory = mandatory,
|
|
|
getter = (owned)getter,
|
|
|
setter = (owned)setter
|
|
|
});
|
|
@@ -62,6 +72,7 @@ namespace Invercargill {
|
|
|
else {
|
|
|
add_mapping(new PropertyMapping<T>() {
|
|
|
name = name,
|
|
|
+ mandatory = mandatory,
|
|
|
getter = (o) => new NativeElement<TProp>(getter(o)),
|
|
|
setter = (o,d) => setter(o, d.as<TProp>())
|
|
|
});
|
|
@@ -69,38 +80,37 @@ namespace Invercargill {
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public PropertyMapperBuilder<T> map_with<TObj>(string name, owned PropertyGetter<T, TObj> getter, owned PropertySetter<T, TObj> setter, PropertyMapper<TObj> mapper) {
|
|
|
+ public PropertyMapperBuilder<T> map_with<TObj>(string name, owned PropertyGetter<T, TObj> getter, owned PropertySetter<T, TObj> setter, PropertyMapper<TObj> mapper, bool mandatory = true) {
|
|
|
add_mapping(new PropertyMapping<T>() {
|
|
|
name = name,
|
|
|
+ mandatory = mandatory,
|
|
|
getter = (o) => new NativeElement<Properties>(mapper.map_from(getter(o))),
|
|
|
setter = (o,d) => setter(o, mapper.materialise(d.as<Properties>()))
|
|
|
});
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public PropertyMapperBuilder<T> map_collection<TCollection, TObj>(string name, owned PropertyGetter<T, Collection<TObj>> getter, owned PropertySetter<T, TCollection<TObj>> setter) requires (typeof(TCollection).is_a(typeof(Collection))) {
|
|
|
+ public PropertyMapperBuilder<T> map_many<TObj>(string name, owned PropertyGetter<T, Enumerable<TObj>> getter, owned PropertySetter<T, Enumerable<TObj>> setter, bool mandatory = true) {
|
|
|
add_mapping(new PropertyMapping<T>() {
|
|
|
name = name,
|
|
|
+ mandatory = mandatory,
|
|
|
getter = (o) => new NativeElement<Elements>(getter(o).to_elements()),
|
|
|
- setter = (o,d) => {
|
|
|
- var collection = (Collection)Object.new(typeof(TCollection));
|
|
|
- collection.add_all(d.as<Elements>().elements_as<TObj>());
|
|
|
- setter(o, collection);
|
|
|
- }
|
|
|
+ setter = (o,d) => setter(o, d.as<Elements>().elements_as<TObj>())
|
|
|
});
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
- public PropertyMapperBuilder<T> map_collection_with<TCollection, TObj>(string name, owned PropertyGetter<T, Collection<TObj>> getter, owned PropertySetter<T, TCollection<TObj>> setter, PropertyMapper<TObj> mapper) requires (typeof(TCollection).is_a(typeof(Collection))) {
|
|
|
+ public PropertyMapperBuilder<T> map_many_with<TObj>(string name, owned PropertyGetter<T, Enumerable<TObj>> getter, owned PropertySetter<T, Enumerable<TObj>> setter, PropertyMapper<TObj> mapper, bool mandatory = true) {
|
|
|
add_mapping(new PropertyMapping<T>() {
|
|
|
name = name,
|
|
|
+ mandatory = mandatory,
|
|
|
getter = (o) => new NativeElement<Elements>(getter(o).select<Properties>(i => mapper.map_from(i)).to_elements()),
|
|
|
setter = (o,d) => {
|
|
|
- var collection = (Collection<TObj>)Object.new(typeof(TCollection));
|
|
|
+ var collection = new Series<TObj>();
|
|
|
foreach (var properties in d.as<Elements>().elements_as<Properties>()) {
|
|
|
collection.add(mapper.materialise(properties));
|
|
|
}
|
|
|
- setter(o, collection);
|
|
|
+ setter(o, collection.seal());
|
|
|
}
|
|
|
});
|
|
|
return this;
|