GithubHelp home page GithubHelp logo

dobrynya / nomin Goto Github PK

View Code? Open in Web Editor NEW
42.0 42.0 19.0 1014 KB

Nomin is a mapping engine for the Java platform. It provides abilities to transform object trees using declarative mapping rules. Main features are no XML configuration, intuitively looking mapping, using arbitrary expressions/method invocations.

Groovy 49.49% Java 50.51%

nomin's People

Contributors

dobrynya avatar fixxer avatar narenchoudhary avatar ratoaq2 avatar tarioch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nomin's Issues

Error when converting enum

Trying to convert DTO to Entity results in following stack trace(getters/setters omitted for brevity):

DTO:

public class TermFullDTO {
private String status;
}

ENTITY:

public class Term {
private TermStatus status;
}

public enum TermStatus {
APPROVED,
PRELIMINARY
}

SCRIPT:

package mappings

import se.termweb.spring.domain.*
import se.termweb.spring.dto.term.TermFullDTO

mappingFor a: Term, b: TermFullDTO
automap()
a.termId = b.displayId
a.concept.oid = b.conceptId
a.oid = b.id
a.language.oid = b.language.id

a.status = b.status
simple([TermStatus.PRELIMINARY, "preliminary"], [TermStatus.APPROVED, "approved"])

org.nomin.core.NominException: term2TermFullDTO.groovy: Mapping rule status:TermStatus = status:String has failed!
at org.nomin.core.ParsedMapping.handle(ParsedMapping.java:70)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:107)
at org.nomin.core.Nomin.map(Nomin.java:205)
at org.nomin.core.Nomin.map(Nomin.java:162)
at org.nomin.core.Nomin.map(Nomin.java:159)
at se.termweb.spring.services.impl.ConverterServiceImpl.convert(ConverterServiceImpl.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy68.convert(Unknown Source)
at se.termweb.spring.services.impl.ConverterServiceImplTest.testConvertTerm2TermFullDTO(ConverterServiceImplTest.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
Caused by: org.nomin.core.NominException: Could not instantiate class se.termweb.spring.domain.TermStatus!
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:88)
at org.nomin.core.Nomin.map(Nomin.java:205)
at org.nomin.core.Nomin.map(Nomin.java:162)
at org.nomin.core.preprocessing.MapperPreprocessing.preprocess(MapperPreprocessing.java:23)
at org.nomin.core.preprocessing.Preprocessing.preprocess(Preprocessing.java:24)
at org.nomin.core.PropRuleElem.set(PropRuleElem.java:27)
at org.nomin.core.MappingRule.map(MappingRule.java:27)
at org.nomin.core.MappingRule.mapBtoA(MappingRule.java:32)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:106)
... 44 more
Caused by: java.lang.InstantiationException: se.termweb.spring.domain.TermStatus
at java.lang.Class.newInstance(Class.java:418)
at org.nomin.util.ReflectionInstanceCreator.create(ReflectionInstanceCreator.java:9)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:87)
... 52 more
Caused by: java.lang.NoSuchMethodException: se.termweb.spring.domain.TermStatus.()
at java.lang.Class.getConstructor0(Class.java:2971)
at java.lang.Class.newInstance(Class.java:403)
... 54 more

Regression in conversion with maps

After upgrading to the latest version I see a regression/change in behavior in regards to the conversions.

If you have something like this

mappingFor a: java.util.Map, b: MyEntity
b.foo = a['FOO']

and during runtime the value for a['FOO'] is a String and b.foo expects a BigInteger this was working, now it fails.

I tracked this down to the change to custom converters.

  protected Preprocessing preprocessing(TypeInfo thiz, TypeInfo that) {
....
    else if (Converters.isRegistered(that.type, thiz.type)) new ConverterPreprocessing(Converters.findConverter(that.type, thiz.type))
    else new MapperPreprocessing(thiz.type, mapping.mapper, mappingCase)
  }

This now checks if a converter from that.type (statically Object) to thiz.type (BigInteger) exists.

Which is false.

Before it was using BeanUtils ConvertUtils.lookup which only uses the sourceType if the target type is string and therefore returned true

During actual mapping of the value, the instance is of type String and this worked fine in the converter.

Question on nomin mapping

