This framework is created to ease everyday tasks regarding conversion between models. It is not directed to one of specific use case like json <-> model conversion but can be used in many.
To make use of this framework there is need to instantiate Gecon
type object. It is provided from herd.gecon.core.engine
module
Example:
Gecon gecon = Gecon{
provider = AutoProvider {
transformations = ScopeProvisioning {
scopes = [
`module herd.gecon.core.transformer`,
`module herd.gecon.collection.transformer`,
`module herd.gecon.json.transformer`
];
};
};
};
This is minimal setup which is required for usage. Modules registered in this guide are providing required Transformation
s for:
- Basic data types transformations
- Generic data types transformations
- Collections transformations
- Json <-> Model transformations
There is only one instantiation parameter used and it is provider
. It tells framework, on what components it will work on. Currently only Transformation
s can be provided. AutoProvider
is used for such purpose. It works on scope based filtering. Basically it takes Transformation
classes, begin available via scopes
parameter and instantiates them, using available resources (currently only no args constructor). There is another parameter called exclusions
in ScopeProvisioning
class, allowing to reduce transformations availability for framework. Scope
is alias of Module|Package|ClassDeclaration
, that provides controll over instantiationing of transformations. Other way to provide Transformation
s is to use ManualProvider
, which requires clients, to instantiate Transformation
s manually, but gives precise controll what and how is available for Gecon
.
Gcon
type object, can also be configured. Currently only Logging
configuration is available to be altered. Logging
provides ability to change priority
, which is stadard ceylon.logging.priority
.
What is Transformation
? A Transformation
is an interface defined by herd.gecon.core.engine
, which provides a way for execution of Transformation.transform
method. It takes source data and transform it, into provided result type. Although below interfeces doesn't extends Transformation
interface (because of transformation method definition). They are wrapped using it and in most cases by Transofmormation
in this guide, one of fallowing interfaces will be ment:
-
Conversion
- Initial entry point for each transformation, takes source object and converts it into result type object. Whole flow can be implemented using singleConversion
or it can delegate to other transformations. Default implementation of this interface isConverter
, which should be used for definingConversion
. -
Resolvance
- Chooses implementation of specific interface, abstract class, or any other type which is ambigous in compile time. The most common use case is selecting collection implementation for interface likeList<String>
. Should this beLinkedList<String>
, or maybeArrayList<String>
? This is handled by implementaton ofResolvance
interface. Default implementation of this is interface isResolver
, which should be used for definingResolvance
. -
Creation
- Creates specific result type object from provided result type and arguments.Creation
can be undestood as a constructor / initializer. In cases, where conversion is generic and type arguments are not available in compile type, it is sometimes usefull to delegate toCreation
. Default implementation of this interface isCreator
, which should be used for definingCreation
. -
Mapping
- Maps result type parts to source parts values usingDictionary
object. Default implementation of this interface isMapper
, which should be used for definingMapping
. Example usecase is when, converting from json to model object and the naming of fields are different in model than in json.
Gecon
type object has a transform
method which will be used for all transformations.
Most commonly used transformation is Conversion
implemented by Converter<Source,Result,ResultType>
class. It has three type parameters as most of transformations:
- Source (Required) - A type of source data provided by framework to the converter,
- Result (Required) - A type of result data which will be produced by converter,
- ResultType (Defaulted :
Type<Result>
) - A Type of result type, provided by the framework to work on, usable only for generic conversions andMatcher
users. By default inConversion.convert
methodresultType
parameter isType<Result>
, which is too less for some converters. They may require thatresultType
beClass<Result>
orClassOrInterface<Result>
orUnionType<Result>
etc. By constraining this type parameter, there is no need for assertations inConversion.convert
method body.
Dummy specific converter definition:
shared class StringToNullConverter() extends Converter<String,Null>(){
shared actual Null convert(Delegator delegator, String source, Type<Null> resultType) => null;
}
When converter registered by Provider
it takes Source
and Result
types and uses HashMap
for storing them. Further when lookup in transformation flow it will be easly retreivable.
Dummy generic converter definition:
shared class AnythingToAnythingConverter() extends Converter<Anything,Anything,Type<Anything>>(){
shared actual Anything convert(Delegator delegator, Anything source, Type<Anything> resultType) {
value resolve = delegator.resolve(source, resultType);
return delegator.convert(source, resolve);
}
shared actual Matcher matcher => Matcher{
predicate(Anything source, Type<Anything> resultType) => (source is String|Null) && (resultType.subtypeOf(`String|Null`));
Integer priority = 0;
};
}
In this case, registration takes Matcher
definition. Whenever hashing fail, because for example Result
type is interface, union type or abstract class. Registered Matcher
s are used for lookup. The search mechanism iterates over available Matcher
s and if Matcher.predicate
method returns true
and the Matcher.priority
is the biggest in this lookup scope, then this Transformation
will be used, in this case for conversion.
All examples in example
source folder.
Examples definitions:
- Json to Model conversion -
module json.to.model
- Model to Json conversion -
module model.to.json
The versioning of this project starts from 0. Is defined as referenced to version of herd.gecon.core.api
module as a base, which is defined as CORE-API . Other modules should define it's version, based on this versioning so version of herd.gecon.core.engine
module will be defined as CORE-API.ENGINE . If a module have it's own API. the versioning for this module will be CORE-API.OTHER-API.MODULE . Change in any API version may mean it is a compatibility break.
Module name | Versioning pattern | Current version |
---|---|---|
herd.gecon.core.api |
CORE_API | 0 |
herd.gecon.core.engine |
CORE_API.ENGINE | 0.0 |
herd.gecon.core.trnasformer |
CORE_API.TRANSFORMER | 0.0 |
herd.gecon.collection.transformer |
CORE_API.TRANSFORMER | 0.0 |
herd.gecon.json.transformer |
CORE_API.TRNASFORMER | 0.0 |
herd.gecon.test.extension |
EXTENSION | 0 |