Hi David L,

I've implemented an initial version here:
https://svn.apache.org/viewvc?view=revision&revision=1765430

I had to rename the methods a little bit. The to() has the actual
implementation type, just as before. The new method added is target() which
is where you can specify how to view the target implementation method. I
added a unit test at [1] which does:

MyDTOWithMethods dto =
converter.convert(src).target(MyDTO.class).to(MyDTOWithMethods.class);

Hope this works for you...

Cheers,

David

[1]
https://svn.apache.org/viewvc/felix/trunk/converter/converter/src/test/java/org/apache/felix/converter/impl/ConverterTest.java?r1=1765430&r2=1765429&pathrev=1765430

On 18 October 2016 at 11:49, David Leangen <o...@leangen.net> wrote:

>
> HI David B.,
>
> Yup, something like that would do just fine!!
>
> Thanks a lot.
>
>
> Cheers,
> =David
>
>
> > On Oct 18, 2016, at 7:43 PM, David Bosschaert <
> david.bosscha...@gmail.com> wrote:
> >
> > Hi David L,
> >
> > The as() method (at least in its current incantation) say something about
> > how to treat the source object - the thing you are converting from. So in
> > your example
> >  myDtoWithMethods =
> > converter.convert(map).as(PlainDTO.class).to(DtoWithMethods.class)
> >
> > it would try to treat the source map as a PlainDTO - which obviously will
> > fail.
> >
> > I guess what you're looking for is a way to say: 'create a target object
> > from this class, but treat it as if it was that class', so maybe
> something
> > like this?:
> >  myDtoWithMethods =
> > converter.convert(map).to(PlainDTO.class).in(DtoWithMethods.class)
> >
> > This is not yet implemented, it's just a suggestion. WDYT?
> >
> > Cheers,
> >
> > David
> >
> > On 18 October 2016 at 11:27, David Leangen <o...@leangen.net> wrote:
> >
> >>
> >> Hi David B.,
> >>
> >> Thanks for this suggestion. That would indeed work nicely. As you say,
> it
> >> requires an extra class, but at least there is very little duplication,
> at
> >> least converting TO something.
> >>
> >> Converting TO:
> >>
> >>> Map m = converter.convert(myDtoWithMethods).as(PlainDTO.
> >> class).to(Map.class)
> >>
> >> When converting FROM something, would this work?
> >>
> >> myDtoWithMethods = converter.convert(map).as(PlainDTO.class).to(
> >> DtoWithMethods.class)
> >>
> >> If so, then I think this would work just fine!
> >>
> >>
> >> Cheers,
> >> =David
> >>
> >>
> >>> On Oct 18, 2016, at 6:13 PM, David Bosschaert <
> >> david.bosscha...@gmail.com> wrote:
> >>>
> >>> Hi David L,
> >>>
> >>> Recently I added the 'as()' method to the converter, which is really
> >> meant
> >>> to disambiguate source objects. Let's say you have an object that is
> >> both a
> >>> JavaBean as well as implementing an interface. The Converter spec will
> >>> specify some 'priority' rules for this, but they may not always be what
> >> you
> >>> want. The as() method can be used to treat the source object in a
> >>> particular way.
> >>>
> >>> For example, let's say your MyClass extends MyBean implements Intf1
> >>> Let's say you want to force the converter to look at an instance of
> >> MyClass
> >>> as Intf1.
> >>>
> >>> You could then do
> >>> converter.convert(myobj).as(Intf1.class).to(Map.class)
> >>>
> >>> Would it help to use this for the DTO+methods as well?
> >>> You might have:
> >>>
> >>> Class PlainDto {
> >>> public String foo;
> >>> }
> >>>
> >>> Class DtoWithMethods extends PlainDto {
> >>> public int someMethod() {}
> >>> }
> >>>
> >>> And then maybe use these via:
> >>> converter.convert(myDtoWithMethods).as(PlainDTO.class).to(Map.class)
> >>> ?
> >>>
> >>> It would require a separate class that follows the pure DTO rules...
> >>>
> >>> Cheers,
> >>>
> >>> David
> >>>
> >>>
> >>> On 18 October 2016 at 09:49, David Leangen <o...@leangen.net> wrote:
> >>>
> >>>>
> >>>> Hi David B.,
> >>>>
> >>>> Thanks. I think you’re right, the spec is quite clear.
> >>>>
> >>>> If I wanted to treat any class like a DTO (ignore the methods and use
> >> only
> >>>> the public fields — just like before the recent changes made to the
> code
> >>>> base), can you think of any way?
> >>>>
> >>>> Perhaps having “strict” mode to follow the spec to the letter, and a
> >> less
> >>>> strict mode for people like me?
> >>>>
> >>>>
> >>>> wdyt?
> >>>>
> >>>> Cheers,
> >>>> =David
> >>>>
> >>>>
> >>>>> On Oct 18, 2016, at 5:45 PM, David Bosschaert <
> >>>> david.bosscha...@gmail.com> wrote:
> >>>>>
> >>>>> Hi all,
> >>>>>
> >>>>> The OSGi spec for DTOs is pretty clear. Section 57.2 of the R6 Core
> >> spec
> >>>>> states:
> >>>>>
> >>>>> "Data Transfer Objects are public classes with no methods, other than
> >> the
> >>>>> compiler supplied default
> >>>>> constructor"
> >>>>>
> >>>>> Therefore I would be reluctant to use a different definition for the
> >>>>> Converter.
> >>>>>
> >>>>> OTOH I think that there are a couple of options if you like to have
> >> 'DTOs
> >>>>> with behaviour':
> >>>>> * you could use JavaBeans. The getters/setters are understood by the
> >> the
> >>>>> converter and will result in similar behaviour, but the beans can
> have
> >>>>> other methods too.
> >>>>> * registry your own converter rules for these classes.
> >>>>>
> >>>>> Cheers,
> >>>>>
> >>>>> David
> >>>>>
> >>>>> On 16 October 2016 at 04:18, David Jencks <david_jen...@yahoo.com.
> >>>> invalid>
> >>>>> wrote:
> >>>>>
> >>>>>> Hi David L,
> >>>>>>
> >>>>>> I imagine the “extra step” and “redirection” are the need to create
> >> both
> >>>>>> the SomeDTO and the SomeImpl?
> >>>>>>
> >>>>>> Thinking about this a bit more I’m reminded that sometimes I end up
> >>>>>> thinking that putting that first “this” parameter back into every
> >> method
> >>>>>> that C++ took out might be a good idea :-)
> >>>>>>
> >>>>>> I started down this rabbit hole by thinking, what if we think of
> DTOs
> >> as
> >>>>>> primitive data types, like int or long, as much as possible.
> >>>>>>
> >>>>>> For your “business method” example, a static method
> >>>>>>
> >>>>>> class SomeHelper {
> >>>>>> public static String calculateFooBar(SomeDTO data) {return data.foo
> +
> >>>>>> “:” + data.bar;}
> >>>>>> }
> >>>>>>
> >>>>>> makes perhaps more sense than the SomeImpl I proposed before.  But
> if
> >>>> you
> >>>>>> want to do something more complicated, a builder to hold state
> >> (outside
> >>>> the
> >>>>>> DTO, presumably) can make sense:
> >>>>>>
> >>>>>> class SomeBuilder {
> >>>>>> String foo;
> >>>>>> String bar;
> >>>>>> SomeBuilder(SomeDTO data) {foo = data.foo;bar = data.bar;}
> >>>>>> public void append(SomeDTO moreData) {
> >>>>>>  data.foo = data.foo + ”,” + moreData.foo;
> >>>>>>  data.bar = data.bar + “,” + moreData.bar;
> >>>>>> }
> >>>>>>
> >>>>>> public String calculateFooBar() {return foo + “:” + bar;}
> >>>>>> }
> >>>>>>
> >>>>>> So I wonder what you end up with if you have
> >>>>>> -DTOs
> >>>>>> -a “Helper” class with only static methods taking one or more DTOs
> >>>>>> -a bunch of “builders” that hold state from one or more DTOs during
> >>>>>> multi-step calculations.
> >>>>>>
> >>>>>> I suppose there also needs to be some code to call some of these
> >>>>>> methods/builders, but I think you need that anyway.
> >>>>>>
> >>>>>> thanks
> >>>>>> david jencks
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>> On Oct 15, 2016, at 5:28 PM, David Leangen <o...@leangen.net>
> wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>> Hi David J.,
> >>>>>>>
> >>>>>>> That is an interesting perspective.
> >>>>>>>
> >>>>>>> Also based on the ideas proposed by Peter, and after a bit of
> >>>>>> experimentation, these are my thoughts:
> >>>>>>>
> >>>>>>> * Java object encapsulation “works", but only if we assume that
> there
> >>>> is
> >>>>>>>  no such thing as reflection. Since an object can be introspected,
> >> it
> >>>>>> means
> >>>>>>>  that there is no “complete” encapsulation, only “weak”
> >>>> encapsulation.
> >>>>>>>
> >>>>>>>   —> True. Important if thinking about security, maybe, but perhaps
> >>>>>> not
> >>>>>>>          very convincing to me to change my thinking.
> >>>>>>>
> >>>>>>> * DTOs are not real “Value Objects” because normally a VO should be
> >>>>>> immutable.
> >>>>>>>  However, if all we make are copies, and both the producer and
> >>>>>> consumer understand
> >>>>>>>  that it is a copy being shipped, then in the end, I cannot see a
> >>>>>> problem. It will cause me
> >>>>>>>  to change some habits, but I don’t see a problem.
> >>>>>>>
> >>>>>>> * Java8 and its “functional” flavour have really started to
> interest
> >>>> me.
> >>>>>>>
> >>>>>>>
> >>>>>>> Based mostly on the last two thoughts, I have tried using the
> >> pattern I
> >>>>>> wrote in my earlier post. In essence:
> >>>>>>>
> >>>>>>> * API interface - determines the contract with the rest of the
> world
> >>>>>>> * DTO - for transmitting and serializing (essential for a working
> >>>> system)
> >>>>>>> * Implementation object - usually Value Objects, but sometimes
> >> Entities
> >>>>>>>
> >>>>>>> By following most of the DTO rules, which generally means (1) make
> >>>>>> serialisable data public, (2) provide a no-arg public constructor,
> and
> >>>> (3)
> >>>>>> have a tree-like structure that only contains other “DTO-type”
> >> objects,
> >>>> the
> >>>>>> DTO can be combined with the implementation.
> >>>>>>>
> >>>>>>> This completely eliminates an extra step.
> >>>>>>>
> >>>>>>> No longer required:  serialized data —> DTO —> domain object
> >>>>>>>
> >>>>>>> New method: serialized data —> DTO (==domain object)
> >>>>>>>
> >>>>>>> I have even started to make my “simple” DTOs (i.e. pure VOs with
> >> little
> >>>>>> or no behaviour) part of the API instead of the impl.
> >>>>>>>
> >>>>>>> I have been very pleased with the results so far. However, if we
> >> don’t
> >>>>>> provide the possibility to relax the rules on the DTOs a bit, this
> >> will
> >>>> no
> >>>>>> longer be possible. I would be really sad to not be able to use this
> >>>>>> pattern, unless of course somebody has come up with a better /
> >> alternate
> >>>>>> solution.
> >>>>>>>
> >>>>>>>
> >>>>>>> What you propose below seems like it would encapsulate well, but it
> >>>>>> seems to me that the extra step of redirection would cause duplicate
> >>>> work.
> >>>>>> No?
> >>>>>>>
> >>>>>>>
> >>>>>>> Cheers,
> >>>>>>> =David
> >>>>>>>
> >>>>>>>
> >>>>>>>> On Oct 16, 2016, at 1:10 AM, David Jencks <david_jen...@yahoo.com
> .
> >>>> INVALID>
> >>>>>> wrote:
> >>>>>>>>
> >>>>>>>> A while ago Peter said something about DTOs violating data hiding
> or
> >>>>>> encapsulation and I decided that if you think of the DTO as a
> >> primitive
> >>>>>> data type they don’t.   Following this line of thinking (which I
> have
> >>>> not
> >>>>>> been able to try out in practice, just as thought experiments) you’d
> >>>> have
> >>>>>>>>
> >>>>>>>> public class SomeDTO extends DTO {
> >>>>>>>> public String foo;
> >>>>>>>> public String bar;
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public interface SomeInterface {
> >>>>>>>> SomeDTO data(); //I’m not sure this is needed
> >>>>>>>> String calculateFooBar();
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> public class SomeImpl {
> >>>>>>>> final SomeDTO data;
> >>>>>>>> public SomeImpl(SomeDTO data) {this.data = data;}
> >>>>>>>> public SomeDTO data() {return data;}
> >>>>>>>> public String calculateFooBar() {return data.foo + “:” +
> data.bar;}
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> I’m curious how this would work out in an actual situation,
> >> especially
> >>>>>> in knowing fi the “data()” accessor is needed.  I’d hope it would
> only
> >>>> be
> >>>>>> needed for serialization purposes.
> >>>>>>>>
> >>>>>>>> thanks
> >>>>>>>> david jencks
> >>>>>>>>
> >>>>>>>>> On Oct 14, 2016, at 9:52 PM, David Leangen <apa...@leangen.net>
> >>>> wrote:
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Hi!
> >>>>>>>>>
> >>>>>>>>> I only noticed now that according to the RFC, DTOs cannot contain
> >>>>>> methods. I can understand why this is so, and I do not object.
> >>>>>>>>>
> >>>>>>>>> However, I have found a very practical design pattern whereby I
> use
> >>>>>> classes that act both as DTOs and domain value objects. In effect,
> >> this
> >>>>>> means that they are DTOs with methods. I am willing to pay the price
> >> of
> >>>>>> having “bloated” DTOs for this convenience.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Would there be any way to allow configuration to permit this?
> >>>>>>>>>
> >>>>>>>>> If that is out of the question then any suggestions as to what I
> >>>> could
> >>>>>> do so as to not have to have “duplicate” classes (DTOs and domain
> >> VOs)?
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Example:
> >>>>>>>>>
> >>>>>>>>> Domain object API
> >>>>>>>>>
> >>>>>>>>> public interface SomeObject {
> >>>>>>>>> String foo();
> >>>>>>>>> String bar();
> >>>>>>>>> String calculateFoobar();
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>> Implementation
> >>>>>>>>>
> >>>>>>>>> public class SomeObjectDTO extends DTO implements SomeObject {
> >>>>>>>>> public String foo;
> >>>>>>>>> public String bar;
> >>>>>>>>>
> >>>>>>>>> public SomeObjectDTO() {}
> >>>>>>>>>
> >>>>>>>>> public SomeObjectDTO( String aFoo, String aBar ) {
> >>>>>>>>>   foo = aFoo; bar = aBar;
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>> @Override public String foo() { return foo; }
> >>>>>>>>> @Override public String bar() { return bar; }
> >>>>>>>>> @Override public String calculateFoobar() { return foo + “:” +
> >> bar; }
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> I like the above because:
> >>>>>>>>> * No duplication
> >>>>>>>>> * As a DTO, can be sent over the wire and serialised
> >>>>>>>>> * Implements the domain API
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Cheers,
> >>>>>>>>> =David
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>
> >>>>
> >>
> >>
>
>

Reply via email to