Hi Group, we are new to nomin mapping. we are planning to use nomin to map entities to JAXB vice-versa. please find the list of issues which we are facing. please let us know if you have any solution for these issues. thanks in advance.

  1. Back Referencing issue:- party entity is refrence to address and address has refernce to party back. how we are going to map these things in groovy file.
  2. Type casting : ex:- A has reference B. c extendeds B. when we want to access c attributes using b reference. how to typecast b to c.

String to date conversion is always lenient

It's not possible to define string 2 date conversion without being lenient

  void dateFormat(String pattern) {
    if (!entries) entry()
    SimpleDateFormat sdf = new SimpleDateFormat(pattern)
    def conversion = new String2DateConversion(sdf)
    convert to_a: conversion, to_b: conversion
  }

When I try to convert 2017-99-99 to date using pattern yyyy-MM-dd it will return a date 2025-06-07 but in my case I want an exception to be thrown.

There should be a way to define whether the date parser should be lenient or not:

SimpleDateFormat sdf = new SimpleDateFormat(pattern)
sdf.setLenient(false)

Problem with Exploding Introspector + Automap + Synthetic Property

I'm trying to use the automap facility while having the coverage data collected by the JaCoCo agent, using the Exploding Introspector.
The JaCoCo agent instruments the tested code by adding a synthetic property named $jacocoData.
When the ExplodingIntrospector.java reads all the properties from the object being mapped, it reads the $jacocoData property and try to use it like the rest of the properties. This causes the NominException "Recursive mapping rule a = b causes infinite loop!"

As per the JaCoCo documentation, all the synthetic properties should be filtered. Indeed if I use a modified custom ExplodingIntrospector that filter all the synthetic properties everything works as expected.
My custom introspector only overrides the properties method, adding a findAll:

    @Override
    Set<String> properties(Class<?> targetClass) {
        Set<String> properties = new HashSet()
        collectFields(targetClass).findAll { !it.synthetic }.each { properties.add(it.name) }
        return properties;
    }

Any way to have different introspectors for two sides?

Hi,
Is there a way to specify different introspectors for side a and b? The context is I have the two different my data models so the ways to access properties are different, e.g. one is java bean with getters/setters whereas the other is XMLElement accessed by xpath. My workaround is combine them into one introspector which looks up in one way and if the first lookup is unlucky go the other way, but obviously it's not a perfect approach. So any chance I could define introspectors separately for side a and b respectively?

deep cloning/mapping

Hi,
with autoMapping enabled and disablingCache. If the requirement is to map between same object types, how do we make sure the Obj hierarchy is deep cloned/mapped? i am observing the sub objects are not cloned but sharing the same reference. Appreciate help.

Hierarchical mapping issue

Hi,

I'd like to indicate an interesting issue I bumped into while working with Nomin. I used it with spring-boot-devtools and discovered that Nomin doesn't work as expected.

One of the issues was, for example, an attempt to convert from Class1 which extends Class. Despite the fact that I have mapping for Class1 -> other Class, Nomin would report that suitable mapping wouldn't exist and would create an automapping, which didn't work for me.

It switched back to normal behavior as soon as I commented out spring-devtool library from the project.

Just wanted to let you know. Maybe it's expected or known thing.

Thank you for the great library!

how to map to element to element mapping while using Map

Hi I am trying to map element to element wise in java.util.map
basically the following is my source objects
public class Message {
private final Map<String, Object> data;
}
and my destination object is just a Map<String, Object> So all I want is not to copy all the elements from the map Map<String, Object> data; but selectively. So I came up with a mapping file something like as follows

mappingFor a: Message, b: Map[String,java.lang.Object]
a.data["ID"] = b["ID"]

but I am getting following exception
Cannot cast object 'Map[String, Object]' with class 'org.nomin.util.TypeInfo' to class 'java.lang.Class' due to: java.lang.ClassNotFoundException: Map[String, Object]

Could you please help me resolve this issue...?

Mapping lists resulting in empty list

Hi,
I'm trying to map two classes that have Lists attributes. If one of this Lists are empty I have to get an empty List on the output object. The problem is, the output object always have a null instead an empty list when the input object has an empty list on the mapped attribute.

Simplified example:

public class A {
    private List<C> cList;

    ...
}

public class B {
    private List<D> dList;

    ...
}
mappingFor a:A, b:B

b.cList = a.dList
B b = new B();
b.dList = new ArrayList<>();
A a = nomin.map(b, A.class);

assert a.cList != null //false

I tried to map this in different ways. Tried defining two different one-way rules with something like:

a.cList = { b.dList.size() == 0 ? [] : mapper.map(b.dList, C.class) }

but the result is always the same.

It seems the change is made in CollectionRuleElem::set, line 24. If the source.size() == 0 then the property is set to null.
Is there a way to create a mapping so empty lists are mapped to empty lists? I was not able to find one.

ContextMap

I am trying to create a contextMap and pass this to another mapping by ( mapper.map(ClassA, ClassB, new ContextMap(** HashMap() **).. but at the another mapping I cant retrive the object in the context that i passed..

How do I get the object by Key at the ContextMap?
I followed an example on Nomin wiki, just typing the key of the map, but I got an error ( propertyMissing )

Thanks in advance.

Multi-level mapping with different contexts - possible?

Hi,

I don't know if this is intended but I am having problems when a mapping that contains a context calls another mapping passing a new context. For example, if a have the classes A, B, M and N:

class A {

    List<B> b

}

class B {

    String text

}

class M {

    String before
    String after
    List<N> n

}

class N {

    String text

}

And the mappings:

A2M.groovy

        mappingFor a: A, b: M

        b.before = { before }

        a.b = b.n
        convert to_a: { n -> mapper.map(n, B, new MapContext([anything: "AAA"])) },
                to_b: { b -> mapper.map(b, N, new MapContext([anything: "BBB"])) }

        b.after = { after }

B2N.groovy

        mappingFor a: B, b: N

        a.text = { b.text + anything}

the

b.before = { before } 

executes successfully but the line

b.after = { after }

will throw a NominException telling that the property 'after' isn't defined, because when

mapper.map(b, N, new MapContext([anything: "BBB"]))

is executed, it cleans the context for the A2M.groovy ( the new context is set before calling the B2N mapping, but resets to EmptyContext before returning, through the contextManager.restoreShared() call)

My question is: Is this the intended behavior? Is there a way to restore the previous context after calling the method Nomin::map(source, targetClass, context) inside another mapping?

Extract interface MappingBuilder

The interface should provide methods like
startNewRule(), pushA(RuleElem), pushB(RuleElem), finishRule(),
ParsedMapping build() etc. This can make possible to separate mapping parsers from mapping runtime.

Issue mapping between primitives and wrappers

Hi,

I'm having a problem with mappings where one side is a primitive and the other is a wrapper.
For example, if I have the mapping:

class AToB extends org.nomin.Mapping {
    protected void build() {
        mappingFor a:A, b:B
        a.numberA = b.numberB
    }
}

class A {
    long numberA
}

class B {
    Long numberB
}```

mapping B to A works as expected but mapping A to B gives me the following error:

Could not find applicable mappings between java.lang.Long and java.lang.Long. A mapping will be created using automapping facility
Exception thrown

org.nomin.core.NominException: org.nomin.Mapping: Mapping rule a.long = b.long is invalid because of missing property Long.long!
at org.nomin.core.PropPathElem.createMappingRuleElement(PropPathElem.groovy:18)
at org.nomin.core.PropPathElem$createMappingRuleElement.call(Unknown Source)
at org.nomin.core.RootPathElem$createMappingRuleElement.call(Unknown Source)
at org.nomin.core.MappingEntry.buildRuleElem(MappingEntry.groovy:77)
at org.nomin.core.MappingEntry.buildRuleElem(MappingEntry.groovy:79)
at org.nomin.core.MappingEntry.buildRuleElem(MappingEntry.groovy)
at org.nomin.core.MappingEntry$_parse_closure4.doCall(MappingEntry.groovy:51)
at org.nomin.core.MappingEntry.parse(MappingEntry.groovy:49)
at org.nomin.Mapping.parse(Mapping.groovy:44)
at org.nomin.core.Nomin.findApplicable(Nomin.java:228)
at org.nomin.core.Nomin.findCachedApplicable(Nomin.java:211)
at org.nomin.core.Nomin.map(Nomin.java:201)
at org.nomin.core.Nomin.map(Nomin.java:159)
at org.nomin.core.preprocessing.MapperPreprocessing.preprocess(MapperPreprocessing.java:23)
at org.nomin.core.preprocessing.Preprocessing.preprocess(Preprocessing.java:25)
at org.nomin.core.PropRuleElem.set(PropRuleElem.java:27)
at org.nomin.core.MappingRule.map(MappingRule.java:27)
at org.nomin.core.MappingRule.mapAtoB(MappingRule.java:36)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:104)
at org.nomin.core.Nomin.map(Nomin.java:202)
at org.nomin.core.Nomin.map(Nomin.java:159)
at org.nomin.core.Nomin.map(Nomin.java:156)
at org.nomin.NominMapper$map$0.call(Unknown Source)
at ConsoleScript24.run(ConsoleScript24:9)


Using the exploding instrospector the message changes, but the error still happens the same way: wrapper to primitive works, primitive to wrapper fails:

Could not find applicable mappings between java.lang.Long and java.lang.Long. A mapping will be created using automapping facility
Exception thrown

org.nomin.core.NominException: AToB: Mapping rule numberA:long = numberB:Long has failed!
at org.nomin.core.ParsedMapping.handle(ParsedMapping.java:70)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:105)
at org.nomin.core.Nomin.map(Nomin.java:202)
at org.nomin.core.Nomin.map(Nomin.java:159)
at org.nomin.core.Nomin.map(Nomin.java:156)
at org.nomin.NominMapper$map$0.call(Unknown Source)
at ConsoleScript21.run(ConsoleScript21:9)
Caused by: org.nomin.core.NominException: Could not instantiate class java.lang.Long!
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:88)
at org.nomin.core.Nomin.map(Nomin.java:202)
at org.nomin.core.Nomin.map(Nomin.java:159)
at org.nomin.core.preprocessing.MapperPreprocessing.preprocess(MapperPreprocessing.java:23)
at org.nomin.core.preprocessing.Preprocessing.preprocess(Preprocessing.java:25)
at org.nomin.core.PropRuleElem.set(PropRuleElem.java:27)
at org.nomin.core.MappingRule.map(MappingRule.java:27)
at org.nomin.core.MappingRule.mapAtoB(MappingRule.java:36)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:104)
... 5 more
Caused by: java.lang.InstantiationException: java.lang.Long
at org.nomin.util.ReflectionInstanceCreator.create(ReflectionInstanceCreator.java:9)
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:87)
... 13 more
Caused by: java.lang.NoSuchMethodException: java.lang.Long.()
... 15 more

Queries on nomin mapping

we are new to nomin mapping, we are are very much interested to use this nomin mapping in our project. when we use nomin we are facing some issues. please find below.

  1. we are getting permgen space error frequently when we invoke the code via nomin mapping. when we map these things via normal java code we are not facing this issue.
  2. we have 2 child classes for one parent. how are we going to typecast to specific child. ex:- B and C classes are extending A class.

ParsedMapping thread local cache might lead to wrong results across different Nomin instances

I have created a test case for it:

map2orderOne.groovy

mappingFor a: java.util.Map, b: org.nomin.entity.OrderItem

b.amount = 1
b.description = a['description']

map2orderTwo.groovy

mappingFor a: java.util.Map, b: org.nomin.entity.OrderItem

b.amount = 2
b.description = a['description']
    @Test
    public void cacheWithMultipleNomins() {
        Nomin nominOne = new Nomin("mappings/map2orderOne.groovy");
        Nomin nominTwo = new Nomin("mappings/map2orderTwo.groovy");

        Map<String, Object> source = Map.of("description", "Order Item");

        OrderItem item1 = nominOne.map(source, OrderItem.class);
        OrderItem item2 = nominTwo.map(source, OrderItem.class);

        assertEquals("Order Item", item1.getDescription());
        assertEquals(Integer.valueOf(1), item1.getAmount());
        assertEquals("Order Item", item2.getDescription());
        assertEquals(Integer.valueOf(2), item2.getAmount());
    }

When running the test case, item2.getAmount() is 1 instead of 2.

07:20:06.508 [Test worker] DEBUG org.nomin.core.ScriptLoader - Loading resource mappings/map2orderTwo.groovy
07:20:06.692 [Test worker] DEBUG org.nomin.core.Nomin - Parsed Mapping a: Map b: OrderItem {
  2 = amount:Integer
  [description]:Object = description:String
}

expected:<2> but was:<1>
Expected :2
Actual   :1

Nomin produces memory leaks in SpringContext.

I have an web application which is using a Nomin with SpringContext, it initialises mapper like this:

@Override public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException { BeanFactory parentBeanFactory = applicationContext.getAutowireCapableBeanFactory(); SpringContext springContext = new SpringContext(parentBeanFactory); mapper = mapper.context(springContext); }

And I have a problem when the context is destroying, servlet container telling me that it has a memory leaks with thread locals of key org.nomin.core.ContextManager:

memoryleak.log.txt

My question is how to correctly destroy mapper? I cannot find any method for it in org.nomin.NominMapper interface.

introspect mapping before using it

Thanks for creating such a cool framework.

We have a question about retrieving information about the mapping before using it.
Here is some context:

  1. We're using mappers to map from a DB to a domain object
  2. The mapper defines the DB fields that we'd like to extract from a ResultSet

Issue: We'd like to ask the mapper what it's going to map and use this in the select statement (prior to invoking the mapper). We'd like to avoid doing a select * on the DB table.

Is this possible? We have a chicken and egg issue.

Or is it possible to give the mapper some metadata / property we could retrieve before invoking the map.

Mapping list of objects with discriminators to polymorph list of objects

Hi,

In my source I have a list with objects with a type discriminator and in my destination I have a polymorph list. How I can map the list with nomin? In my tests Nomin tries to instantiate the abstract class

DstAnimal:
Caused by: org.nomin.core.NominException: Could not instantiate class nomin.DstAnimal!
at org.nomin.core.ParsedMapping.map(ParsedMapping.java:88)

class SrcAnimals {
  SrcAnimal[] animals = []
}

class SrcAnimal {
  enum Type {
    DOG,
    CAT
  }
  Type type
  String name
}

class DstAnimals {
  DstAnimal[] animals = []
}

abstract class DstAnimal {
  String name
}

class DstDog extends DstAnimal {
}

class DstCat extends DstAnimal {
}

Mapping test:

class NominTest {

  @Test
  public void mapAnimals() throws Exception {
    NominMapper nomin = new Nomin("srcAnimals2dstAnimals.groovy")

    SrcAnimals srcAnimals = new SrcAnimals(
        animals: [new SrcAnimal(type: DOG, name: 'Wau'), new SrcAnimal(type: CAT, name: 'Mau')]
    )

    DstAnimals result = nomin.map(srcAnimals, DstAnimals)

    assert result.animals.size() == 2
    assert result.animals[0].name == 'Wau'
    assert result.animals[0] instanceof DstDog
    assert result.animals[1].name == 'Mau'
    assert result.animals[1] instanceof DstCat
  }
}

Mapping config file:

mappingFor a: DstAnimals, b: SrcAnimals
a.animals = b.animals
hint a: [{ it.type == DOG ? DstDog : DstCat }]

SpringContext usage in mappings

Hello Dmitry,

Great framework you made, kudos!

Would you mind giving some examples of using SpringContext in a mapping file? Is it just using a bean name?

mappingFor a: Class1, b: Class2
a.f1 = { b.f2 + ' ' + beanName.prop1 }

Thank you!

Problems with using closures in Groovy 2.5

We have successfully used Nomin for quite some time in Groovy 2.4, but are running into trouble after an upgrade to Groovy 2.5. The core of the problem seems to be that closures work in a different context, so afterAtoB and Closure mapping rules have inconsistent understanding of what "a" and "b" is. We have items that correspond to JSON structures and want to map these onto models for our own usage, but data in the JSON is divided into various substructures. Our way to get around this is to map several items onto the same one. So we have ItemInfo and ItemData both being mapped onto our internal object CombinedItem. This is fine in Groovy 2.4, but after upgrading to 2.5, Closures in ItemData think that the variable "a" in the Closure is of the type ItemInfo and fail.

I have created a simple test setup that demonstrates this:
https://github.com/nc-hlb/nominmapper
If you run it in the Groovy 2.4 configuration all tests pass, but if you switch to using 2.5 they fail.

Date Conversions to custom Date type

Is there a way to do an additional conversion after the String2Date conversion or is there another way to be able to use this syntax

a.strDate = b.details.birth
dateFormat "dd-MM-yyyy"

to produce something except java.util.Date? E.g. java.time.LocalDateTime
I would like to do this somewhere globally so I don't have to provide custom code on each field that's mapped.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.