You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(3) |
Feb
(4) |
Mar
(1) |
Apr
(5) |
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
(6) |
2006 |
Jan
(1) |
Feb
(6) |
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(12) |
2007 |
Jan
(44) |
Feb
(36) |
Mar
(24) |
Apr
(59) |
May
(6) |
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
(2) |
Nov
(4) |
Dec
(3) |
2008 |
Jan
(34) |
Feb
(4) |
Mar
|
Apr
|
May
|
Jun
(4) |
Jul
|
Aug
(7) |
Sep
(2) |
Oct
|
Nov
(3) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(5) |
Nov
|
Dec
|
2010 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Matt B. <gud...@ya...> - 2008-02-07 23:43:23
|
I'm attaching a simple patch to allow defining a transformer name on BaseTransformer; this will be used as the identifier in the Log (and defaults to getClass().getName() for BC). It seems like this should be extremely helpful for debugging (I have a lot of outlandishly nested transformations that you might not even believe). WDYT? -Matt B ____________________________________________________________________________________ Looking for last minute shopping deals? Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping |
From: Matt B. <gud...@ya...> - 2008-01-31 21:40:57
|
--- Matt Sgarlata <mat...@sp...> wrote: > I was actually originally thinking of > isImprecise(Object,Object), but of > course that doesn't really work for converters, so I > hadn't through things > very clearly ;) It's probably a blessing in disguse > that > isImprecise(Class,Object) doesn't work, because that > interface really feels > like fudging things to me. > > How about this, for PNMC, just attempt to > instantiate an empty instance of > the source and destination and retrieve the > properties that way. If the > PNMC is able to instantiate the source and > destination and figure out the > properties of the objects, great. Otherwise, just > assume the transformation > is imprecise. Subclasses can refine the behavior. > How does that sound? > That sounds okay to me. > Or if that ends up being too much work, perhaps it > would be safest to just > assume PNMC is imprecise, because most of the time > it is going to be. This > is because PNMC takes any old Object as a source and > destination, so all the > nonsensical transformations like Integer -> Map get > thrown its way. > I'll keep this option in mind as well if I run into further trouble. Thanks, Matt B > Matt > > On Jan 31, 2008 2:03 PM, Matt Benson > <gud...@ya...> wrote: > > > Wait--this won't work with ChainedTransformer b/c > it > > wants to use classes when it's determining a > > conversion path (it doesn't have the intermediate > > objects). The only way to do this would be to > check > > each conversion step for precision; if precise > perform > > the conversion step and repeat. :( This is kind > of > > ugly and would at the very least require the > > conversion path to be cached. The caching isn't > > necessarily a bad idea anyway, but it still feels > very > > heavy. As does having separate interfaces and/or > > methods for Copiers vs. Converters. :( > > > > Matt B > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > like > > > > ImpreciseTransformer.isImpreciseTransformation(Class > > > destinationType, Object source)? So that it > would > > > be > > > compatible w/ both Copiers and Converters. That > > > makes > > > sense... thanks! > > > > > > -Matt B > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > wrote: > > > > > > > Perhaps it would make sense to change > > > > ImpreciseTransformer so that it > > > > operates on objects instead of classes? That > way > > > > you can give much more > > > > accurate results. For example, 3.0 (double) > is > > > > completely precise > > > > converting to the integer 3, whereas 3.01 -> > > > integer > > > > is not precise. > > > > > > > > Matt > > > > > > > > On Jan 30, 2008 10:15 AM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > --- Matt Sgarlata > > > > <mat...@sp...> > > > > > wrote: > > > > > > > > > > > To clarify, I am +0 on > ImpreciseTransformer. > > > I > > > > am > > > > > > -1 on > > > > > > PrecisionTransformer, but of course I am > all > > > > ears if > > > > > > you would like me to > > > > > > change my vote on that one ;) > > > > > > > > > > Hmm, I committed what I had for > > > > ImpreciseConverter, > > > > > refactored to ImpreciseTransformer. I began > to > > > > > implement ImpreciseTransformer for > > > > > PropertyNameMatchingCopier, with the idea > that > > > if > > > > > properties exist for the source object that > > > don't > > > > > exist on the destination object, then that > is > > > > > imprecise. The only problem is that > Reflectors > > > > work > > > > > on objects rather than classes. So I can't > > > tell > > > > this > > > > > info at the class level. Do you have any > > > > suggestions? > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > Matt > > > > > > > > > > > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > > > > > > <mat...@sp...> > > > > > > wrote: > > > > > > > > > > > > > Oh boy, it's an Apache pop quiz! If I > > > > remember > > > > > > correctly, I am +0 to > > > > > > > indicate I support the feature's > addition, > > > but > > > > I > > > > > > do not plan on actively > > > > > > > working on it myself. > > > > > > > > > > > > > > Just to remind you, I believe I have > already > > > > fixed > > > > > > the issue that > > > > > > > ImpreciseTransformer is intended to > address > > > by > > > > > > ensuring order of components > > > > > > > is always maintained. However, I see no > > > > problem > > > > > > with having 2 alternative > > > > > > > solutions to the issue. > > > > > > > > > > > > > > Matt > > > > > > > > > > > > > > > > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > Where did you end up on the > > > > ImpreciseTransformer > > > > > > idea? > > > > > > > > +1, -1, or +0? > > > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > <mat...@sp...> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > I see what you mean. I prefer > > > > > > ImpreciseTransformer > > > > > > > > > to PrecisionTransformer > > > > > > > > > because of the difficulty of > assigning a > > > > > > numeric > > > > > > > > > value for the degree of > > > > > > > > > precision. I think that assignment > is > > > > going > > > > > > to end > > > > > > > > > up arbitrary and > > > > > > > > > confusing pretty quickly. > > > > > > ImpreciseTransformer also > > > > > > > > > would probably make the > > > > > > > > > logic for determining the conversion > > > path > > > > > > simpler. > > > > > > > > > > > > > > > > > > In terms of using different paths > for > > > > > > different > > > > > > > > > source and destination > > > > > > > > > combos, I think perhaps the best > > > solution > > > > in > > > > > > such a > > > > > > > > > case would be to just > > > > > > > > > make a bunch of individual > > > > AssemblerCopiers > > > > > > with > > > > > > > > > individual paths, and then > > > > > > > > > add them all together using the > > > > > > > > > SimpleDelegatingTransformer. > > > > > > > > > > > > > > > > > > Matt > > > > > > > > > > > > > > > > > > On Jan 10, 2008 12:14 PM, Matt > Benson > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > You have a point, though I guess > my > > > aim > > > > in > > > > > > > > > avoiding > > > > > > > > > > such a thing was > that--usually--the > > > path > > > > is > > > > > > simple > > > > > > > > > > enough to determine given source > and > > > > dest > > > > > > classes. > > > > > > > > > > Secondly, you might use a > different > > > path > > > > > > depending > > > > > > > > > on > > > > > > > > > > available source/dest combos, so > the > > > > > > configuration > > > > > > > > > > might be a little more complex. > :| > > > As > > > > for > > > > > > where > > > > > > > > > > converters with awareness of > > > "precision" > > > > > > might be > > > > > > > > > > useful, I can't say that I know of > > > > another > > > > > > context > > > > > > > > > > right now, but at the very least I > > > would > > > > say > > > > > > it > > > > > > > > > might > > > > > > > > > > be useful knowledge for both > number > > > and > > > > text > > > > > > > > > types. > > > > > > > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > <mat...@sp...> > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > I agree, that does sound like it > > > could > > > > end > > > > > > up > > > > > > > > > being > > > > > > > > > > > somewhat arbitrary. I > > > > > > > > > > > know the original impetus for > this > > > was > > > > > > that > > > > > > > > > > > configuration of the > > > > > > > > > > > ChainedTransformer could be a > real > > > > pain in > > > > > > the > > > > > > > > > neck. > > > > > > > > > > > Are there other > > > > > > > > > > > situations where the information > > > > provided > > > > > > by > > > > > > > > > > > ImplicitTransformer or > > > > > > > > > > > PrecisionTransformer might be > > > useful? > > > > I > > > > > > guess > > > > > > > > > what > > > > > > > > > > > I'm getting at here is, > > > > > > > > > > > what is the requirement we are > > > trying > > > > to > > > > > > solve? > > > > > > > > > > > Perhaps if we think about > > > > > > > > > > > it in a new way a different > solution > > > > will > > > > > > > > > present > > > > > > > > > > > itself. > > > > > > > > > > > > > > > > > > > > > > Perhaps an alternative could be > to > > > > > > introduce a > > > > > > > > > new > > > > > > > > > > > setTransformationPath(Class[] > path) > > > > method > > > > > > to > > > > > > > > > the > > > > > > > > > > > ChainedTransformer. That > > > > > > > > > > > would make configuration a snap, > > > even > > > > if > > > > > > you > > > > > > > > > were > > > > > > > > > > > trying to use dependency > > > > > > > > > > > injection for the configuration. > > > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt > > > Benson > > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > > > More on this: what do you > think > > > > about > > > > > > the > > > > > > > > > concept > > > > > > > > > > > of > > > > > > > > > > > > something like a > > > > PrecisionTransformer > > > > > > that > > > > > > > > > returns > > > > > > > > > > > a > > > > > > > > > > > > float precision from 0.0 to > 1.0 > > > > given a > > > > > > > > > > > > destinationClass and a > > > sourceClass? > > > > > > These > > > > > > > > > might > > > > > > > > > > > be > > > > > > > > > > > > somewhat arbitrary, or > calculated > > > > (like > > > > > > with > > > > > > > > > > > numeric > > > > > > > > > > > > types), but they might allow a > > > > little > > > > > > more > > > > > > > > > > > > informedness on the part of > the > > > > > > consumer. > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Benson > > > > <gud...@ya...> > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > > > > > > > > > <mat...@sp...> > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > I have been thinking more > > > about > > > > this > > > > > > > > > approach, > > > > > > > > > > > and > > > > > > > > > > > > > > it's really starting to > > > > > > > > > > > > > > grow on me. I do have one > > > > concern > > > > > > though, > > > > > > > > > can > > > > > > > > > > > > > this > > > > > > > > > > > > > > approach be extended to > > > > > > > > > > > > > > Copiers? For example, a > Map > > > -> > > > > > > Object > > > > > > > > > copy > > > > > > > > > > > could > > > > > > > > > > > > > > probably be considered an > > > > > > > > > > > > > > imprecise transformation > > > because > > > > the > > > > > > Map > > > > > > > > > may > > > > > > > > > > > have > > > > > > > > > > > > > > more keys than the Object > > > > > > > > > > > > > > has properties. > > > > > > > > > > > > > > > > > > > > > > > > > > I thought about this as > well. > > > It > > > > > > could be > > > > > > > > > done; > > > > > > > > > > > it > > > > > > > > > > > > > might be slightly complex > > > > calculating > > > > > > the > > > > > > > > > > > > > "precision" > > > > > > > > > > > > > of a > > > PropertyNameMatchingCopier--I > > > > > > would > > > > > > > > > think > > > > > > > > > > > an > > > > > > > > > > > > > explicitly specified > PNMatchingC > > > > would > > > > > > be > > > > > > > > > > > precise; > > > > > > > > > > > > > an > > > > > > > > > > > > > imprecise one would be one > using > > > > > > property > > > > > > > > > name > > > > > > > > > > > > > discovery and where the > > > properties > > > > of > > > > > > the > > > > > > > > > source > > > > > > > > > > > are > > > > > > > > > > > > > not all available on the > > > > destination. > > > > > > > > > > > There--the > > > > > > > > > > > > > hard > > > > > > > > > > > > > part of that one is over. > :) I > > > > will > > > > > > work > > > > > > > > > on > > > > > > > > > > > > > ImpreciseConverter -> > > > > > > ImpreciseTransformer > > > > > > > > > > > extends > > > > > > > > > > > > > Transformer and other > semantic > > > > changes > > > > > > as > > > > > > > > > time > > > > > > > > > > > > > permits. Your ordering > changes > > > > are, I > > > > > > > > > expect, > > > > > > > > > > > fine > > > > > > > > > > > > > by > > > > > > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your > approach, > > > I > > > > also > > > > > > like > > > > > > > > > the > > > > > > > > > > > idea > > > > > > > > > > > > > > of cleaning up the > > > > > > > > > > > > > > internal implementation in > > > Morph > > > > so > > > > > > that > > > > > > > > > > > ordering > > > > > > > > > > > > > of > > > > > > > > > > > > > > source and destination > > > > > > > > > > > > > > classes is preserved for > the > > > > > > following > > > > > > > > > > > reasons: > > > > > > > > > > > > > > 1) for at least some > portion > > > of > > > > > > users, > > > > > > > > > setting > > > > > > > > > > > the > > > > > > > > > > > > > > order of source and > > > > > > > > > > > > > > destination classes will > make > > > > sense > > > > > > as an > > > > > > > > > > > > > indication > > > > > > > > > > > > > > of the transformer's > > > > > > > > > > > > > > preferences for performing > > > > > > transformations > > > > > > > > > (so > > > > > > > > > > > for > > > > > > > > > > > > > > this class of users, > > > > > > > > > > > > > > creating new transformers > that > > > > play > > > > > > nicely > > > > > > > > > > > with > > > > > > > > > > > > > the > > > > > > > > > > > > > > ChainedTransformerTestCase > > > will > > > > be > > > > > > > > > simpler) > > > > > > > > > > > > > > 2) I think a general > change > > > from > > > > > > using > > > > > > > > > > > HashSets to > > > > > > > > > > > > > > ordered sets in Morph's > > > > > > > > > > > > > > implementation will mean > > > > > > transformations > > > > > > > > > > > happen > > > > > > > > > > > > > more > > > > > > > > > > > > > > consistently across > > > > > > > > > > > > > > JVMs and across time on > the > > > same > > > > > > JVM, > > > > > > > > > leading > > > > > > > > > > > to a > > > > > > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > > > > > > > > > > > So, what I did is I > basically > > > > went > > > > > > through > > > > > > > > > the > > > > > > > > > > > > > Morph > > > > > > > > > > > > > > codebase and replaced > > > > > > > > > > > > > > HashSets with ordered sets > > > > > > (preference > > > > > > > > > order > > > > > > > > > > > is: > > > > > > > > > > > > > JDK > > > > > > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > > > > > > Commons-collections > > > > ListOrderedSet, > > > > > > copy > > > > > > > > > of > > > > > > > > > > > > > > ListOrderedSet in > > > > > > > > > > > > > > net.sf.morph.util). I was > > > never > > > > > > able to > > > > > > > > > > > modify > > > > > > > > > > > > > the > > > > > > > > > > > > > > ChainedTransformerTestCase > so > > > > that > > > > > > it > > > > > > > > > > > consistently > > > > > > > > > > > > > > threw an error. However, > > > > > > > > > > > > > > after working on the test > case > > > > long > > > > > > > > > enough, > > > > > > > > > > > > > > eventually something > changed > > > in > > > > > > > > > > > > > > my environment so that the > > > test > > > > > > started to > > > > > > > > > > > fail. > > > > > > > > > > > > > I > > > > > > > > > > > > > > did my change of > > > > > > > > > > > > > > HashSets to ordered sets, > and > > > > that > > > > > > was > > > > > > > > > able to > > > > > > > > > > > fix > > > > > > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > > > > > > > > > > > I checked in my changes > for > > > you > > > > to > > > > > > take a > > > > > > > > > look > > > > > > > > > > > > > at... > > > > > > > > > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, > Matt > > > > Benson > > > > > > > > > > > > > > <gud...@ya...> > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > > > > > > Be a better friend, > > > newshound, > > > > and > > > > > > > > > > > > > > > know-it-all with Yahoo! > > > > Mobile. > > > > > > Try it > > > > > > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > > > /* > > > > > > > > > > > > > > > - * Copyright 2004-2005, > > > 2007 > > > > the > > > > > > > > > original > > > > > > > > > > > > > author > > > > > > > > > > > > > > or authors. > > > > > > > > > > > > > > > + * Copyright 2004-2005, > > > > 2007-2008 > > > > > > the > > > > > > > > > > > original > > > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > > > * > > > > > > > > > > > > > > > * Licensed under the > Apache > > > > > > License, > > > > > > > > > > > Version > > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > > > not > > > > > > > > > > > > > > > * use this file except > in > > > > > > compliance > > > > > > > > > with > > > > > > > > > > > the > > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > public class > > > > > > > > > SimpleDelegatingTransformer > > > > > > > > > > > > > extends > > > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > > > implements > > > > > > > > > > > > > > > - > > > > SpecializableComposite, > > > > > > > > > > > > > > ExplicitTransformer, > > > > Transformer, > > > > > > > > > > > > > > > DecoratedCopier, > > > > > > DecoratedConverter, > > > > > > > > > > > Cloneable { > > > > > > > > > > > > > > > + > > > > > > SpecializableComposite, > > > > > > > > > > > > > > ExplicitTransformer, > > > > Transformer, > > > > > > > > > > > > > > > DecoratedCopier, > > > > > > > > > > > > > > > + > > > > > > DecoratedConverter, > > > > > > > > > > > Cloneable, > > > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > > > > > > BaseDelegatingTransformer > > > > > > > > > > > > > > with pluggable delegate > > > > > > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > > > > > > private static > class > > > > > > > > > MapThreadLocal > > > > > > > > > > > > > extends > > > > > > > > > > > > > > ThreadLocal { > > > > > > > > > > > > > > > protected > > > > Object > > > > > > > > > > > initialValue() { > > > > > > > > > > > > > > > > > > return > > > > new > > > > > > > > > HashMap(); > > > > > > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > private > Specializer > > > > > > specializer; > > > > > > > > > > > > > > > + private boolean > > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > private transient > > > > > > ThreadLocal > > > > > > > > > > > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > > > > > > = > > > > > > > > > > > new > > > > > > > > > > > > > > MapThreadLocal(); > > > > > > > > > > > > > > > private transient > > > > > > ThreadLocal > > > > > > > > > > > > > > stackDepthThreadLocal = > new > > > > > > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + protected > boolean > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > > destinationClass, Class > > > > > > sourceClass) { > > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > > > > > > + > > > > > > > > > > > sourceClass), > > > > > > > > > > > > > > destinationClass, > > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > > > > > > () > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > protected Class[] > > > > > > > > > > > getSourceClassesImpl() > > > > > > > > > > > > > > throws Exception { > > > > > > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > > > > > > * if > no > > > > > > suitable > > > > > > > > > > > transformer > > > > > > > > > > > > > > could be found > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > private > Transformer > > > > > > > > > > > getTransformer(Class > > > > > > > > > > > > > > transformerType, Class > > > > > > > > > > > > > > > destinationClass, Class > > > > > > sourceClass) > > > > > > > > > throws > > > > > > > > > > > > > > TransformationException { > > > > > > > > > > > > > > > + > Transformer > > > > > > candidate = > > > > > > > > > > > null; > > > > > > > > > > > > > > > for (int > i = > > > 0; > > > > i < > > > > > > > > > > > > > > components.length; i++) { > > > > > > > > > > > > > > > > // if > > > > the > > > > > > > > > transformer > > > > > > > > > > > is > > > > > > > > > > > > > > the correct type > > > > > > > > > > > > > > > > > > > Transformer > > > > > > > > > > > transformer = > > > > > > > > > > > > > > (Transformer) > > > > > > > > > > > > > > > components[i]; > > > > > > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > > > > > > > > > > > > > // > > > > > > if the > > > > > > > > > > > > > > transformer is capable of > > > > > > > > > > > > > > > performing the > > > transformation > > > > > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > > > > > > destinationClass, > > > > sourceClass)) { > > > > > > > > > > > > > > > + > > > > > > > > > if > > > > > > > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > > > > > > null > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > destinationClass, > > > > sourceClass)) { > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > candidate = transformer; > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > continue; > > > > > > > > > > > > > > > + > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > > > > > > > > > > > return > > > > > > > > > > > > > > transformer; > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > - > > > > > > > > > > > > > > > + > if > > > > > > (candidate != > > > > > > > > > > > null) { > > > > > > > > > > > > > > > + > > > > > > return > > > > > > > > > > > > > candidate; > > > > > > > > > > > > > > > + > } > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > throw new > > > > > > > > > > > > > TransformationException( > > > > > > > > > > > > > > > > > > "Could > > > > not > > > > > > find a > > > > > > > > > > > > > > transformer that can > transform > > > > > > > > > > > > > > > objects of " > > > > > > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > > > > > > > > > > > source); > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * Get the > > > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > > > > + * @return > boolean > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + public boolean > > > > > > > > > > > > > > > isPreferPreciseTransformers() > > > { > > > > > > > > > > > > > > > + return > > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * Set the > > > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > > > Default false. > > > > > > > > > > > > > > > + * @param > > > > > > > > > preferPreciseTransformers > > > > > > > > > > > the > > > > > > > > > > > > > > boolean to set > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + public void > > > > > > > > > > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > > > > > > + > > > > > > > > > > > this.preferPreciseTransformers = > > > > > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > \ No newline at end of > file > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > (revision 358) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * > Implementation of > > > > > > > > > > > > > isImpreciseConversion > > > > > > > > > > > > > > > + * @param > > > > destinationClass > > > > > > > > > > > > > > > + * @param > > > sourceClass > > > > > > > > > > > > > > > + * @return > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + protected > boolean > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > > destinationClass, Class > > > > > > sourceClass) { > > > > > > > > > > > > > > > + return > > > > > > destinationClass > > > > > > > > > == > > > > > > > > > > > null > > > > > > > > > > > > > && > > > > > > > > > > > > > > sourceClass != null; > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * Learn whether > the > > > > > > specified > > > > > > > > > > > > > conversion > > > > > > > > > > > > > > yields an imprecise > > > > > > > > > > > > > > > result. > > > > > > > > > > > > > > > + * @param > > > > destinationClass > > > > > > > > > > > > > > > + * @param > > > sourceClass > > > > > > > > > > > > > > > + * @return > boolean > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + public final > boolean > > > > > > > > > > > > > > > isImpreciseConversion(Class > > > > > > > > > destinationClass, > > > > > > > > > > > > > > > Class sourceClass) { > > > > > > > > > > > > > > > + try { > > > > > > > > > > > > > > > + > > > return > > > > > > > > > > > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > > + } catch > > > > (Exception > > > > > > e) { > > > > > > > > > > > > > > > + > if > > > (e > > > > > > instanceof > > > > > > > > > > > > > > RuntimeException && > > > > > > > > > > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > > > > > > + > > > > > > throw > > > > > > > > > > > > > > (RuntimeException) e; > > > > > > > > > > > > > > > + > } > > > > > > > > > > > > > > > + > > > throw > > > > new > > > > > > > > > > > > > > > TransformationException("Could > > > > not > > > > > > > > > > > > > > > determine if conversion > of " > > > > > > > > > > > > > > > + > > > > > > > > > + > > > > > > > > > > > > > > sourceClass + " to " + > > > > > > > > > > > > > > > destinationClass > > > > > > > > > > > > > > > + > > > > > > > > > + " > > > > > > > > > > > > > > results in a loss of > > > > > > > > > > > > > > > precision", e); > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > // property getters and > > > > setters > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > > > /* > > > > > > > > > > > > > > > - * Copyright 2004-2005, > > > 2007 > > > > the > > > > > > > > > original > > > > > > > > > > > > > author > > > > > > > > > > > > > > or authors. > > > > > > > > > > > > > > > + * Copyright 2004-2005, > > > > 2007-2008 > > > > > > the > > > > > > > > > > > original > > > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > > > * > > > > > > > > > > > > > > > * Licensed under the > Apache > > > > > > License, > > > > > > > > > > > Version > > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > > > not > > > > > > > > > > > > > > > * use this file except > in > > > > > > compliance > > > > > > > > > with > > > > > > > > > > > the > > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > > > > > > package > > > > > > > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > import > java.util.ArrayList; > > > > > > > > > > > > > > > +import > java.util.Iterator; > > > > > > > > > > > > > > > import java.util.List; > > > > > > > > > > > > > > > import > java.util.Locale; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > public class > > > > ChainedTransformer > > > > > > extends > > > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > > > implements > > > > > > > > > > > > > > > - > > > > > > DecoratedConverter, > > > > > > > > > > > > > > DecoratedCopier, > > > > ExplicitTransformer > > > > > > { > > > > > > > > > > > > > > > + > > > > > > DecoratedConverter, > > > > > > > > > > > > > > DecoratedCopier, > > > > > > ExplicitTransformer, > > > > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > > > copyConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + protected > boolean > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > > destinationClass, Class > > > > > > sourceClass) { > > > > > > > > > > > > > > > + List > > > > > > conversionPath = > > > > > > > > > > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > > + return > > > > > > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > > > > > > sourceClass, 0); > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > * Get the > converter > > > > used > > > > > > when > > > > > > > > > using > > > > > > > > > > > a > > > > > > > > > > > > > > ChainedTransformer as a > > > > > > > > > > > > > > > Copier. > > > > > > > > > > > > > > > * @return > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > > > > > > > throw > > > > new > > > > > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > + > > > > log.debug("Using > > > > > > chained > > > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > > > Object o > = > > > > source; > > > > > > > > > > > > > > > for (int > i = > > > 0; > > > > i < > > > > > > > > > > > > > > conversionPath.size(); > i++) { > > > > > > > > > > > > > > > o > = > > > > > > > > > > > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > > > > > > conversionPath.get(i), > o, > > > > locale); > > > > > > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > > > > > > > throw > > > > new > > > > > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > + > > > > log.debug("Using > > > > > > chained > > > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > > > Object > last = > > > > > > > > > > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > > > > > > > > > > conversionPath.get(chain.length - > > > > > > 2), > > > > > > > > > > > source, > > > > > > > > > > > > > > locale); > > > > > > > > > > > > > > > ((Copier) > > > > > > > > > > > > > copier).copy(destination, > > > > > > > > > > > > > > last, locale); > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > protected List > > > > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > > sourceType) { > > > > > > > > > > > > > > > - if > > > (sourceType > > > > != > > > > > > null) > > > > > > > > > { > > > > > > > > > > > > > > > - > List > > > > > > withoutNull > > > > > > > > > = > > > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > > sourceType, > > > > > > > > > > > > > 0, > > > > > > > > > > > > > > false); > > > > > > > > > > > > > > > - > if > > > > > > (withoutNull > > > > > > > > > != > > > > > > > > > > > null) > > > > > > > > > > > > > { > > > > > > > > > > > > > > > - > > > > > > return > > > > > > > > > > > > > > withoutNull; > > > > > > > > > > > > > > > - > } > > > > > > > > > > > > > > > - } > > > > > > > > > > > > > > > - return > > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > sourceType, > > > > > > > > > > > 0, > > > > > > > > > > > > > > > true); > > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > sourceType, > > > > > > > > > > > 0); > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > > > > > > * @param > allowNull > > > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > - private List > > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > > sourceType, int index, > > > boolean > > > > > > > > > allowNull) { > > > > > > > > > > > > > > > + private List > > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > > sourceType, int index) { > > > > > > > > > > > > > > > > Transformer[] > > > > chain > > > > > > = > > > > > > > > > > > getChain(); > > > > > > > > > > > > > > > > Transformer c > > > = > > > > > > > > > chain[index]; > > > > > > > > > > > > > > > if (index > + 1 > > > > == > > > > > > > > > > > chain.length) { > > > > > > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > return > > > > > > null; > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > + List > > > > > > possibleResult = > > > > > > > > > null; > > > > > > > > > > > > > > > Class[] > > > > available = > > > > > > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > > > > > > for (int > i = > > > 0; > > > > i < > > > > > > > > > > > > > > available.length; i++) { > > > > > > > > > > > > > > > - > if > > > > > > (available[i] > > > > > > > > > == > > > > > > > > > > > null > > > > > > > > > > > > > > && !allowNull) { > > > > > > > > > > > > > > > - > > > > > > > > > continue; > > > > > > > > > > > > > > > - > } > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > > > > > > available[i], > sourceType)) { > > > > > > > > > > > > > > > - > > > > > > List > > > > > > > > > tail = > > > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > > available[i], > > > > > > > > > > > > > > index + 1, allowNull); > > > > > > > > > > > > > > > + > > > > > > List > > > > > > > > > tail = > > > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > > available[i], > > > > > > > > > > > > > > index + 1); > > > > > > > > > > > > > > > > > > > > > > if > > > > > > (tail > > > > > > > > > != > > > > > > > > > > > null) > > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > > > > > > available[i]); > > > > > > > > > > > > > > > - > > > > > > > > > > > return > > > > > > > > > > > > > > tail; > > > > > > > > > > > > > > > + > > > > > > > > > if > > > > > > > > > > > > > > (isPrecise(tail, > sourceType, > > > > > > > > > > > > > > > index)) { > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > return tail; > > > > > > > > > > > > > > > + > > > > > > > > > } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > possibleResult = tail; > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > - return > null; > > > > > > > > > > > > > > > + return > > > > > > possibleResult; > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + private boolean > > > > > > isPrecise(List > > > > > > > > > > > > > > conversionPath, Class > > > > sourceType, > > > > > > > > > > > > > > > int index) { > > > > > > > > > > > > > > > + > > > Transformer[] > > > > > > chain = > > > > > > > > > > > > > getChain(); > > > > > > > > > > > > > > > + Class > > > > > > currentSource = > > > > > > > > > > > > > sourceType; > > > > > > > > > > > > > > > + int i = > 0; > > > > > > > > > > > > > > > + for > > > (Iterator > > > > iter > > > > > > = > > > > > > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > > > > > > + > > > Class > > > > > > > > > currentDest = > > > > > > > > > > > > > > (Class) iter.next(); > > > > > > > > > > > > > > > + > if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > > > > > > + i], currentDest, > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > currentSource)) { > > > > > > > > > > > > > > > + > > > > > > return > > > > > > > > > > > false; > > > > > > > > > > > > > > > + > } > > > > > > > > > > > > > > > + > > > > > > currentSource = > > > > > > > > > > > > > > currentDest; > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + return > true; > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > * Get the > components > > > > array > > > > > > > > > narrowed > > > > > > > > > > > to a > > > > > > > > > > > > > > Transformer[]. > > > > > > > > > > > > > > > * @return > > > > Transformer[] > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > (revision > > > > > > > > > > > > > > > 0) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > (revision > > > > > > > > > > > > > > > 0) > > > > > > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > > > > > > +/* > > > > > > > > > > > > > > > + * Copyright 2008 the > > > > original > > > > > > author > > > > > > > > > or > > > > > > > > > > > > > authors. > > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > > + * Licensed under the > > > Apache > > > > > > License, > > > > > > > > > > > Version > > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > > (the "License"); you > > > > > > > > > > > > > > > may not > > > > > > > > > > > > > > > + * use this file except > in > > > > > > compliance > > > > > > > > > with > > > > > > > > > > > the > > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > > + * the License at > > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > > + * Unless required by > > > > applicable > > > > > > law or > > > > > > > > > > > agreed > > > > > > > > > > > > > to > > > > > > > > > > > > > > in writing, software > > > > > > > > > > > > > > > + * distributed under > the > > > > License > > > > > > is > > > > > > > > > > > distributed > > > > > > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > > > > > > WITHOUT > > > > > > > > > > > > > > > + * WARRANTIES OR > CONDITIONS > > > > OF > > > > > > ANY > > > > > > > > > KIND, > > > > > > > > > > > either > > > > > > > > > > > > > > express or implied. See > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > + * License for the > specific > > > > > > language > > > > > > > > > > > governing > > > > > > > > > > > > > > permissions and > > > > > > > > > > > > > > > limitations under > > > > > > > > > > > > > > > + * the License. > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > +package > > > > net.sf.morph.transform; > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > +/** > > > > > > > > > > > > > > > + * Defines a converter > > > whose > > > > > > operation > > > > > > > > > may > > > > > > > > > > > > > result > > > > > > > > > > > > > > in a loss of data > > > > > > > > > > > > > > > precision. > > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > > + * @author mbenson > > > > > > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > +public interface > > > > > > ImpreciseConverter > > > > > > > > > extends > > > > > > > > > > > > > > Converter { > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * Learn whether > the > > > > > > specified > > > > > > > > > > > > > conversion > > > > > > > > > > > > > > might yield an imprecise > > > > > > > > > > > > > > > result. > > > > > > > > > > > > > > > + * @param > > > > destinationClass > > > > > > > > > > > > > > > + * @param > > > sourceClass > > > > > > > > > > > > > > > + * @return > boolean > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > + boolean > > > > > > > > > isImpreciseConversion(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > (revision 362) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > > > > > > import > > > net.sf.morph.Defaults; > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > > > +import > > > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > * Converts an object to > a > > > > textual > > > > > > > > > > > > > representation > > > > > > > > > > > > > > by calling the object's > > > > > > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > -public class > > > > > > ObjectToTextConverter > > > > > > > > > extends > > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > > > +public class > > > > > > ObjectToTextConverter > > > > > > > > > extends > > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > > DecoratedConverter, > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > > > textConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > > + protected > boolean > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > > destinationClass, Class > > > > > > sourceClass) { > > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > > > > destinationClass, > > > > String.class); > > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > > protected boolean > > > > > > > > > > > > > > > isWrappingRuntimeExceptions() > > > { > > > > > > > > > > > > > > > return true; > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > (revision 361) > > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > (wor... [truncated message content] |
From: Matt S. <mat...@sp...> - 2008-01-31 21:30:42
|
I was actually originally thinking of isImprecise(Object,Object), but of course that doesn't really work for converters, so I hadn't through things very clearly ;) It's probably a blessing in disguse that isImprecise(Class,Object) doesn't work, because that interface really feels like fudging things to me. How about this, for PNMC, just attempt to instantiate an empty instance of the source and destination and retrieve the properties that way. If the PNMC is able to instantiate the source and destination and figure out the properties of the objects, great. Otherwise, just assume the transformation is imprecise. Subclasses can refine the behavior. How does that sound? Or if that ends up being too much work, perhaps it would be safest to just assume PNMC is imprecise, because most of the time it is going to be. This is because PNMC takes any old Object as a source and destination, so all the nonsensical transformations like Integer -> Map get thrown its way. Matt On Jan 31, 2008 2:03 PM, Matt Benson <gud...@ya...> wrote: > Wait--this won't work with ChainedTransformer b/c it > wants to use classes when it's determining a > conversion path (it doesn't have the intermediate > objects). The only way to do this would be to check > each conversion step for precision; if precise perform > the conversion step and repeat. :( This is kind of > ugly and would at the very least require the > conversion path to be cached. The caching isn't > necessarily a bad idea anyway, but it still feels very > heavy. As does having separate interfaces and/or > methods for Copiers vs. Converters. :( > > Matt B > > --- Matt Benson <gud...@ya...> wrote: > > > like > > ImpreciseTransformer.isImpreciseTransformation(Class > > destinationType, Object source)? So that it would > > be > > compatible w/ both Copiers and Converters. That > > makes > > sense... thanks! > > > > -Matt B > > > > --- Matt Sgarlata > > <mat...@sp...> > > wrote: > > > > > Perhaps it would make sense to change > > > ImpreciseTransformer so that it > > > operates on objects instead of classes? That way > > > you can give much more > > > accurate results. For example, 3.0 (double) is > > > completely precise > > > converting to the integer 3, whereas 3.01 -> > > integer > > > is not precise. > > > > > > Matt > > > > > > On Jan 30, 2008 10:15 AM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > > wrote: > > > > > > > > > To clarify, I am +0 on ImpreciseTransformer. > > I > > > am > > > > > -1 on > > > > > PrecisionTransformer, but of course I am all > > > ears if > > > > > you would like me to > > > > > change my vote on that one ;) > > > > > > > > Hmm, I committed what I had for > > > ImpreciseConverter, > > > > refactored to ImpreciseTransformer. I began to > > > > implement ImpreciseTransformer for > > > > PropertyNameMatchingCopier, with the idea that > > if > > > > properties exist for the source object that > > don't > > > > exist on the destination object, then that is > > > > imprecise. The only problem is that Reflectors > > > work > > > > on objects rather than classes. So I can't > > tell > > > this > > > > info at the class level. Do you have any > > > suggestions? > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > Matt > > > > > > > > > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > > > > > <mat...@sp...> > > > > > wrote: > > > > > > > > > > > Oh boy, it's an Apache pop quiz! If I > > > remember > > > > > correctly, I am +0 to > > > > > > indicate I support the feature's addition, > > but > > > I > > > > > do not plan on actively > > > > > > working on it myself. > > > > > > > > > > > > Just to remind you, I believe I have already > > > fixed > > > > > the issue that > > > > > > ImpreciseTransformer is intended to address > > by > > > > > ensuring order of components > > > > > > is always maintained. However, I see no > > > problem > > > > > with having 2 alternative > > > > > > solutions to the issue. > > > > > > > > > > > > Matt > > > > > > > > > > > > > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > Where did you end up on the > > > ImpreciseTransformer > > > > > idea? > > > > > > > +1, -1, or +0? > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > <mat...@sp...> > > > > > > > wrote: > > > > > > > > > > > > > > > I see what you mean. I prefer > > > > > ImpreciseTransformer > > > > > > > > to PrecisionTransformer > > > > > > > > because of the difficulty of assigning a > > > > > numeric > > > > > > > > value for the degree of > > > > > > > > precision. I think that assignment is > > > going > > > > > to end > > > > > > > > up arbitrary and > > > > > > > > confusing pretty quickly. > > > > > ImpreciseTransformer also > > > > > > > > would probably make the > > > > > > > > logic for determining the conversion > > path > > > > > simpler. > > > > > > > > > > > > > > > > In terms of using different paths for > > > > > different > > > > > > > > source and destination > > > > > > > > combos, I think perhaps the best > > solution > > > in > > > > > such a > > > > > > > > case would be to just > > > > > > > > make a bunch of individual > > > AssemblerCopiers > > > > > with > > > > > > > > individual paths, and then > > > > > > > > add them all together using the > > > > > > > > SimpleDelegatingTransformer. > > > > > > > > > > > > > > > > Matt > > > > > > > > > > > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > You have a point, though I guess my > > aim > > > in > > > > > > > > avoiding > > > > > > > > > such a thing was that--usually--the > > path > > > is > > > > > simple > > > > > > > > > enough to determine given source and > > > dest > > > > > classes. > > > > > > > > > Secondly, you might use a different > > path > > > > > depending > > > > > > > > on > > > > > > > > > available source/dest combos, so the > > > > > configuration > > > > > > > > > might be a little more complex. :| > > As > > > for > > > > > where > > > > > > > > > converters with awareness of > > "precision" > > > > > might be > > > > > > > > > useful, I can't say that I know of > > > another > > > > > context > > > > > > > > > right now, but at the very least I > > would > > > say > > > > > it > > > > > > > > might > > > > > > > > > be useful knowledge for both number > > and > > > text > > > > > > > > types. > > > > > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > <mat...@sp...> > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > I agree, that does sound like it > > could > > > end > > > > > up > > > > > > > > being > > > > > > > > > > somewhat arbitrary. I > > > > > > > > > > know the original impetus for this > > was > > > > > that > > > > > > > > > > configuration of the > > > > > > > > > > ChainedTransformer could be a real > > > pain in > > > > > the > > > > > > > > neck. > > > > > > > > > > Are there other > > > > > > > > > > situations where the information > > > provided > > > > > by > > > > > > > > > > ImplicitTransformer or > > > > > > > > > > PrecisionTransformer might be > > useful? > > > I > > > > > guess > > > > > > > > what > > > > > > > > > > I'm getting at here is, > > > > > > > > > > what is the requirement we are > > trying > > > to > > > > > solve? > > > > > > > > > > Perhaps if we think about > > > > > > > > > > it in a new way a different solution > > > will > > > > > > > > present > > > > > > > > > > itself. > > > > > > > > > > > > > > > > > > > > Perhaps an alternative could be to > > > > > introduce a > > > > > > > > new > > > > > > > > > > setTransformationPath(Class[] path) > > > method > > > > > to > > > > > > > > the > > > > > > > > > > ChainedTransformer. That > > > > > > > > > > would make configuration a snap, > > even > > > if > > > > > you > > > > > > > > were > > > > > > > > > > trying to use dependency > > > > > > > > > > injection for the configuration. > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt > > Benson > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > More on this: what do you think > > > about > > > > > the > > > > > > > > concept > > > > > > > > > > of > > > > > > > > > > > something like a > > > PrecisionTransformer > > > > > that > > > > > > > > returns > > > > > > > > > > a > > > > > > > > > > > float precision from 0.0 to 1.0 > > > given a > > > > > > > > > > > destinationClass and a > > sourceClass? > > > > > These > > > > > > > > might > > > > > > > > > > be > > > > > > > > > > > somewhat arbitrary, or calculated > > > (like > > > > > with > > > > > > > > > > numeric > > > > > > > > > > > types), but they might allow a > > > little > > > > > more > > > > > > > > > > > informedness on the part of the > > > > > consumer. > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > --- Matt Benson > > > <gud...@ya...> > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > > > > > > > <mat...@sp...> > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > I have been thinking more > > about > > > this > > > > > > > > approach, > > > > > > > > > > and > > > > > > > > > > > > > it's really starting to > > > > > > > > > > > > > grow on me. I do have one > > > concern > > > > > though, > > > > > > > > can > > > > > > > > > > > > this > > > > > > > > > > > > > approach be extended to > > > > > > > > > > > > > Copiers? For example, a Map > > -> > > > > > Object > > > > > > > > copy > > > > > > > > > > could > > > > > > > > > > > > > probably be considered an > > > > > > > > > > > > > imprecise transformation > > because > > > the > > > > > Map > > > > > > > > may > > > > > > > > > > have > > > > > > > > > > > > > more keys than the Object > > > > > > > > > > > > > has properties. > > > > > > > > > > > > > > > > > > > > > > > > I thought about this as well. > > It > > > > > could be > > > > > > > > done; > > > > > > > > > > it > > > > > > > > > > > > might be slightly complex > > > calculating > > > > > the > > > > > > > > > > > > "precision" > > > > > > > > > > > > of a > > PropertyNameMatchingCopier--I > > > > > would > > > > > > > > think > > > > > > > > > > an > > > > > > > > > > > > explicitly specified PNMatchingC > > > would > > > > > be > > > > > > > > > > precise; > > > > > > > > > > > > an > > > > > > > > > > > > imprecise one would be one using > > > > > property > > > > > > > > name > > > > > > > > > > > > discovery and where the > > properties > > > of > > > > > the > > > > > > > > source > > > > > > > > > > are > > > > > > > > > > > > not all available on the > > > destination. > > > > > > > > > > There--the > > > > > > > > > > > > hard > > > > > > > > > > > > part of that one is over. :) I > > > will > > > > > work > > > > > > > > on > > > > > > > > > > > > ImpreciseConverter -> > > > > > ImpreciseTransformer > > > > > > > > > > extends > > > > > > > > > > > > Transformer and other semantic > > > changes > > > > > as > > > > > > > > time > > > > > > > > > > > > permits. Your ordering changes > > > are, I > > > > > > > > expect, > > > > > > > > > > fine > > > > > > > > > > > > by > > > > > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, > > I > > > also > > > > > like > > > > > > > > the > > > > > > > > > > idea > > > > > > > > > > > > > of cleaning up the > > > > > > > > > > > > > internal implementation in > > Morph > > > so > > > > > that > > > > > > > > > > ordering > > > > > > > > > > > > of > > > > > > > > > > > > > source and destination > > > > > > > > > > > > > classes is preserved for the > > > > > following > > > > > > > > > > reasons: > > > > > > > > > > > > > 1) for at least some portion > > of > > > > > users, > > > > > > > > setting > > > > > > > > > > the > > > > > > > > > > > > > order of source and > > > > > > > > > > > > > destination classes will make > > > sense > > > > > as an > > > > > > > > > > > > indication > > > > > > > > > > > > > of the transformer's > > > > > > > > > > > > > preferences for performing > > > > > transformations > > > > > > > > (so > > > > > > > > > > for > > > > > > > > > > > > > this class of users, > > > > > > > > > > > > > creating new transformers that > > > play > > > > > nicely > > > > > > > > > > with > > > > > > > > > > > > the > > > > > > > > > > > > > ChainedTransformerTestCase > > will > > > be > > > > > > > > simpler) > > > > > > > > > > > > > 2) I think a general change > > from > > > > > using > > > > > > > > > > HashSets to > > > > > > > > > > > > > ordered sets in Morph's > > > > > > > > > > > > > implementation will mean > > > > > transformations > > > > > > > > > > happen > > > > > > > > > > > > more > > > > > > > > > > > > > consistently across > > > > > > > > > > > > > JVMs and across time on the > > same > > > > > JVM, > > > > > > > > leading > > > > > > > > > > to a > > > > > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > > > > > > > > > So, what I did is I basically > > > went > > > > > through > > > > > > > > the > > > > > > > > > > > > Morph > > > > > > > > > > > > > codebase and replaced > > > > > > > > > > > > > HashSets with ordered sets > > > > > (preference > > > > > > > > order > > > > > > > > > > is: > > > > > > > > > > > > JDK > > > > > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > > > > > Commons-collections > > > ListOrderedSet, > > > > > copy > > > > > > > > of > > > > > > > > > > > > > ListOrderedSet in > > > > > > > > > > > > > net.sf.morph.util). I was > > never > > > > > able to > > > > > > > > > > modify > > > > > > > > > > > > the > > > > > > > > > > > > > ChainedTransformerTestCase so > > > that > > > > > it > > > > > > > > > > consistently > > > > > > > > > > > > > threw an error. However, > > > > > > > > > > > > > after working on the test case > > > long > > > > > > > > enough, > > > > > > > > > > > > > eventually something changed > > in > > > > > > > > > > > > > my environment so that the > > test > > > > > started to > > > > > > > > > > fail. > > > > > > > > > > > > I > > > > > > > > > > > > > did my change of > > > > > > > > > > > > > HashSets to ordered sets, and > > > that > > > > > was > > > > > > > > able to > > > > > > > > > > fix > > > > > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > > > > > > > > > I checked in my changes for > > you > > > to > > > > > take a > > > > > > > > look > > > > > > > > > > > > at... > > > > > > > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt > > > Benson > > > > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > > > > > Be a better friend, > > newshound, > > > and > > > > > > > > > > > > > > know-it-all with Yahoo! > > > Mobile. > > > > > Try it > > > > > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > > /* > > > > > > > > > > > > > > - * Copyright 2004-2005, > > 2007 > > > the > > > > > > > > original > > > > > > > > > > > > author > > > > > > > > > > > > > or authors. > > > > > > > > > > > > > > + * Copyright 2004-2005, > > > 2007-2008 > > > > > the > > > > > > > > > > original > > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > > * > > > > > > > > > > > > > > * Licensed under the Apache > > > > > License, > > > > > > > > > > Version > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > > not > > > > > > > > > > > > > > * use this file except in > > > > > compliance > > > > > > > > with > > > > > > > > > > the > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > import > > > > > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > > import > > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > public class > > > > > > > > SimpleDelegatingTransformer > > > > > > > > > > > > extends > > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > > implements > > > > > > > > > > > > > > - > > > SpecializableComposite, > > > > > > > > > > > > > ExplicitTransformer, > > > Transformer, > > > > > > > > > > > > > > DecoratedCopier, > > > > > DecoratedConverter, > > > > > > > > > > Cloneable { > > > > > > > > > > > > > > + > > > > > SpecializableComposite, > > > > > > > > > > > > > ExplicitTransformer, > > > Transformer, > > > > > > > > > > > > > > DecoratedCopier, > > > > > > > > > > > > > > + > > > > > DecoratedConverter, > > > > > > > > > > Cloneable, > > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > > > > > BaseDelegatingTransformer > > > > > > > > > > > > > with pluggable delegate > > > > > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > > > > > private static class > > > > > > > > MapThreadLocal > > > > > > > > > > > > extends > > > > > > > > > > > > > ThreadLocal { > > > > > > > > > > > > > > protected > > > Object > > > > > > > > > > initialValue() { > > > > > > > > > > > > > > > > return > > > new > > > > > > > > HashMap(); > > > > > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Specializer > > > > > specializer; > > > > > > > > > > > > > > + private boolean > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > > > > > > > > > private transient > > > > > ThreadLocal > > > > > > > > > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > > > > > = > > > > > > > > > > new > > > > > > > > > > > > > MapThreadLocal(); > > > > > > > > > > > > > > private transient > > > > > ThreadLocal > > > > > > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) { > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > > > > > + > > > > > > > > > > sourceClass), > > > > > > > > > > > > > destinationClass, > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > > > > > () > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > protected Class[] > > > > > > > > > > getSourceClassesImpl() > > > > > > > > > > > > > throws Exception { > > > > > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > > > > > * if no > > > > > suitable > > > > > > > > > > transformer > > > > > > > > > > > > > could be found > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > private Transformer > > > > > > > > > > getTransformer(Class > > > > > > > > > > > > > transformerType, Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) > > > > > > > > throws > > > > > > > > > > > > > TransformationException { > > > > > > > > > > > > > > + Transformer > > > > > candidate = > > > > > > > > > > null; > > > > > > > > > > > > > > for (int i = > > 0; > > > i < > > > > > > > > > > > > > components.length; i++) { > > > > > > > > > > > > > > // if > > > the > > > > > > > > transformer > > > > > > > > > > is > > > > > > > > > > > > > the correct type > > > > > > > > > > > > > > > > > Transformer > > > > > > > > > > transformer = > > > > > > > > > > > > > (Transformer) > > > > > > > > > > > > > > components[i]; > > > > > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > > > > > > > > > > // > > > > > if the > > > > > > > > > > > > > transformer is capable of > > > > > > > > > > > > > > performing the > > transformation > > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > > > > > destinationClass, > > > sourceClass)) { > > > > > > > > > > > > > > + > > > > > > > > if > > > > > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > > > > > null > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > > > > > + > > > > > > > > > > > > > > destinationClass, > > > sourceClass)) { > > > > > > > > > > > > > > + > > > > > > > > > > > > > candidate = transformer; > > > > > > > > > > > > > > + > > > > > > > > > > > > > continue; > > > > > > > > > > > > > > + > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > > > > > > > > > return > > > > > > > > > > > > > transformer; > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > } > > > > > > > > > > > > > > - > > > > > > > > > > > > > > + if > > > > > (candidate != > > > > > > > > > > null) { > > > > > > > > > > > > > > + > > > > > return > > > > > > > > > > > > candidate; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > } > > > > > > > > > > > > > > throw new > > > > > > > > > > > > TransformationException( > > > > > > > > > > > > > > > > "Could > > > not > > > > > find a > > > > > > > > > > > > > transformer that can transform > > > > > > > > > > > > > > objects of " > > > > > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > > > > > > > > > source); > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * Get the > > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + public boolean > > > > > > > > > > > > > isPreferPreciseTransformers() > > { > > > > > > > > > > > > > > + return > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * Set the > > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > > Default false. > > > > > > > > > > > > > > + * @param > > > > > > > > preferPreciseTransformers > > > > > > > > > > the > > > > > > > > > > > > > boolean to set > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + public void > > > > > > > > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > > > > > + > > > > > > > > > > this.preferPreciseTransformers = > > > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > } > > > > > > > > > > > > > > \ No newline at end of file > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > (revision 358) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > > > > > } > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * Implementation of > > > > > > > > > > > > isImpreciseConversion > > > > > > > > > > > > > > + * @param > > > destinationClass > > > > > > > > > > > > > > + * @param > > sourceClass > > > > > > > > > > > > > > + * @return > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) { > > > > > > > > > > > > > > + return > > > > > destinationClass > > > > > > > > == > > > > > > > > > > null > > > > > > > > > > > > && > > > > > > > > > > > > > sourceClass != null; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * Learn whether the > > > > > specified > > > > > > > > > > > > conversion > > > > > > > > > > > > > yields an imprecise > > > > > > > > > > > > > > result. > > > > > > > > > > > > > > + * @param > > > destinationClass > > > > > > > > > > > > > > + * @param > > sourceClass > > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + public final boolean > > > > > > > > > > > > > isImpreciseConversion(Class > > > > > > > > destinationClass, > > > > > > > > > > > > > > Class sourceClass) { > > > > > > > > > > > > > > + try { > > > > > > > > > > > > > > + > > return > > > > > > > > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > + } catch > > > (Exception > > > > > e) { > > > > > > > > > > > > > > + if > > (e > > > > > instanceof > > > > > > > > > > > > > RuntimeException && > > > > > > > > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > > > > > + > > > > > throw > > > > > > > > > > > > > (RuntimeException) e; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > throw > > > new > > > > > > > > > > > > > TransformationException("Could > > > not > > > > > > > > > > > > > > determine if conversion of " > > > > > > > > > > > > > > + > > > > > > > > + > > > > > > > > > > > > > sourceClass + " to " + > > > > > > > > > > > > > > destinationClass > > > > > > > > > > > > > > + > > > > > > > > + " > > > > > > > > > > > > > results in a loss of > > > > > > > > > > > > > > precision", e); > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > // property getters and > > > setters > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > > /* > > > > > > > > > > > > > > - * Copyright 2004-2005, > > 2007 > > > the > > > > > > > > original > > > > > > > > > > > > author > > > > > > > > > > > > > or authors. > > > > > > > > > > > > > > + * Copyright 2004-2005, > > > 2007-2008 > > > > > the > > > > > > > > > > original > > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > > * > > > > > > > > > > > > > > * Licensed under the Apache > > > > > License, > > > > > > > > > > Version > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > > not > > > > > > > > > > > > > > * use this file except in > > > > > compliance > > > > > > > > with > > > > > > > > > > the > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > > > > > package > > > > > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > > > > > > +import java.util.Iterator; > > > > > > > > > > > > > > import java.util.List; > > > > > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > > import > > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > public class > > > ChainedTransformer > > > > > extends > > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > > implements > > > > > > > > > > > > > > - > > > > > DecoratedConverter, > > > > > > > > > > > > > DecoratedCopier, > > > ExplicitTransformer > > > > > { > > > > > > > > > > > > > > + > > > > > DecoratedConverter, > > > > > > > > > > > > > DecoratedCopier, > > > > > ExplicitTransformer, > > > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > > copyConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) { > > > > > > > > > > > > > > + List > > > > > conversionPath = > > > > > > > > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > + return > > > > > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > > > > > sourceClass, 0); > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > * Get the converter > > > used > > > > > when > > > > > > > > using > > > > > > > > > > a > > > > > > > > > > > > > ChainedTransformer as a > > > > > > > > > > > > > > Copier. > > > > > > > > > > > > > > * @return > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > > > > > throw > > > new > > > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > > } > > > > > > > > > > > > > > + > > > log.debug("Using > > > > > chained > > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > > Object o = > > > source; > > > > > > > > > > > > > > for (int i = > > 0; > > > i < > > > > > > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > > > > > > o = > > > > > > > > > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > > > > > conversionPath.get(i), o, > > > locale); > > > > > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > > > > > throw > > > new > > > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > > } > > > > > > > > > > > > > > + > > > log.debug("Using > > > > > chained > > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > > Object last = > > > > > > > > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > > > > > > > > conversionPath.get(chain.length - > > > > > 2), > > > > > > > > > > source, > > > > > > > > > > > > > locale); > > > > > > > > > > > > > > ((Copier) > > > > > > > > > > > > copier).copy(destination, > > > > > > > > > > > > > last, locale); > > > > > > > > > > > > > > } > > > > > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > protected List > > > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > sourceType) { > > > > > > > > > > > > > > - if > > (sourceType > > > != > > > > > null) > > > > > > > > { > > > > > > > > > > > > > > - List > > > > > withoutNull > > > > > > > > = > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > sourceType, > > > > > > > > > > > > 0, > > > > > > > > > > > > > false); > > > > > > > > > > > > > > - if > > > > > (withoutNull > > > > > > > > != > > > > > > > > > > null) > > > > > > > > > > > > { > > > > > > > > > > > > > > - > > > > > return > > > > > > > > > > > > > withoutNull; > > > > > > > > > > > > > > - } > > > > > > > > > > > > > > - } > > > > > > > > > > > > > > - return > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > sourceType, > > > > > > > > > > 0, > > > > > > > > > > > > > > true); > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > sourceType, > > > > > > > > > > 0); > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > > > > > * @param allowNull > > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > - private List > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > sourceType, int index, > > boolean > > > > > > > > allowNull) { > > > > > > > > > > > > > > + private List > > > > > > > > getConversionPath(Class > > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > > sourceType, int index) { > > > > > > > > > > > > > > Transformer[] > > > chain > > > > > = > > > > > > > > > > getChain(); > > > > > > > > > > > > > > Transformer c > > = > > > > > > > > chain[index]; > > > > > > > > > > > > > > if (index + 1 > > > == > > > > > > > > > > chain.length) { > > > > > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > return > > > > > null; > > > > > > > > > > > > > > } > > > > > > > > > > > > > > + List > > > > > possibleResult = > > > > > > > > null; > > > > > > > > > > > > > > Class[] > > > available = > > > > > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > > > > > for (int i = > > 0; > > > i < > > > > > > > > > > > > > available.length; i++) { > > > > > > > > > > > > > > - if > > > > > (available[i] > > > > > > > > == > > > > > > > > > > null > > > > > > > > > > > > > && !allowNull) { > > > > > > > > > > > > > > - > > > > > > > > continue; > > > > > > > > > > > > > > - } > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > > > > > available[i], sourceType)) { > > > > > > > > > > > > > > - > > > > > List > > > > > > > > tail = > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > available[i], > > > > > > > > > > > > > index + 1, allowNull); > > > > > > > > > > > > > > + > > > > > List > > > > > > > > tail = > > > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > > available[i], > > > > > > > > > > > > > index + 1); > > > > > > > > > > > > > > > > > > > if > > > > > (tail > > > > > > > > != > > > > > > > > > > null) > > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > > > > > available[i]); > > > > > > > > > > > > > > - > > > > > > > > > > return > > > > > > > > > > > > > tail; > > > > > > > > > > > > > > + > > > > > > > > if > > > > > > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > > > > > > index)) { > > > > > > > > > > > > > > + > > > > > > > > > > > > > return tail; > > > > > > > > > > > > > > + > > > > > > > > } > > > > > > > > > > > > > > + > > > > > > > > > > > > > possibleResult = tail; > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > } > > > > > > > > > > > > > > } > > > > > > > > > > > > > > - return null; > > > > > > > > > > > > > > + return > > > > > possibleResult; > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > + private boolean > > > > > isPrecise(List > > > > > > > > > > > > > conversionPath, Class > > > sourceType, > > > > > > > > > > > > > > int index) { > > > > > > > > > > > > > > + > > Transformer[] > > > > > chain = > > > > > > > > > > > > getChain(); > > > > > > > > > > > > > > + Class > > > > > currentSource = > > > > > > > > > > > > sourceType; > > > > > > > > > > > > > > + int i = 0; > > > > > > > > > > > > > > + for > > (Iterator > > > iter > > > > > = > > > > > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > > > > > + > > Class > > > > > > > > currentDest = > > > > > > > > > > > > > (Class) iter.next(); > > > > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > > > > > + i], currentDest, > > > > > > > > > > > > > > + > > > > > > > > > > > > > currentSource)) { > > > > > > > > > > > > > > + > > > > > return > > > > > > > > > > false; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > currentSource = > > > > > > > > > > > > > currentDest; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + return true; > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > * Get the components > > > array > > > > > > > > narrowed > > > > > > > > > > to a > > > > > > > > > > > > > Transformer[]. > > > > > > > > > > > > > > * @return > > > Transformer[] > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > (revision > > > > > > > > > > > > > > 0) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > (revision > > > > > > > > > > > > > > 0) > > > > > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > > > > > +/* > > > > > > > > > > > > > > + * Copyright 2008 the > > > original > > > > > author > > > > > > > > or > > > > > > > > > > > > authors. > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > + * Licensed under the > > Apache > > > > > License, > > > > > > > > > > Version > > > > > > > > > > > > 2.0 > > > > > > > > > > > > > (the "License"); you > > > > > > > > > > > > > > may not > > > > > > > > > > > > > > + * use this file except in > > > > > compliance > > > > > > > > with > > > > > > > > > > the > > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > > copy of > > > > > > > > > > > > > > + * the License at > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > + * > > > > > > > > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > + * Unless required by > > > applicable > > > > > law or > > > > > > > > > > agreed > > > > > > > > > > > > to > > > > > > > > > > > > > in writing, software > > > > > > > > > > > > > > + * distributed under the > > > License > > > > > is > > > > > > > > > > distributed > > > > > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > > > > > WITHOUT > > > > > > > > > > > > > > + * WARRANTIES OR CONDITIONS > > > OF > > > > > ANY > > > > > > > > KIND, > > > > > > > > > > either > > > > > > > > > > > > > express or implied. See > > > > > > > > > > > > > > the > > > > > > > > > > > > > > + * License for the specific > > > > > language > > > > > > > > > > governing > > > > > > > > > > > > > permissions and > > > > > > > > > > > > > > limitations under > > > > > > > > > > > > > > + * the License. > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > +package > > > net.sf.morph.transform; > > > > > > > > > > > > > > + > > > > > > > > > > > > > > +/** > > > > > > > > > > > > > > + * Defines a converter > > whose > > > > > operation > > > > > > > > may > > > > > > > > > > > > result > > > > > > > > > > > > > in a loss of data > > > > > > > > > > > > > > precision. > > > > > > > > > > > > > > + * > > > > > > > > > > > > > > + * @author mbenson > > > > > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > +public interface > > > > > ImpreciseConverter > > > > > > > > extends > > > > > > > > > > > > > Converter { > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * Learn whether the > > > > > specified > > > > > > > > > > > > conversion > > > > > > > > > > > > > might yield an imprecise > > > > > > > > > > > > > > result. > > > > > > > > > > > > > > + * @param > > > destinationClass > > > > > > > > > > > > > > + * @param > > sourceClass > > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + boolean > > > > > > > > isImpreciseConversion(Class > > > > > > > > > > > > > destinationClass, Class > > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > (revision 362) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > > > > > import > > net.sf.morph.Defaults; > > > > > > > > > > > > > > import > > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > > +import > > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > * Converts an object to a > > > textual > > > > > > > > > > > > representation > > > > > > > > > > > > > by calling the object's > > > > > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > -public class > > > > > ObjectToTextConverter > > > > > > > > extends > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > > +public class > > > > > ObjectToTextConverter > > > > > > > > extends > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > DecoratedConverter, > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > > textConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) { > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > > > destinationClass, > > > String.class); > > > > > > > > > > > > > > + } > > > > > > > > > > > > > > + > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > protected boolean > > > > > > > > > > > > > isWrappingRuntimeExceptions() > > { > > > > > > > > > > > > > > return true; > > > > > > > > > > > > > > } > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > (revision 361) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > > > > > > import > > > > > > > > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > - * Converts basic text > > types > > > into > > > > > > > > primtive > > > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > > > + * Converts basic text > > types > > > into > > > > > > > > primitive > > > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > > > * objects. > > > > > > > > > > > > > > * > > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > (revision 363) > > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > > > > > > import > > net.sf.morph.Defaults; > > > > > > > > > > > > > > import > > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > > +import > > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > * Converts {@link > > > > > java.lang.Number}s > > > > > > > > into > > > > > > > > > > basic > > > > > > > > > > > > > text types ({@link > > > > > > > > > > > > > > java.lang.String}, > > > > > > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > > > > > > */ > > > > > > > > > > > > > > -public class > > > > > NumberToTextConverter > > > > > > > > extends > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > > +public class > > > > > NumberToTextConverter > > > > > > > > extends > > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > > > + > > > ImpreciseConverter > > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > > textConverter; > > > > > > > > > > > > > > private Converter > > > > > > > > numberConverter; > > > > > > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > > + */ > > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > > destinationClass, Class > > > > > sourceClass) { > > > > > > > > > > > > > > + return > > > > > > > > > > > > > > ... [truncated message content] |
From: Matt B. <gud...@ya...> - 2008-01-31 19:04:07
|
Wait--this won't work with ChainedTransformer b/c it wants to use classes when it's determining a conversion path (it doesn't have the intermediate objects). The only way to do this would be to check each conversion step for precision; if precise perform the conversion step and repeat. :( This is kind of ugly and would at the very least require the conversion path to be cached. The caching isn't necessarily a bad idea anyway, but it still feels very heavy. As does having separate interfaces and/or methods for Copiers vs. Converters. :( Matt B --- Matt Benson <gud...@ya...> wrote: > like > ImpreciseTransformer.isImpreciseTransformation(Class > destinationType, Object source)? So that it would > be > compatible w/ both Copiers and Converters. That > makes > sense... thanks! > > -Matt B > > --- Matt Sgarlata > <mat...@sp...> > wrote: > > > Perhaps it would make sense to change > > ImpreciseTransformer so that it > > operates on objects instead of classes? That way > > you can give much more > > accurate results. For example, 3.0 (double) is > > completely precise > > converting to the integer 3, whereas 3.01 -> > integer > > is not precise. > > > > Matt > > > > On Jan 30, 2008 10:15 AM, Matt Benson > > <gud...@ya...> wrote: > > > > > > > > --- Matt Sgarlata > > <mat...@sp...> > > > wrote: > > > > > > > To clarify, I am +0 on ImpreciseTransformer. > I > > am > > > > -1 on > > > > PrecisionTransformer, but of course I am all > > ears if > > > > you would like me to > > > > change my vote on that one ;) > > > > > > Hmm, I committed what I had for > > ImpreciseConverter, > > > refactored to ImpreciseTransformer. I began to > > > implement ImpreciseTransformer for > > > PropertyNameMatchingCopier, with the idea that > if > > > properties exist for the source object that > don't > > > exist on the destination object, then that is > > > imprecise. The only problem is that Reflectors > > work > > > on objects rather than classes. So I can't > tell > > this > > > info at the class level. Do you have any > > suggestions? > > > > > > -Matt B > > > > > > > > > > > > > > Matt > > > > > > > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > > > > <mat...@sp...> > > > > wrote: > > > > > > > > > Oh boy, it's an Apache pop quiz! If I > > remember > > > > correctly, I am +0 to > > > > > indicate I support the feature's addition, > but > > I > > > > do not plan on actively > > > > > working on it myself. > > > > > > > > > > Just to remind you, I believe I have already > > fixed > > > > the issue that > > > > > ImpreciseTransformer is intended to address > by > > > > ensuring order of components > > > > > is always maintained. However, I see no > > problem > > > > with having 2 alternative > > > > > solutions to the issue. > > > > > > > > > > Matt > > > > > > > > > > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > > > Where did you end up on the > > ImpreciseTransformer > > > > idea? > > > > > > +1, -1, or +0? > > > > > > > > > > > > -Matt > > > > > > > > > > > > --- Matt Sgarlata > > > > <mat...@sp...> > > > > > > wrote: > > > > > > > > > > > > > I see what you mean. I prefer > > > > ImpreciseTransformer > > > > > > > to PrecisionTransformer > > > > > > > because of the difficulty of assigning a > > > > numeric > > > > > > > value for the degree of > > > > > > > precision. I think that assignment is > > going > > > > to end > > > > > > > up arbitrary and > > > > > > > confusing pretty quickly. > > > > ImpreciseTransformer also > > > > > > > would probably make the > > > > > > > logic for determining the conversion > path > > > > simpler. > > > > > > > > > > > > > > In terms of using different paths for > > > > different > > > > > > > source and destination > > > > > > > combos, I think perhaps the best > solution > > in > > > > such a > > > > > > > case would be to just > > > > > > > make a bunch of individual > > AssemblerCopiers > > > > with > > > > > > > individual paths, and then > > > > > > > add them all together using the > > > > > > > SimpleDelegatingTransformer. > > > > > > > > > > > > > > Matt > > > > > > > > > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > You have a point, though I guess my > aim > > in > > > > > > > avoiding > > > > > > > > such a thing was that--usually--the > path > > is > > > > simple > > > > > > > > enough to determine given source and > > dest > > > > classes. > > > > > > > > Secondly, you might use a different > path > > > > depending > > > > > > > on > > > > > > > > available source/dest combos, so the > > > > configuration > > > > > > > > might be a little more complex. :| > As > > for > > > > where > > > > > > > > converters with awareness of > "precision" > > > > might be > > > > > > > > useful, I can't say that I know of > > another > > > > context > > > > > > > > right now, but at the very least I > would > > say > > > > it > > > > > > > might > > > > > > > > be useful knowledge for both number > and > > text > > > > > > > types. > > > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > <mat...@sp...> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > I agree, that does sound like it > could > > end > > > > up > > > > > > > being > > > > > > > > > somewhat arbitrary. I > > > > > > > > > know the original impetus for this > was > > > > that > > > > > > > > > configuration of the > > > > > > > > > ChainedTransformer could be a real > > pain in > > > > the > > > > > > > neck. > > > > > > > > > Are there other > > > > > > > > > situations where the information > > provided > > > > by > > > > > > > > > ImplicitTransformer or > > > > > > > > > PrecisionTransformer might be > useful? > > I > > > > guess > > > > > > > what > > > > > > > > > I'm getting at here is, > > > > > > > > > what is the requirement we are > trying > > to > > > > solve? > > > > > > > > > Perhaps if we think about > > > > > > > > > it in a new way a different solution > > will > > > > > > > present > > > > > > > > > itself. > > > > > > > > > > > > > > > > > > Perhaps an alternative could be to > > > > introduce a > > > > > > > new > > > > > > > > > setTransformationPath(Class[] path) > > method > > > > to > > > > > > > the > > > > > > > > > ChainedTransformer. That > > > > > > > > > would make configuration a snap, > even > > if > > > > you > > > > > > > were > > > > > > > > > trying to use dependency > > > > > > > > > injection for the configuration. > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt > Benson > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > More on this: what do you think > > about > > > > the > > > > > > > concept > > > > > > > > > of > > > > > > > > > > something like a > > PrecisionTransformer > > > > that > > > > > > > returns > > > > > > > > > a > > > > > > > > > > float precision from 0.0 to 1.0 > > given a > > > > > > > > > > destinationClass and a > sourceClass? > > > > These > > > > > > > might > > > > > > > > > be > > > > > > > > > > somewhat arbitrary, or calculated > > (like > > > > with > > > > > > > > > numeric > > > > > > > > > > types), but they might allow a > > little > > > > more > > > > > > > > > > informedness on the part of the > > > > consumer. > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > --- Matt Benson > > <gud...@ya...> > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > > > > > <mat...@sp...> > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > I have been thinking more > about > > this > > > > > > > approach, > > > > > > > > > and > > > > > > > > > > > > it's really starting to > > > > > > > > > > > > grow on me. I do have one > > concern > > > > though, > > > > > > > can > > > > > > > > > > > this > > > > > > > > > > > > approach be extended to > > > > > > > > > > > > Copiers? For example, a Map > -> > > > > Object > > > > > > > copy > > > > > > > > > could > > > > > > > > > > > > probably be considered an > > > > > > > > > > > > imprecise transformation > because > > the > > > > Map > > > > > > > may > > > > > > > > > have > > > > > > > > > > > > more keys than the Object > > > > > > > > > > > > has properties. > > > > > > > > > > > > > > > > > > > > > > I thought about this as well. > It > > > > could be > > > > > > > done; > > > > > > > > > it > > > > > > > > > > > might be slightly complex > > calculating > > > > the > > > > > > > > > > > "precision" > > > > > > > > > > > of a > PropertyNameMatchingCopier--I > > > > would > > > > > > > think > > > > > > > > > an > > > > > > > > > > > explicitly specified PNMatchingC > > would > > > > be > > > > > > > > > precise; > > > > > > > > > > > an > > > > > > > > > > > imprecise one would be one using > > > > property > > > > > > > name > > > > > > > > > > > discovery and where the > properties > > of > > > > the > > > > > > > source > > > > > > > > > are > > > > > > > > > > > not all available on the > > destination. > > > > > > > > > There--the > > > > > > > > > > > hard > > > > > > > > > > > part of that one is over. :) I > > will > > > > work > > > > > > > on > > > > > > > > > > > ImpreciseConverter -> > > > > ImpreciseTransformer > > > > > > > > > extends > > > > > > > > > > > Transformer and other semantic > > changes > > > > as > > > > > > > time > > > > > > > > > > > permits. Your ordering changes > > are, I > > > > > > > expect, > > > > > > > > > fine > > > > > > > > > > > by > > > > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, > I > > also > > > > like > > > > > > > the > > > > > > > > > idea > > > > > > > > > > > > of cleaning up the > > > > > > > > > > > > internal implementation in > Morph > > so > > > > that > > > > > > > > > ordering > > > > > > > > > > > of > > > > > > > > > > > > source and destination > > > > > > > > > > > > classes is preserved for the > > > > following > > > > > > > > > reasons: > > > > > > > > > > > > 1) for at least some portion > of > > > > users, > > > > > > > setting > > > > > > > > > the > > > > > > > > > > > > order of source and > > > > > > > > > > > > destination classes will make > > sense > > > > as an > > > > > > > > > > > indication > > > > > > > > > > > > of the transformer's > > > > > > > > > > > > preferences for performing > > > > transformations > > > > > > > (so > > > > > > > > > for > > > > > > > > > > > > this class of users, > > > > > > > > > > > > creating new transformers that > > play > > > > nicely > > > > > > > > > with > > > > > > > > > > > the > > > > > > > > > > > > ChainedTransformerTestCase > will > > be > > > > > > > simpler) > > > > > > > > > > > > 2) I think a general change > from > > > > using > > > > > > > > > HashSets to > > > > > > > > > > > > ordered sets in Morph's > > > > > > > > > > > > implementation will mean > > > > transformations > > > > > > > > > happen > > > > > > > > > > > more > > > > > > > > > > > > consistently across > > > > > > > > > > > > JVMs and across time on the > same > > > > JVM, > > > > > > > leading > > > > > > > > > to a > > > > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > > > > > > > So, what I did is I basically > > went > > > > through > > > > > > > the > > > > > > > > > > > Morph > > > > > > > > > > > > codebase and replaced > > > > > > > > > > > > HashSets with ordered sets > > > > (preference > > > > > > > order > > > > > > > > > is: > > > > > > > > > > > JDK > > > > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > > > > Commons-collections > > ListOrderedSet, > > > > copy > > > > > > > of > > > > > > > > > > > > ListOrderedSet in > > > > > > > > > > > > net.sf.morph.util). I was > never > > > > able to > > > > > > > > > modify > > > > > > > > > > > the > > > > > > > > > > > > ChainedTransformerTestCase so > > that > > > > it > > > > > > > > > consistently > > > > > > > > > > > > threw an error. However, > > > > > > > > > > > > after working on the test case > > long > > > > > > > enough, > > > > > > > > > > > > eventually something changed > in > > > > > > > > > > > > my environment so that the > test > > > > started to > > > > > > > > > fail. > > > > > > > > > > > I > > > > > > > > > > > > did my change of > > > > > > > > > > > > HashSets to ordered sets, and > > that > > > > was > > > > > > > able to > > > > > > > > > fix > > > > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > > > > > > > I checked in my changes for > you > > to > > > > take a > > > > > > > look > > > > > > > > > > > at... > > > > > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt > > Benson > > > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > > > > Be a better friend, > newshound, > > and > > > > > > > > > > > > > know-it-all with Yahoo! > > Mobile. > > > > Try it > > > > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > /* > > > > > > > > > > > > > - * Copyright 2004-2005, > 2007 > > the > > > > > > > original > > > > > > > > > > > author > > > > > > > > > > > > or authors. > > > > > > > > > > > > > + * Copyright 2004-2005, > > 2007-2008 > > > > the > > > > > > > > > original > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > * > > > > > > > > > > > > > * Licensed under the Apache > > > > License, > > > > > > > > > Version > > > > > > > > > > > 2.0 > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > not > > > > > > > > > > > > > * use this file except in > > > > compliance > > > > > > > with > > > > > > > > > the > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > copy of > > > > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > > > > */ > > > > > > > > > > > > > public class > > > > > > > SimpleDelegatingTransformer > > > > > > > > > > > extends > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > implements > > > > > > > > > > > > > - > > SpecializableComposite, > > > > > > > > > > > > ExplicitTransformer, > > Transformer, > > > > > > > > > > > > > DecoratedCopier, > > > > DecoratedConverter, > > > > > > > > > Cloneable { > > > > > > > > > > > > > + > > > > SpecializableComposite, > > > > > > > > > > > > ExplicitTransformer, > > Transformer, > > > > > > > > > > > > > DecoratedCopier, > > > > > > > > > > > > > + > > > > DecoratedConverter, > > > > > > > > > Cloneable, > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > > > > BaseDelegatingTransformer > > > > > > > > > > > > with pluggable delegate > > > > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > > > > private static class > > > > > > > MapThreadLocal > > > > > > > > > > > extends > > > > > > > > > > > > ThreadLocal { > > > > > > > > > > > > > protected > > Object > > > > > > > > > initialValue() { > > > > > > > > > > > > > > return > > new > > > > > > > HashMap(); > > > > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > private Specializer > > > > specializer; > > > > > > > > > > > > > + private boolean > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > > > > > > > private transient > > > > ThreadLocal > > > > > > > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > > > > = > > > > > > > > > new > > > > > > > > > > > > MapThreadLocal(); > > > > > > > > > > > > > private transient > > > > ThreadLocal > > > > > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > > > > + > > > > > > > > > sourceClass), > > > > > > > > > > > > destinationClass, > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > > > > () > > > > > > > > > > > > > */ > > > > > > > > > > > > > protected Class[] > > > > > > > > > getSourceClassesImpl() > > > > > > > > > > > > throws Exception { > > > > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > > > > * if no > > > > suitable > > > > > > > > > transformer > > > > > > > > > > > > could be found > > > > > > > > > > > > > */ > > > > > > > > > > > > > private Transformer > > > > > > > > > getTransformer(Class > > > > > > > > > > > > transformerType, Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) > > > > > > > throws > > > > > > > > > > > > TransformationException { > > > > > > > > > > > > > + Transformer > > > > candidate = > > > > > > > > > null; > > > > > > > > > > > > > for (int i = > 0; > > i < > > > > > > > > > > > > components.length; i++) { > > > > > > > > > > > > > // if > > the > > > > > > > transformer > > > > > > > > > is > > > > > > > > > > > > the correct type > > > > > > > > > > > > > > > Transformer > > > > > > > > > transformer = > > > > > > > > > > > > (Transformer) > > > > > > > > > > > > > components[i]; > > > > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > > > > > > > // > > > > if the > > > > > > > > > > > > transformer is capable of > > > > > > > > > > > > > performing the > transformation > > > > > > > > > > > > > > > > if > > > > > > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > > > > destinationClass, > > sourceClass)) { > > > > > > > > > > > > > + > > > > > > > if > > > > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > > > > null > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > > > > + > > > > > > > > > > > > > destinationClass, > > sourceClass)) { > > > > > > > > > > > > > + > > > > > > > > > > > > candidate = transformer; > > > > > > > > > > > > > + > > > > > > > > > > > > continue; > > > > > > > > > > > > > + > > > > > > > } > > > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > > > > > > > return > > > > > > > > > > > > transformer; > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > } > > > > > > > > > > > > > - > > > > > > > > > > > > > + if > > > > (candidate != > > > > > > > > > null) { > > > > > > > > > > > > > + > > > > return > > > > > > > > > > > candidate; > > > > > > > > > > > > > + } > > > > > > > > > > > > > } > > > > > > > > > > > > > throw new > > > > > > > > > > > TransformationException( > > > > > > > > > > > > > > "Could > > not > > > > find a > > > > > > > > > > > > transformer that can transform > > > > > > > > > > > > > objects of " > > > > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > > > > > > > source); > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * Get the > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + public boolean > > > > > > > > > > > > isPreferPreciseTransformers() > { > > > > > > > > > > > > > + return > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * Set the > > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > Default false. > > > > > > > > > > > > > + * @param > > > > > > > preferPreciseTransformers > > > > > > > > > the > > > > > > > > > > > > boolean to set > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + public void > > > > > > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > > > > + > > > > > > > > > this.preferPreciseTransformers = > > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > } > > > > > > > > > > > > > \ No newline at end of file > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > (revision 358) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > > > > } > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * Implementation of > > > > > > > > > > > isImpreciseConversion > > > > > > > > > > > > > + * @param > > destinationClass > > > > > > > > > > > > > + * @param > sourceClass > > > > > > > > > > > > > + * @return > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + return > > > > destinationClass > > > > > > > == > > > > > > > > > null > > > > > > > > > > > && > > > > > > > > > > > > sourceClass != null; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * Learn whether the > > > > specified > > > > > > > > > > > conversion > > > > > > > > > > > > yields an imprecise > > > > > > > > > > > > > result. > > > > > > > > > > > > > + * @param > > destinationClass > > > > > > > > > > > > > + * @param > sourceClass > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + public final boolean > > > > > > > > > > > > isImpreciseConversion(Class > > > > > > > destinationClass, > > > > > > > > > > > > > Class sourceClass) { > > > > > > > > > > > > > + try { > > > > > > > > > > > > > + > return > > > > > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > + } catch > > (Exception > > > > e) { > > > > > > > > > > > > > + if > (e > > > > instanceof > > > > > > > > > > > > RuntimeException && > > > > > > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > > > > + > > > > throw > > > > > > > > > > > > (RuntimeException) e; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > throw > > new > > > > > > > > > > > > TransformationException("Could > > not > > > > > > > > > > > > > determine if conversion of " > > > > > > > > > > > > > + > > > > > > > + > > > > > > > > > > > > sourceClass + " to " + > > > > > > > > > > > > > destinationClass > > > > > > > > > > > > > + > > > > > > > + " > > > > > > > > > > > > results in a loss of > > > > > > > > > > > > > precision", e); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > // property getters and > > setters > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > > /* > > > > > > > > > > > > > - * Copyright 2004-2005, > 2007 > > the > > > > > > > original > > > > > > > > > > > author > > > > > > > > > > > > or authors. > > > > > > > > > > > > > + * Copyright 2004-2005, > > 2007-2008 > > > > the > > > > > > > > > original > > > > > > > > > > > > author or authors. > > > > > > > > > > > > > * > > > > > > > > > > > > > * Licensed under the Apache > > > > License, > > > > > > > > > Version > > > > > > > > > > > 2.0 > > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > > not > > > > > > > > > > > > > * use this file except in > > > > compliance > > > > > > > with > > > > > > > > > the > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > copy of > > > > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > > > > package > > > > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > > > > > +import java.util.Iterator; > > > > > > > > > > > > > import java.util.List; > > > > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > > > > */ > > > > > > > > > > > > > public class > > ChainedTransformer > > > > extends > > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > > implements > > > > > > > > > > > > > - > > > > DecoratedConverter, > > > > > > > > > > > > DecoratedCopier, > > ExplicitTransformer > > > > { > > > > > > > > > > > > > + > > > > DecoratedConverter, > > > > > > > > > > > > DecoratedCopier, > > > > ExplicitTransformer, > > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > copyConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + List > > > > conversionPath = > > > > > > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > + return > > > > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > > > > sourceClass, 0); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > * Get the converter > > used > > > > when > > > > > > > using > > > > > > > > > a > > > > > > > > > > > > ChainedTransformer as a > > > > > > > > > > > > > Copier. > > > > > > > > > > > > > * @return > > > > > > > > > > > > > */ > > > > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > > > > throw > > new > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > } > > > > > > > > > > > > > + > > log.debug("Using > > > > chained > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > Object o = > > source; > > > > > > > > > > > > > for (int i = > 0; > > i < > > > > > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > > > > > o = > > > > > > > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > > > > conversionPath.get(i), o, > > locale); > > > > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > > > > throw > > new > > > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > > conversion path could not > > > > > > > > > > > > > be determined"); > > > > > > > > > > > > > } > > > > > > > > > > > > > + > > log.debug("Using > > > > chained > > > > > > > > > > > > conversion path " + > > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > > Object last = > > > > > > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > > > > > > conversionPath.get(chain.length - > > > > 2), > > > > > > > > > source, > > > > > > > > > > > > locale); > > > > > > > > > > > > > ((Copier) > > > > > > > > > > > copier).copy(destination, > > > > > > > > > > > > last, locale); > > > > > > > > > > > > > } > > > > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > */ > > > > > > > > > > > > > protected List > > > > > > > > > getConversionPath(Class > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > sourceType) { > > > > > > > > > > > > > - if > (sourceType > > != > > > > null) > > > > > > > { > > > > > > > > > > > > > - List > > > > withoutNull > > > > > > > = > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > sourceType, > > > > > > > > > > > 0, > > > > > > > > > > > > false); > > > > > > > > > > > > > - if > > > > (withoutNull > > > > > > > != > > > > > > > > > null) > > > > > > > > > > > { > > > > > > > > > > > > > - > > > > return > > > > > > > > > > > > withoutNull; > > > > > > > > > > > > > - } > > > > > > > > > > > > > - } > > > > > > > > > > > > > - return > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > sourceType, > > > > > > > > > 0, > > > > > > > > > > > > > true); > > > > > > > > > > > > > + return > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > sourceType, > > > > > > > > > 0); > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > > > > * @param allowNull > > > > > > > > > > > > > * @return List > > > > > > > > > > > > > */ > > > > > > > > > > > > > - private List > > > > > > > getConversionPath(Class > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > sourceType, int index, > boolean > > > > > > > allowNull) { > > > > > > > > > > > > > + private List > > > > > > > getConversionPath(Class > > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > > sourceType, int index) { > > > > > > > > > > > > > Transformer[] > > chain > > > > = > > > > > > > > > getChain(); > > > > > > > > > > > > > Transformer c > = > > > > > > > chain[index]; > > > > > > > > > > > > > if (index + 1 > > == > > > > > > > > > chain.length) { > > > > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > > > > } > > > > > > > > > > > > > > return > > > > null; > > > > > > > > > > > > > } > > > > > > > > > > > > > + List > > > > possibleResult = > > > > > > > null; > > > > > > > > > > > > > Class[] > > available = > > > > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > > > > for (int i = > 0; > > i < > > > > > > > > > > > > available.length; i++) { > > > > > > > > > > > > > - if > > > > (available[i] > > > > > > > == > > > > > > > > > null > > > > > > > > > > > > && !allowNull) { > > > > > > > > > > > > > - > > > > > > > continue; > > > > > > > > > > > > > - } > > > > > > > > > > > > > if > > > > > > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > > > > available[i], sourceType)) { > > > > > > > > > > > > > - > > > > List > > > > > > > tail = > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > available[i], > > > > > > > > > > > > index + 1, allowNull); > > > > > > > > > > > > > + > > > > List > > > > > > > tail = > > > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > > available[i], > > > > > > > > > > > > index + 1); > > > > > > > > > > > > > > > > if > > > > (tail > > > > > > > != > > > > > > > > > null) > > > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > > > > available[i]); > > > > > > > > > > > > > - > > > > > > > > > return > > > > > > > > > > > > tail; > > > > > > > > > > > > > + > > > > > > > if > > > > > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > > > > > index)) { > > > > > > > > > > > > > + > > > > > > > > > > > > return tail; > > > > > > > > > > > > > + > > > > > > > } > > > > > > > > > > > > > + > > > > > > > > > > > > possibleResult = tail; > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > } > > > > > > > > > > > > > } > > > > > > > > > > > > > - return null; > > > > > > > > > > > > > + return > > > > possibleResult; > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > + private boolean > > > > isPrecise(List > > > > > > > > > > > > conversionPath, Class > > sourceType, > > > > > > > > > > > > > int index) { > > > > > > > > > > > > > + > Transformer[] > > > > chain = > > > > > > > > > > > getChain(); > > > > > > > > > > > > > + Class > > > > currentSource = > > > > > > > > > > > sourceType; > > > > > > > > > > > > > + int i = 0; > > > > > > > > > > > > > + for > (Iterator > > iter > > > > = > > > > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > > > > + > Class > > > > > > > currentDest = > > > > > > > > > > > > (Class) iter.next(); > > > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > > > > + i], currentDest, > > > > > > > > > > > > > + > > > > > > > > > > > > currentSource)) { > > > > > > > > > > > > > + > > > > return > > > > > > > > > false; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > currentSource = > > > > > > > > > > > > currentDest; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + return true; > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > /** > > > > > > > > > > > > > * Get the components > > array > > > > > > > narrowed > > > > > > > > > to a > > > > > > > > > > > > Transformer[]. > > > > > > > > > > > > > * @return > > Transformer[] > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > (revision > > > > > > > > > > > > > 0) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > (revision > > > > > > > > > > > > > 0) > > > > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > > > > +/* > > > > > > > > > > > > > + * Copyright 2008 the > > original > > > > author > > > > > > > or > > > > > > > > > > > authors. > > > > > > > > > > > > > + * > > > > > > > > > > > > > + * Licensed under the > Apache > > > > License, > > > > > > > > > Version > > > > > > > > > > > 2.0 > > > > > > > > > > > > (the "License"); you > > > > > > > > > > > > > may not > > > > > > > > > > > > > + * use this file except in > > > > compliance > > > > > > > with > > > > > > > > > the > > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > > copy of > > > > > > > > > > > > > + * the License at > > > > > > > > > > > > > + * > > > > > > > > > > > > > + * > > > > > > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > > > > + * > > > > > > > > > > > > > + * Unless required by > > applicable > > > > law or > > > > > > > > > agreed > > > > > > > > > > > to > > > > > > > > > > > > in writing, software > > > > > > > > > > > > > + * distributed under the > > License > > > > is > > > > > > > > > distributed > > > > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > > > > WITHOUT > > > > > > > > > > > > > + * WARRANTIES OR CONDITIONS > > OF > > > > ANY > > > > > > > KIND, > > > > > > > > > either > > > > > > > > > > > > express or implied. See > > > > > > > > > > > > > the > > > > > > > > > > > > > + * License for the specific > > > > language > > > > > > > > > governing > > > > > > > > > > > > permissions and > > > > > > > > > > > > > limitations under > > > > > > > > > > > > > + * the License. > > > > > > > > > > > > > + */ > > > > > > > > > > > > > +package > > net.sf.morph.transform; > > > > > > > > > > > > > + > > > > > > > > > > > > > +/** > > > > > > > > > > > > > + * Defines a converter > whose > > > > operation > > > > > > > may > > > > > > > > > > > result > > > > > > > > > > > > in a loss of data > > > > > > > > > > > > > precision. > > > > > > > > > > > > > + * > > > > > > > > > > > > > + * @author mbenson > > > > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > > > > + */ > > > > > > > > > > > > > +public interface > > > > ImpreciseConverter > > > > > > > extends > > > > > > > > > > > > Converter { > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * Learn whether the > > > > specified > > > > > > > > > > > conversion > > > > > > > > > > > > might yield an imprecise > > > > > > > > > > > > > result. > > > > > > > > > > > > > + * @param > > destinationClass > > > > > > > > > > > > > + * @param > sourceClass > > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + boolean > > > > > > > isImpreciseConversion(Class > > > > > > > > > > > > destinationClass, Class > > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > (revision 362) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > > > > import > net.sf.morph.Defaults; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > +import > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > * Converts an object to a > > textual > > > > > > > > > > > representation > > > > > > > > > > > > by calling the object's > > > > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > > > > */ > > > > > > > > > > > > > -public class > > > > ObjectToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > +public class > > > > ObjectToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter, > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > textConverter; > > > > > > > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > > > > /** > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > > destinationClass, > > String.class); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > + */ > > > > > > > > > > > > > protected boolean > > > > > > > > > > > > isWrappingRuntimeExceptions() > { > > > > > > > > > > > > > return true; > > > > > > > > > > > > > } > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > (revision 361) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > > > > > import > > > > > > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > - * Converts basic text > types > > into > > > > > > > primtive > > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > > + * Converts basic text > types > > into > > > > > > > primitive > > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > > * objects. > > > > > > > > > > > > > * > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > (revision 363) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > > > > > import > net.sf.morph.Defaults; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > +import > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > * Converts {@link > > > > java.lang.Number}s > > > > > > > into > > > > > > > > > basic > > > > > > > > > > > > text types ({@link > > > > > > > > > > > > > java.lang.String}, > > > > > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > > > > > */ > > > > > > > > > > > > > -public class > > > > NumberToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > +public class > > > > NumberToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > > + > > ImpreciseConverter > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > > textConverter; > > > > > > > > > > > > > private Converter > > > > > > > numberConverter; > > > > > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > + */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > > destinationClass, > > String.class); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > * Get the number > > converter > > > > used > > > > > > > by > > > > > > > > > this > > > > > > > > > > > > NumberToTextConverter. > > > > > > > > > > > > > * @return Converter > > > > > > > > > > > > > */ > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > (revision 360) > > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > (working copy) > > > > > > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > > > > > > import > net.sf.morph.Defaults; > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > > +import > > > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > > +import > > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > > * Converts the basic time > > types > > > > ({@link > > > > > > > > > > > > java.util.Date} and > > > > > > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > > * @since Dec 31, 2004 > > > > > > > > > > > > > */ > > > > > > > > > > > > > -public class > > TimeToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > > +public class > > TimeToTextConverter > > > > > > > extends > > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > > + > > ImpreciseConverter > > > > { > > > > > > > > > > > > > > > > > > > > > > > > > > private DateFormat > > > > dateFormat; > > > > > > > > > > > > > private Converter > > > > timeConverter; > > > > > > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > > > > > > /** > > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > > */ > > > > > > > > > > > > > + protected boolean > > > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > > destinationClass, Class > > > > sourceClass) { > > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > > destinationClass, > > String.class); > > > > > > > > > > > > > + } > > > > > > > > > > > > > + > > > > > > > > > > > > > + /** > > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > > + */ > > > > > > > > > > > > > protected boolean > > > > > > > > > > > > isWrappingRuntimeExceptions() > { > > > > > > > > > > > > > return true; > > > > > > > > > > > > > } > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > >... [truncated message content] |
From: Matt B. <gud...@ya...> - 2008-01-31 18:54:19
|
like ImpreciseTransformer.isImpreciseTransformation(Class destinationType, Object source)? So that it would be compatible w/ both Copiers and Converters. That makes sense... thanks! -Matt B --- Matt Sgarlata <mat...@sp...> wrote: > Perhaps it would make sense to change > ImpreciseTransformer so that it > operates on objects instead of classes? That way > you can give much more > accurate results. For example, 3.0 (double) is > completely precise > converting to the integer 3, whereas 3.01 -> integer > is not precise. > > Matt > > On Jan 30, 2008 10:15 AM, Matt Benson > <gud...@ya...> wrote: > > > > > --- Matt Sgarlata > <mat...@sp...> > > wrote: > > > > > To clarify, I am +0 on ImpreciseTransformer. I > am > > > -1 on > > > PrecisionTransformer, but of course I am all > ears if > > > you would like me to > > > change my vote on that one ;) > > > > Hmm, I committed what I had for > ImpreciseConverter, > > refactored to ImpreciseTransformer. I began to > > implement ImpreciseTransformer for > > PropertyNameMatchingCopier, with the idea that if > > properties exist for the source object that don't > > exist on the destination object, then that is > > imprecise. The only problem is that Reflectors > work > > on objects rather than classes. So I can't tell > this > > info at the class level. Do you have any > suggestions? > > > > -Matt B > > > > > > > > > > Matt > > > > > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > > > <mat...@sp...> > > > wrote: > > > > > > > Oh boy, it's an Apache pop quiz! If I > remember > > > correctly, I am +0 to > > > > indicate I support the feature's addition, but > I > > > do not plan on actively > > > > working on it myself. > > > > > > > > Just to remind you, I believe I have already > fixed > > > the issue that > > > > ImpreciseTransformer is intended to address by > > > ensuring order of components > > > > is always maintained. However, I see no > problem > > > with having 2 alternative > > > > solutions to the issue. > > > > > > > > Matt > > > > > > > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > > > Where did you end up on the > ImpreciseTransformer > > > idea? > > > > > +1, -1, or +0? > > > > > > > > > > -Matt > > > > > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > > > wrote: > > > > > > > > > > > I see what you mean. I prefer > > > ImpreciseTransformer > > > > > > to PrecisionTransformer > > > > > > because of the difficulty of assigning a > > > numeric > > > > > > value for the degree of > > > > > > precision. I think that assignment is > going > > > to end > > > > > > up arbitrary and > > > > > > confusing pretty quickly. > > > ImpreciseTransformer also > > > > > > would probably make the > > > > > > logic for determining the conversion path > > > simpler. > > > > > > > > > > > > In terms of using different paths for > > > different > > > > > > source and destination > > > > > > combos, I think perhaps the best solution > in > > > such a > > > > > > case would be to just > > > > > > make a bunch of individual > AssemblerCopiers > > > with > > > > > > individual paths, and then > > > > > > add them all together using the > > > > > > SimpleDelegatingTransformer. > > > > > > > > > > > > Matt > > > > > > > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > You have a point, though I guess my aim > in > > > > > > avoiding > > > > > > > such a thing was that--usually--the path > is > > > simple > > > > > > > enough to determine given source and > dest > > > classes. > > > > > > > Secondly, you might use a different path > > > depending > > > > > > on > > > > > > > available source/dest combos, so the > > > configuration > > > > > > > might be a little more complex. :| As > for > > > where > > > > > > > converters with awareness of "precision" > > > might be > > > > > > > useful, I can't say that I know of > another > > > context > > > > > > > right now, but at the very least I would > say > > > it > > > > > > might > > > > > > > be useful knowledge for both number and > text > > > > > > types. > > > > > > > > > > > > > > -Matt > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > <mat...@sp...> > > > > > > > wrote: > > > > > > > > > > > > > > > I agree, that does sound like it could > end > > > up > > > > > > being > > > > > > > > somewhat arbitrary. I > > > > > > > > know the original impetus for this was > > > that > > > > > > > > configuration of the > > > > > > > > ChainedTransformer could be a real > pain in > > > the > > > > > > neck. > > > > > > > > Are there other > > > > > > > > situations where the information > provided > > > by > > > > > > > > ImplicitTransformer or > > > > > > > > PrecisionTransformer might be useful? > I > > > guess > > > > > > what > > > > > > > > I'm getting at here is, > > > > > > > > what is the requirement we are trying > to > > > solve? > > > > > > > > Perhaps if we think about > > > > > > > > it in a new way a different solution > will > > > > > > present > > > > > > > > itself. > > > > > > > > > > > > > > > > Perhaps an alternative could be to > > > introduce a > > > > > > new > > > > > > > > setTransformationPath(Class[] path) > method > > > to > > > > > > the > > > > > > > > ChainedTransformer. That > > > > > > > > would make configuration a snap, even > if > > > you > > > > > > were > > > > > > > > trying to use dependency > > > > > > > > injection for the configuration. > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > More on this: what do you think > about > > > the > > > > > > concept > > > > > > > > of > > > > > > > > > something like a > PrecisionTransformer > > > that > > > > > > returns > > > > > > > > a > > > > > > > > > float precision from 0.0 to 1.0 > given a > > > > > > > > > destinationClass and a sourceClass? > > > These > > > > > > might > > > > > > > > be > > > > > > > > > somewhat arbitrary, or calculated > (like > > > with > > > > > > > > numeric > > > > > > > > > types), but they might allow a > little > > > more > > > > > > > > > informedness on the part of the > > > consumer. > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > --- Matt Benson > <gud...@ya...> > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > > > <mat...@sp...> > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > I have been thinking more about > this > > > > > > approach, > > > > > > > > and > > > > > > > > > > > it's really starting to > > > > > > > > > > > grow on me. I do have one > concern > > > though, > > > > > > can > > > > > > > > > > this > > > > > > > > > > > approach be extended to > > > > > > > > > > > Copiers? For example, a Map -> > > > Object > > > > > > copy > > > > > > > > could > > > > > > > > > > > probably be considered an > > > > > > > > > > > imprecise transformation because > the > > > Map > > > > > > may > > > > > > > > have > > > > > > > > > > > more keys than the Object > > > > > > > > > > > has properties. > > > > > > > > > > > > > > > > > > > > I thought about this as well. It > > > could be > > > > > > done; > > > > > > > > it > > > > > > > > > > might be slightly complex > calculating > > > the > > > > > > > > > > "precision" > > > > > > > > > > of a PropertyNameMatchingCopier--I > > > would > > > > > > think > > > > > > > > an > > > > > > > > > > explicitly specified PNMatchingC > would > > > be > > > > > > > > precise; > > > > > > > > > > an > > > > > > > > > > imprecise one would be one using > > > property > > > > > > name > > > > > > > > > > discovery and where the properties > of > > > the > > > > > > source > > > > > > > > are > > > > > > > > > > not all available on the > destination. > > > > > > > > There--the > > > > > > > > > > hard > > > > > > > > > > part of that one is over. :) I > will > > > work > > > > > > on > > > > > > > > > > ImpreciseConverter -> > > > ImpreciseTransformer > > > > > > > > extends > > > > > > > > > > Transformer and other semantic > changes > > > as > > > > > > time > > > > > > > > > > permits. Your ordering changes > are, I > > > > > > expect, > > > > > > > > fine > > > > > > > > > > by > > > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, I > also > > > like > > > > > > the > > > > > > > > idea > > > > > > > > > > > of cleaning up the > > > > > > > > > > > internal implementation in Morph > so > > > that > > > > > > > > ordering > > > > > > > > > > of > > > > > > > > > > > source and destination > > > > > > > > > > > classes is preserved for the > > > following > > > > > > > > reasons: > > > > > > > > > > > 1) for at least some portion of > > > users, > > > > > > setting > > > > > > > > the > > > > > > > > > > > order of source and > > > > > > > > > > > destination classes will make > sense > > > as an > > > > > > > > > > indication > > > > > > > > > > > of the transformer's > > > > > > > > > > > preferences for performing > > > transformations > > > > > > (so > > > > > > > > for > > > > > > > > > > > this class of users, > > > > > > > > > > > creating new transformers that > play > > > nicely > > > > > > > > with > > > > > > > > > > the > > > > > > > > > > > ChainedTransformerTestCase will > be > > > > > > simpler) > > > > > > > > > > > 2) I think a general change from > > > using > > > > > > > > HashSets to > > > > > > > > > > > ordered sets in Morph's > > > > > > > > > > > implementation will mean > > > transformations > > > > > > > > happen > > > > > > > > > > more > > > > > > > > > > > consistently across > > > > > > > > > > > JVMs and across time on the same > > > JVM, > > > > > > leading > > > > > > > > to a > > > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > > > > > So, what I did is I basically > went > > > through > > > > > > the > > > > > > > > > > Morph > > > > > > > > > > > codebase and replaced > > > > > > > > > > > HashSets with ordered sets > > > (preference > > > > > > order > > > > > > > > is: > > > > > > > > > > JDK > > > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > > > Commons-collections > ListOrderedSet, > > > copy > > > > > > of > > > > > > > > > > > ListOrderedSet in > > > > > > > > > > > net.sf.morph.util). I was never > > > able to > > > > > > > > modify > > > > > > > > > > the > > > > > > > > > > > ChainedTransformerTestCase so > that > > > it > > > > > > > > consistently > > > > > > > > > > > threw an error. However, > > > > > > > > > > > after working on the test case > long > > > > > > enough, > > > > > > > > > > > eventually something changed in > > > > > > > > > > > my environment so that the test > > > started to > > > > > > > > fail. > > > > > > > > > > I > > > > > > > > > > > did my change of > > > > > > > > > > > HashSets to ordered sets, and > that > > > was > > > > > > able to > > > > > > > > fix > > > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > > > > > I checked in my changes for you > to > > > take a > > > > > > look > > > > > > > > > > at... > > > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt > Benson > > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > > > Be a better friend, newshound, > and > > > > > > > > > > > > know-it-all with Yahoo! > Mobile. > > > Try it > > > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > /* > > > > > > > > > > > > - * Copyright 2004-2005, 2007 > the > > > > > > original > > > > > > > > > > author > > > > > > > > > > > or authors. > > > > > > > > > > > > + * Copyright 2004-2005, > 2007-2008 > > > the > > > > > > > > original > > > > > > > > > > > author or authors. > > > > > > > > > > > > * > > > > > > > > > > > > * Licensed under the Apache > > > License, > > > > > > > > Version > > > > > > > > > > 2.0 > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > not > > > > > > > > > > > > * use this file except in > > > compliance > > > > > > with > > > > > > > > the > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > copy of > > > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > > > */ > > > > > > > > > > > > public class > > > > > > SimpleDelegatingTransformer > > > > > > > > > > extends > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > implements > > > > > > > > > > > > - > SpecializableComposite, > > > > > > > > > > > ExplicitTransformer, > Transformer, > > > > > > > > > > > > DecoratedCopier, > > > DecoratedConverter, > > > > > > > > Cloneable { > > > > > > > > > > > > + > > > SpecializableComposite, > > > > > > > > > > > ExplicitTransformer, > Transformer, > > > > > > > > > > > > DecoratedCopier, > > > > > > > > > > > > + > > > DecoratedConverter, > > > > > > > > Cloneable, > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > > > BaseDelegatingTransformer > > > > > > > > > > > with pluggable delegate > > > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > > > private static class > > > > > > MapThreadLocal > > > > > > > > > > extends > > > > > > > > > > > ThreadLocal { > > > > > > > > > > > > protected > Object > > > > > > > > initialValue() { > > > > > > > > > > > > return > new > > > > > > HashMap(); > > > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > private Specializer > > > specializer; > > > > > > > > > > > > + private boolean > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > > > > > private transient > > > ThreadLocal > > > > > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > > > = > > > > > > > > new > > > > > > > > > > > MapThreadLocal(); > > > > > > > > > > > > private transient > > > ThreadLocal > > > > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > + */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + return > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > > > + > > > > > > > > sourceClass), > > > > > > > > > > > destinationClass, > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > > > () > > > > > > > > > > > > */ > > > > > > > > > > > > protected Class[] > > > > > > > > getSourceClassesImpl() > > > > > > > > > > > throws Exception { > > > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > > > * if no > > > suitable > > > > > > > > transformer > > > > > > > > > > > could be found > > > > > > > > > > > > */ > > > > > > > > > > > > private Transformer > > > > > > > > getTransformer(Class > > > > > > > > > > > transformerType, Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) > > > > > > throws > > > > > > > > > > > TransformationException { > > > > > > > > > > > > + Transformer > > > candidate = > > > > > > > > null; > > > > > > > > > > > > for (int i = 0; > i < > > > > > > > > > > > components.length; i++) { > > > > > > > > > > > > // if > the > > > > > > transformer > > > > > > > > is > > > > > > > > > > > the correct type > > > > > > > > > > > > > Transformer > > > > > > > > transformer = > > > > > > > > > > > (Transformer) > > > > > > > > > > > > components[i]; > > > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > > > > // > > > if the > > > > > > > > > > > transformer is capable of > > > > > > > > > > > > performing the transformation > > > > > > > > > > > > > if > > > > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > > > destinationClass, > sourceClass)) { > > > > > > > > > > > > + > > > > > > if > > > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > > > null > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > > > + > > > > > > > > > > > > destinationClass, > sourceClass)) { > > > > > > > > > > > > + > > > > > > > > > > > candidate = transformer; > > > > > > > > > > > > + > > > > > > > > > > > continue; > > > > > > > > > > > > + > > > > > > } > > > > > > > > > > > > > > > > > > if > > > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > > > > > return > > > > > > > > > > > transformer; > > > > > > > > > > > > > } > > > > > > > > > > > > } > > > > > > > > > > > > - > > > > > > > > > > > > + if > > > (candidate != > > > > > > > > null) { > > > > > > > > > > > > + > > > return > > > > > > > > > > candidate; > > > > > > > > > > > > + } > > > > > > > > > > > > } > > > > > > > > > > > > throw new > > > > > > > > > > TransformationException( > > > > > > > > > > > > "Could > not > > > find a > > > > > > > > > > > transformer that can transform > > > > > > > > > > > > objects of " > > > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > > > > > source); > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > + * Get the > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > + */ > > > > > > > > > > > > + public boolean > > > > > > > > > > > isPreferPreciseTransformers() { > > > > > > > > > > > > + return > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > + * Set the > > > > > > > > preferPreciseTransformers. > > > > > > > > > > > Default false. > > > > > > > > > > > > + * @param > > > > > > preferPreciseTransformers > > > > > > > > the > > > > > > > > > > > boolean to set > > > > > > > > > > > > + */ > > > > > > > > > > > > + public void > > > > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > > > + > > > > > > > > this.preferPreciseTransformers = > > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > } > > > > > > > > > > > > \ No newline at end of file > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > (revision 358) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > > > } > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > > + * Implementation of > > > > > > > > > > isImpreciseConversion > > > > > > > > > > > > + * @param > destinationClass > > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > > + * @return > > > > > > > > > > > > + */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + return > > > destinationClass > > > > > > == > > > > > > > > null > > > > > > > > > > && > > > > > > > > > > > sourceClass != null; > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > + * Learn whether the > > > specified > > > > > > > > > > conversion > > > > > > > > > > > yields an imprecise > > > > > > > > > > > > result. > > > > > > > > > > > > + * @param > destinationClass > > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > + */ > > > > > > > > > > > > + public final boolean > > > > > > > > > > > isImpreciseConversion(Class > > > > > > destinationClass, > > > > > > > > > > > > Class sourceClass) { > > > > > > > > > > > > + try { > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > + } catch > (Exception > > > e) { > > > > > > > > > > > > + if (e > > > instanceof > > > > > > > > > > > RuntimeException && > > > > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > > > + > > > throw > > > > > > > > > > > (RuntimeException) e; > > > > > > > > > > > > + } > > > > > > > > > > > > + throw > new > > > > > > > > > > > TransformationException("Could > not > > > > > > > > > > > > determine if conversion of " > > > > > > > > > > > > + > > > > > > + > > > > > > > > > > > sourceClass + " to " + > > > > > > > > > > > > destinationClass > > > > > > > > > > > > + > > > > > > + " > > > > > > > > > > > results in a loss of > > > > > > > > > > > > precision", e); > > > > > > > > > > > > + } > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > // property getters and > setters > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > > /* > > > > > > > > > > > > - * Copyright 2004-2005, 2007 > the > > > > > > original > > > > > > > > > > author > > > > > > > > > > > or authors. > > > > > > > > > > > > + * Copyright 2004-2005, > 2007-2008 > > > the > > > > > > > > original > > > > > > > > > > > author or authors. > > > > > > > > > > > > * > > > > > > > > > > > > * Licensed under the Apache > > > License, > > > > > > > > Version > > > > > > > > > > 2.0 > > > > > > > > > > > (the "License"); you may > > > > > > > > > > > > not > > > > > > > > > > > > * use this file except in > > > compliance > > > > > > with > > > > > > > > the > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > copy of > > > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > > > package > > > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > > > > +import java.util.Iterator; > > > > > > > > > > > > import java.util.List; > > > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > > > */ > > > > > > > > > > > > public class > ChainedTransformer > > > extends > > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > > implements > > > > > > > > > > > > - > > > DecoratedConverter, > > > > > > > > > > > DecoratedCopier, > ExplicitTransformer > > > { > > > > > > > > > > > > + > > > DecoratedConverter, > > > > > > > > > > > DecoratedCopier, > > > ExplicitTransformer, > > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > copyConverter; > > > > > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > + */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + List > > > conversionPath = > > > > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > + return > > > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > > > sourceClass, 0); > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > * Get the converter > used > > > when > > > > > > using > > > > > > > > a > > > > > > > > > > > ChainedTransformer as a > > > > > > > > > > > > Copier. > > > > > > > > > > > > * @return > > > > > > > > > > > > */ > > > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > > > throw > new > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > conversion path could not > > > > > > > > > > > > be determined"); > > > > > > > > > > > > } > > > > > > > > > > > > + > log.debug("Using > > > chained > > > > > > > > > > > conversion path " + > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > Object o = > source; > > > > > > > > > > > > for (int i = 0; > i < > > > > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > > > > o = > > > > > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > > > conversionPath.get(i), o, > locale); > > > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > > > throw > new > > > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > > conversion path could not > > > > > > > > > > > > be determined"); > > > > > > > > > > > > } > > > > > > > > > > > > + > log.debug("Using > > > chained > > > > > > > > > > > conversion path " + > > > > > > > > > > > > conversionPath); > > > > > > > > > > > > Object last = > > > > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > > > > conversionPath.get(chain.length - > > > 2), > > > > > > > > source, > > > > > > > > > > > locale); > > > > > > > > > > > > ((Copier) > > > > > > > > > > copier).copy(destination, > > > > > > > > > > > last, locale); > > > > > > > > > > > > } > > > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > > > * @return List > > > > > > > > > > > > */ > > > > > > > > > > > > protected List > > > > > > > > getConversionPath(Class > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > sourceType) { > > > > > > > > > > > > - if (sourceType > != > > > null) > > > > > > { > > > > > > > > > > > > - List > > > withoutNull > > > > > > = > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > sourceType, > > > > > > > > > > 0, > > > > > > > > > > > false); > > > > > > > > > > > > - if > > > (withoutNull > > > > > > != > > > > > > > > null) > > > > > > > > > > { > > > > > > > > > > > > - > > > return > > > > > > > > > > > withoutNull; > > > > > > > > > > > > - } > > > > > > > > > > > > - } > > > > > > > > > > > > - return > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > sourceType, > > > > > > > > 0, > > > > > > > > > > > > true); > > > > > > > > > > > > + return > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > sourceType, > > > > > > > > 0); > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > > > * @param allowNull > > > > > > > > > > > > * @return List > > > > > > > > > > > > */ > > > > > > > > > > > > - private List > > > > > > getConversionPath(Class > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > sourceType, int index, boolean > > > > > > allowNull) { > > > > > > > > > > > > + private List > > > > > > getConversionPath(Class > > > > > > > > > > > destinationType, Class > > > > > > > > > > > > sourceType, int index) { > > > > > > > > > > > > Transformer[] > chain > > > = > > > > > > > > getChain(); > > > > > > > > > > > > Transformer c = > > > > > > chain[index]; > > > > > > > > > > > > if (index + 1 > == > > > > > > > > chain.length) { > > > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > > > } > > > > > > > > > > > > return > > > null; > > > > > > > > > > > > } > > > > > > > > > > > > + List > > > possibleResult = > > > > > > null; > > > > > > > > > > > > Class[] > available = > > > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > > > for (int i = 0; > i < > > > > > > > > > > > available.length; i++) { > > > > > > > > > > > > - if > > > (available[i] > > > > > > == > > > > > > > > null > > > > > > > > > > > && !allowNull) { > > > > > > > > > > > > - > > > > > > continue; > > > > > > > > > > > > - } > > > > > > > > > > > > if > > > > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > > > available[i], sourceType)) { > > > > > > > > > > > > - > > > List > > > > > > tail = > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > available[i], > > > > > > > > > > > index + 1, allowNull); > > > > > > > > > > > > + > > > List > > > > > > tail = > > > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > > available[i], > > > > > > > > > > > index + 1); > > > > > > > > > > > > > if > > > (tail > > > > > > != > > > > > > > > null) > > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > > > available[i]); > > > > > > > > > > > > - > > > > > > > > return > > > > > > > > > > > tail; > > > > > > > > > > > > + > > > > > > if > > > > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > > > > index)) { > > > > > > > > > > > > + > > > > > > > > > > > return tail; > > > > > > > > > > > > + > > > > > > } > > > > > > > > > > > > + > > > > > > > > > > > possibleResult = tail; > > > > > > > > > > > > > } > > > > > > > > > > > > } > > > > > > > > > > > > } > > > > > > > > > > > > - return null; > > > > > > > > > > > > + return > > > possibleResult; > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > + private boolean > > > isPrecise(List > > > > > > > > > > > conversionPath, Class > sourceType, > > > > > > > > > > > > int index) { > > > > > > > > > > > > + Transformer[] > > > chain = > > > > > > > > > > getChain(); > > > > > > > > > > > > + Class > > > currentSource = > > > > > > > > > > sourceType; > > > > > > > > > > > > + int i = 0; > > > > > > > > > > > > + for (Iterator > iter > > > = > > > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > > > + Class > > > > > > currentDest = > > > > > > > > > > > (Class) iter.next(); > > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > > > + i], currentDest, > > > > > > > > > > > > + > > > > > > > > > > > currentSource)) { > > > > > > > > > > > > + > > > return > > > > > > > > false; > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > currentSource = > > > > > > > > > > > currentDest; > > > > > > > > > > > > + } > > > > > > > > > > > > + return true; > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > /** > > > > > > > > > > > > * Get the components > array > > > > > > narrowed > > > > > > > > to a > > > > > > > > > > > Transformer[]. > > > > > > > > > > > > * @return > Transformer[] > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > (revision > > > > > > > > > > > > 0) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > (revision > > > > > > > > > > > > 0) > > > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > > > +/* > > > > > > > > > > > > + * Copyright 2008 the > original > > > author > > > > > > or > > > > > > > > > > authors. > > > > > > > > > > > > + * > > > > > > > > > > > > + * Licensed under the Apache > > > License, > > > > > > > > Version > > > > > > > > > > 2.0 > > > > > > > > > > > (the "License"); you > > > > > > > > > > > > may not > > > > > > > > > > > > + * use this file except in > > > compliance > > > > > > with > > > > > > > > the > > > > > > > > > > > License. You may obtain a > > > > > > > > > > > > copy of > > > > > > > > > > > > + * the License at > > > > > > > > > > > > + * > > > > > > > > > > > > + * > > > > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > > > + * > > > > > > > > > > > > + * Unless required by > applicable > > > law or > > > > > > > > agreed > > > > > > > > > > to > > > > > > > > > > > in writing, software > > > > > > > > > > > > + * distributed under the > License > > > is > > > > > > > > distributed > > > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > > > WITHOUT > > > > > > > > > > > > + * WARRANTIES OR CONDITIONS > OF > > > ANY > > > > > > KIND, > > > > > > > > either > > > > > > > > > > > express or implied. See > > > > > > > > > > > > the > > > > > > > > > > > > + * License for the specific > > > language > > > > > > > > governing > > > > > > > > > > > permissions and > > > > > > > > > > > > limitations under > > > > > > > > > > > > + * the License. > > > > > > > > > > > > + */ > > > > > > > > > > > > +package > net.sf.morph.transform; > > > > > > > > > > > > + > > > > > > > > > > > > +/** > > > > > > > > > > > > + * Defines a converter whose > > > operation > > > > > > may > > > > > > > > > > result > > > > > > > > > > > in a loss of data > > > > > > > > > > > > precision. > > > > > > > > > > > > + * > > > > > > > > > > > > + * @author mbenson > > > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > > > + */ > > > > > > > > > > > > +public interface > > > ImpreciseConverter > > > > > > extends > > > > > > > > > > > Converter { > > > > > > > > > > > > + /** > > > > > > > > > > > > + * Learn whether the > > > specified > > > > > > > > > > conversion > > > > > > > > > > > might yield an imprecise > > > > > > > > > > > > result. > > > > > > > > > > > > + * @param > destinationClass > > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > > + * @return boolean > > > > > > > > > > > > + */ > > > > > > > > > > > > + boolean > > > > > > isImpreciseConversion(Class > > > > > > > > > > > destinationClass, Class > > > > > > > > > > > > sourceClass); > > > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > (revision 362) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > +import > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > * Converts an object to a > textual > > > > > > > > > > representation > > > > > > > > > > > by calling the object's > > > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > > > */ > > > > > > > > > > > > -public class > > > ObjectToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > +public class > > > ObjectToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter, > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > textConverter; > > > > > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > > > /** > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > destinationClass, > String.class); > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > + */ > > > > > > > > > > > > protected boolean > > > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > > > return true; > > > > > > > > > > > > } > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > (revision 361) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > > > > import > > > > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > - * Converts basic text types > into > > > > > > primtive > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > + * Converts basic text types > into > > > > > > primitive > > > > > > > > > > > numbers or {@link > > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > > * objects. > > > > > > > > > > > > * > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > (revision 363) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > +import > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > * Converts {@link > > > java.lang.Number}s > > > > > > into > > > > > > > > basic > > > > > > > > > > > text types ({@link > > > > > > > > > > > > java.lang.String}, > > > > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > > > > */ > > > > > > > > > > > > -public class > > > NumberToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > +public class > > > NumberToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > + > ImpreciseConverter > > > { > > > > > > > > > > > > > > > > > > > > > > > > private Converter > > > textConverter; > > > > > > > > > > > > private Converter > > > > > > numberConverter; > > > > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > + */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > destinationClass, > String.class); > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > * Get the number > converter > > > used > > > > > > by > > > > > > > > this > > > > > > > > > > > NumberToTextConverter. > > > > > > > > > > > > * @return Converter > > > > > > > > > > > > */ > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > (revision 360) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > +import > > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > > * Converts the basic time > types > > > ({@link > > > > > > > > > > > java.util.Date} and > > > > > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > > * @since Dec 31, 2004 > > > > > > > > > > > > */ > > > > > > > > > > > > -public class > TimeToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > > +public class > TimeToTextConverter > > > > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > + > ImpreciseConverter > > > { > > > > > > > > > > > > > > > > > > > > > > > > private DateFormat > > > dateFormat; > > > > > > > > > > > > private Converter > > > timeConverter; > > > > > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > > > > > /** > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > > destinationClass, > String.class); > > > > > > > > > > > > + } > > > > > > > > > > > > + > > > > > > > > > > > > + /** > > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > > + */ > > > > > > > > > > > > protected boolean > > > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > > > return true; > > > > > > > > > > > > } > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > (revision 357) > > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > (working copy) > > > > > > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > > +import > > > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > > import > > > net.sf.morph.util.ClassUtils; > > > > > > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > > > > > > * @since Jan 2, 2005 > > > > > > > > > > > > */ > > > > > > > > > > > > public class TextConverter > > > extends > > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > > - > > > ExplicitTransformer { > > > > > > > > > > > > + > > > ExplicitTransformer, > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > > > private static final > Class > > > > > > > > CHAR_SEQUENCE > > > > > > > > > > = > > > > > > > > > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > > > > > > ClassUtils > > > > > > > > > > > > > > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > > > > > > > > > s.add(Character.class); > > > > > > > > > > > > > s.add(char.class); > > > > > > > > > > > > s.add(null); > > > > > > > > > > > > - if > (CHAR_SEQUENCE > > > != > > > > > > null) { > > > > > > > > > > > > - > > > > > > > > s.add(CHAR_SEQUENCE); > > > > > > > > > > > > - try { > > > > > > > > > > > > - > > > > > > > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > > > > > > > > > StringBuffer.class.getConstructor(new > > > > > > > > Class[] { > > > > > > > > > > > String.class })); > > > > > > > > > > > > - } > catch > > > > > > (Exception > > > > > > > > e) { > > > > > > > > > > > > - > > > //nope > > > > > > > > > > > > - } > > > > > > > > > > > > - } > > > > > > > > > > > > + > > > s.add(CHAR_SEQUENCE); > > > > > > > > > > > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > > > > > > = > > > > > > > > > > > (Class[]) s.toArray(new > > > > > > > > > > > > Class[s.size()]); > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > > > > > > } > > > > > > > > > > > > return > new > > > > > > > > > > > Character(string.charAt(0)); > > > > > > > > > > > > } > > > > > > > > > > > > - if > > > (destinationClass == > > > > > > > > > > > String.class) { > > > > > > > > > > > > + if > > > (destinationClass == > > > > > > > > > > > String.class > > > > > > > > > > > > + > || > > > > > > > > > > > (destinationClass == > CHAR_SEQUENCE > > > && > > > > > > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > > > > > > return > > > string; > > > > > > > > > > > > } > > > > > > > > > > > > if > > > (destinationClass == > > > > > > > > > > > byte[].class) { > > > > > > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > > > > > > /** > > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > > */ > > > > > > > > > > > > + protected boolean > > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > > destinationClass, Class > > > sourceClass) { > > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > > sourceClass)) { > > > > > > > > > > > > + return > > > true; > > > > > > > > > > > > + ... [truncated message content] |
From: Matt S. <mat...@sp...> - 2008-01-31 18:51:25
|
I think we talked about this before, and the preferredTransformationType definitely has some code smell associated with it. I think this is a good workaround for now. BTW, I didn't write in my last email that I like the idea of ImpreciseTransformer and your changes look good. I did make some cosmetic changes to a couple files. I hope you are doing well, Matt S On Jan 30, 2008 12:00 PM, Matt Benson <gud...@ya...> wrote: > Matt S: At your convenience, you may want to review > the extension point I just added to > BasePropertyNameCopier to allow a subclass to override > the preferredTransformationType of a given copy > operation. Then again, you may not. ;) > > br, > Matt B > > > > ____________________________________________________________________________________ > Never miss a thing. Make Yahoo your home page. > http://www.yahoo.com/r/hs > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt S. <mat...@sp...> - 2008-01-31 18:49:03
|
Perhaps it would make sense to change ImpreciseTransformer so that it operates on objects instead of classes? That way you can give much more accurate results. For example, 3.0 (double) is completely precise converting to the integer 3, whereas 3.01 -> integer is not precise. Matt On Jan 30, 2008 10:15 AM, Matt Benson <gud...@ya...> wrote: > > --- Matt Sgarlata <mat...@sp...> > wrote: > > > To clarify, I am +0 on ImpreciseTransformer. I am > > -1 on > > PrecisionTransformer, but of course I am all ears if > > you would like me to > > change my vote on that one ;) > > Hmm, I committed what I had for ImpreciseConverter, > refactored to ImpreciseTransformer. I began to > implement ImpreciseTransformer for > PropertyNameMatchingCopier, with the idea that if > properties exist for the source object that don't > exist on the destination object, then that is > imprecise. The only problem is that Reflectors work > on objects rather than classes. So I can't tell this > info at the class level. Do you have any suggestions? > > -Matt B > > > > > > Matt > > > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > > <mat...@sp...> > > wrote: > > > > > Oh boy, it's an Apache pop quiz! If I remember > > correctly, I am +0 to > > > indicate I support the feature's addition, but I > > do not plan on actively > > > working on it myself. > > > > > > Just to remind you, I believe I have already fixed > > the issue that > > > ImpreciseTransformer is intended to address by > > ensuring order of components > > > is always maintained. However, I see no problem > > with having 2 alternative > > > solutions to the issue. > > > > > > Matt > > > > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > > <gud...@ya...> wrote: > > > > > > > Where did you end up on the ImpreciseTransformer > > idea? > > > > +1, -1, or +0? > > > > > > > > -Matt > > > > > > > > --- Matt Sgarlata > > <mat...@sp...> > > > > wrote: > > > > > > > > > I see what you mean. I prefer > > ImpreciseTransformer > > > > > to PrecisionTransformer > > > > > because of the difficulty of assigning a > > numeric > > > > > value for the degree of > > > > > precision. I think that assignment is going > > to end > > > > > up arbitrary and > > > > > confusing pretty quickly. > > ImpreciseTransformer also > > > > > would probably make the > > > > > logic for determining the conversion path > > simpler. > > > > > > > > > > In terms of using different paths for > > different > > > > > source and destination > > > > > combos, I think perhaps the best solution in > > such a > > > > > case would be to just > > > > > make a bunch of individual AssemblerCopiers > > with > > > > > individual paths, and then > > > > > add them all together using the > > > > > SimpleDelegatingTransformer. > > > > > > > > > > Matt > > > > > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > > > <gud...@ya...> wrote: > > > > > > > > > > > You have a point, though I guess my aim in > > > > > avoiding > > > > > > such a thing was that--usually--the path is > > simple > > > > > > enough to determine given source and dest > > classes. > > > > > > Secondly, you might use a different path > > depending > > > > > on > > > > > > available source/dest combos, so the > > configuration > > > > > > might be a little more complex. :| As for > > where > > > > > > converters with awareness of "precision" > > might be > > > > > > useful, I can't say that I know of another > > context > > > > > > right now, but at the very least I would say > > it > > > > > might > > > > > > be useful knowledge for both number and text > > > > > types. > > > > > > > > > > > > -Matt > > > > > > > > > > > > --- Matt Sgarlata > > > > > <mat...@sp...> > > > > > > wrote: > > > > > > > > > > > > > I agree, that does sound like it could end > > up > > > > > being > > > > > > > somewhat arbitrary. I > > > > > > > know the original impetus for this was > > that > > > > > > > configuration of the > > > > > > > ChainedTransformer could be a real pain in > > the > > > > > neck. > > > > > > > Are there other > > > > > > > situations where the information provided > > by > > > > > > > ImplicitTransformer or > > > > > > > PrecisionTransformer might be useful? I > > guess > > > > > what > > > > > > > I'm getting at here is, > > > > > > > what is the requirement we are trying to > > solve? > > > > > > > Perhaps if we think about > > > > > > > it in a new way a different solution will > > > > > present > > > > > > > itself. > > > > > > > > > > > > > > Perhaps an alternative could be to > > introduce a > > > > > new > > > > > > > setTransformationPath(Class[] path) method > > to > > > > > the > > > > > > > ChainedTransformer. That > > > > > > > would make configuration a snap, even if > > you > > > > > were > > > > > > > trying to use dependency > > > > > > > injection for the configuration. > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > More on this: what do you think about > > the > > > > > concept > > > > > > > of > > > > > > > > something like a PrecisionTransformer > > that > > > > > returns > > > > > > > a > > > > > > > > float precision from 0.0 to 1.0 given a > > > > > > > > destinationClass and a sourceClass? > > These > > > > > might > > > > > > > be > > > > > > > > somewhat arbitrary, or calculated (like > > with > > > > > > > numeric > > > > > > > > types), but they might allow a little > > more > > > > > > > > informedness on the part of the > > consumer. > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > --- Matt Benson <gud...@ya...> > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > > <mat...@sp...> > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > I have been thinking more about this > > > > > approach, > > > > > > > and > > > > > > > > > > it's really starting to > > > > > > > > > > grow on me. I do have one concern > > though, > > > > > can > > > > > > > > > this > > > > > > > > > > approach be extended to > > > > > > > > > > Copiers? For example, a Map -> > > Object > > > > > copy > > > > > > > could > > > > > > > > > > probably be considered an > > > > > > > > > > imprecise transformation because the > > Map > > > > > may > > > > > > > have > > > > > > > > > > more keys than the Object > > > > > > > > > > has properties. > > > > > > > > > > > > > > > > > > I thought about this as well. It > > could be > > > > > done; > > > > > > > it > > > > > > > > > might be slightly complex calculating > > the > > > > > > > > > "precision" > > > > > > > > > of a PropertyNameMatchingCopier--I > > would > > > > > think > > > > > > > an > > > > > > > > > explicitly specified PNMatchingC would > > be > > > > > > > precise; > > > > > > > > > an > > > > > > > > > imprecise one would be one using > > property > > > > > name > > > > > > > > > discovery and where the properties of > > the > > > > > source > > > > > > > are > > > > > > > > > not all available on the destination. > > > > > > > There--the > > > > > > > > > hard > > > > > > > > > part of that one is over. :) I will > > work > > > > > on > > > > > > > > > ImpreciseConverter -> > > ImpreciseTransformer > > > > > > > extends > > > > > > > > > Transformer and other semantic changes > > as > > > > > time > > > > > > > > > permits. Your ordering changes are, I > > > > > expect, > > > > > > > fine > > > > > > > > > by > > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, I also > > like > > > > > the > > > > > > > idea > > > > > > > > > > of cleaning up the > > > > > > > > > > internal implementation in Morph so > > that > > > > > > > ordering > > > > > > > > > of > > > > > > > > > > source and destination > > > > > > > > > > classes is preserved for the > > following > > > > > > > reasons: > > > > > > > > > > 1) for at least some portion of > > users, > > > > > setting > > > > > > > the > > > > > > > > > > order of source and > > > > > > > > > > destination classes will make sense > > as an > > > > > > > > > indication > > > > > > > > > > of the transformer's > > > > > > > > > > preferences for performing > > transformations > > > > > (so > > > > > > > for > > > > > > > > > > this class of users, > > > > > > > > > > creating new transformers that play > > nicely > > > > > > > with > > > > > > > > > the > > > > > > > > > > ChainedTransformerTestCase will be > > > > > simpler) > > > > > > > > > > 2) I think a general change from > > using > > > > > > > HashSets to > > > > > > > > > > ordered sets in Morph's > > > > > > > > > > implementation will mean > > transformations > > > > > > > happen > > > > > > > > > more > > > > > > > > > > consistently across > > > > > > > > > > JVMs and across time on the same > > JVM, > > > > > leading > > > > > > > to a > > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > > > So, what I did is I basically went > > through > > > > > the > > > > > > > > > Morph > > > > > > > > > > codebase and replaced > > > > > > > > > > HashSets with ordered sets > > (preference > > > > > order > > > > > > > is: > > > > > > > > > JDK > > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > > Commons-collections ListOrderedSet, > > copy > > > > > of > > > > > > > > > > ListOrderedSet in > > > > > > > > > > net.sf.morph.util). I was never > > able to > > > > > > > modify > > > > > > > > > the > > > > > > > > > > ChainedTransformerTestCase so that > > it > > > > > > > consistently > > > > > > > > > > threw an error. However, > > > > > > > > > > after working on the test case long > > > > > enough, > > > > > > > > > > eventually something changed in > > > > > > > > > > my environment so that the test > > started to > > > > > > > fail. > > > > > > > > > I > > > > > > > > > > did my change of > > > > > > > > > > HashSets to ordered sets, and that > > was > > > > > able to > > > > > > > fix > > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > > > I checked in my changes for you to > > take a > > > > > look > > > > > > > > > at... > > > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > > Be a better friend, newshound, and > > > > > > > > > > > know-it-all with Yahoo! Mobile. > > Try it > > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > (revision 357) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > /* > > > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > > > original > > > > > > > > > author > > > > > > > > > > or authors. > > > > > > > > > > > + * Copyright 2004-2005, 2007-2008 > > the > > > > > > > original > > > > > > > > > > author or authors. > > > > > > > > > > > * > > > > > > > > > > > * Licensed under the Apache > > License, > > > > > > > Version > > > > > > > > > 2.0 > > > > > > > > > > (the "License"); you may > > > > > > > > > > > not > > > > > > > > > > > * use this file except in > > compliance > > > > > with > > > > > > > the > > > > > > > > > > License. You may obtain a > > > > > > > > > > > copy of > > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > > */ > > > > > > > > > > > public class > > > > > SimpleDelegatingTransformer > > > > > > > > > extends > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > implements > > > > > > > > > > > - SpecializableComposite, > > > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > > > DecoratedCopier, > > DecoratedConverter, > > > > > > > Cloneable { > > > > > > > > > > > + > > SpecializableComposite, > > > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > > > DecoratedCopier, > > > > > > > > > > > + > > DecoratedConverter, > > > > > > > Cloneable, > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > > BaseDelegatingTransformer > > > > > > > > > > with pluggable delegate > > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > > private static class > > > > > MapThreadLocal > > > > > > > > > extends > > > > > > > > > > ThreadLocal { > > > > > > > > > > > protected Object > > > > > > > initialValue() { > > > > > > > > > > > return new > > > > > HashMap(); > > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > private Specializer > > specializer; > > > > > > > > > > > + private boolean > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > > > private transient > > ThreadLocal > > > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > > = > > > > > > > new > > > > > > > > > > MapThreadLocal(); > > > > > > > > > > > private transient > > ThreadLocal > > > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > > + > > > > > > > sourceClass), > > > > > > > > > > destinationClass, > > > > > > > > > > > sourceClass); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > > () > > > > > > > > > > > */ > > > > > > > > > > > protected Class[] > > > > > > > getSourceClassesImpl() > > > > > > > > > > throws Exception { > > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > > * if no > > suitable > > > > > > > transformer > > > > > > > > > > could be found > > > > > > > > > > > */ > > > > > > > > > > > private Transformer > > > > > > > getTransformer(Class > > > > > > > > > > transformerType, Class > > > > > > > > > > > destinationClass, Class > > sourceClass) > > > > > throws > > > > > > > > > > TransformationException { > > > > > > > > > > > + Transformer > > candidate = > > > > > > > null; > > > > > > > > > > > for (int i = 0; i < > > > > > > > > > > components.length; i++) { > > > > > > > > > > > // if the > > > > > transformer > > > > > > > is > > > > > > > > > > the correct type > > > > > > > > > > > Transformer > > > > > > > transformer = > > > > > > > > > > (Transformer) > > > > > > > > > > > components[i]; > > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > > // > > if the > > > > > > > > > > transformer is capable of > > > > > > > > > > > performing the transformation > > > > > > > > > > > if > > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > > > + > > > > > if > > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > > null > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > > + > > > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > > > + > > > > > > > > > > candidate = transformer; > > > > > > > > > > > + > > > > > > > > > > continue; > > > > > > > > > > > + > > > > > } > > > > > > > > > > > > > > > > if > > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > > > return > > > > > > > > > > transformer; > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > - > > > > > > > > > > > + if > > (candidate != > > > > > > > null) { > > > > > > > > > > > + > > return > > > > > > > > > candidate; > > > > > > > > > > > + } > > > > > > > > > > > } > > > > > > > > > > > throw new > > > > > > > > > TransformationException( > > > > > > > > > > > "Could not > > find a > > > > > > > > > > transformer that can transform > > > > > > > > > > > objects of " > > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > > > source); > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > + * Get the > > > > > > > preferPreciseTransformers. > > > > > > > > > > > + * @return boolean > > > > > > > > > > > + */ > > > > > > > > > > > + public boolean > > > > > > > > > > isPreferPreciseTransformers() { > > > > > > > > > > > + return > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * Set the > > > > > > > preferPreciseTransformers. > > > > > > > > > > Default false. > > > > > > > > > > > + * @param > > > > > preferPreciseTransformers > > > > > > > the > > > > > > > > > > boolean to set > > > > > > > > > > > + */ > > > > > > > > > > > + public void > > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > > + > > > > > > > this.preferPreciseTransformers = > > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > } > > > > > > > > > > > \ No newline at end of file > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > (revision 358) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > > + * Implementation of > > > > > > > > > isImpreciseConversion > > > > > > > > > > > + * @param destinationClass > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > + * @return > > > > > > > > > > > + */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > destinationClass > > > > > == > > > > > > > null > > > > > > > > > && > > > > > > > > > > sourceClass != null; > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * Learn whether the > > specified > > > > > > > > > conversion > > > > > > > > > > yields an imprecise > > > > > > > > > > > result. > > > > > > > > > > > + * @param destinationClass > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > + * @return boolean > > > > > > > > > > > + */ > > > > > > > > > > > + public final boolean > > > > > > > > > > isImpreciseConversion(Class > > > > > destinationClass, > > > > > > > > > > > Class sourceClass) { > > > > > > > > > > > + try { > > > > > > > > > > > + return > > > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > sourceClass); > > > > > > > > > > > + } catch (Exception > > e) { > > > > > > > > > > > + if (e > > instanceof > > > > > > > > > > RuntimeException && > > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > > + > > throw > > > > > > > > > > (RuntimeException) e; > > > > > > > > > > > + } > > > > > > > > > > > + throw new > > > > > > > > > > TransformationException("Could not > > > > > > > > > > > determine if conversion of " > > > > > > > > > > > + > > > > > + > > > > > > > > > > sourceClass + " to " + > > > > > > > > > > > destinationClass > > > > > > > > > > > + > > > > > + " > > > > > > > > > > results in a loss of > > > > > > > > > > > precision", e); > > > > > > > > > > > + } > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > // property getters and setters > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > (revision 357) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > > /* > > > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > > > original > > > > > > > > > author > > > > > > > > > > or authors. > > > > > > > > > > > + * Copyright 2004-2005, 2007-2008 > > the > > > > > > > original > > > > > > > > > > author or authors. > > > > > > > > > > > * > > > > > > > > > > > * Licensed under the Apache > > License, > > > > > > > Version > > > > > > > > > 2.0 > > > > > > > > > > (the "License"); you may > > > > > > > > > > > not > > > > > > > > > > > * use this file except in > > compliance > > > > > with > > > > > > > the > > > > > > > > > > License. You may obtain a > > > > > > > > > > > copy of > > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > > package > > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > > > +import java.util.Iterator; > > > > > > > > > > > import java.util.List; > > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > > */ > > > > > > > > > > > public class ChainedTransformer > > extends > > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > > implements > > > > > > > > > > > - > > DecoratedConverter, > > > > > > > > > > DecoratedCopier, ExplicitTransformer > > { > > > > > > > > > > > + > > DecoratedConverter, > > > > > > > > > > DecoratedCopier, > > ExplicitTransformer, > > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > private Converter > > copyConverter; > > > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + List > > conversionPath = > > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > > sourceClass); > > > > > > > > > > > + return > > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > > sourceClass, 0); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > * Get the converter used > > when > > > > > using > > > > > > > a > > > > > > > > > > ChainedTransformer as a > > > > > > > > > > > Copier. > > > > > > > > > > > * @return > > > > > > > > > > > */ > > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > > throw new > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > conversion path could not > > > > > > > > > > > be determined"); > > > > > > > > > > > } > > > > > > > > > > > + log.debug("Using > > chained > > > > > > > > > > conversion path " + > > > > > > > > > > > conversionPath); > > > > > > > > > > > Object o = source; > > > > > > > > > > > for (int i = 0; i < > > > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > > > o = > > > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > > conversionPath.get(i), o, locale); > > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > > throw new > > > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > > > "Chained > > > > > > > > > > conversion path could not > > > > > > > > > > > be determined"); > > > > > > > > > > > } > > > > > > > > > > > + log.debug("Using > > chained > > > > > > > > > > conversion path " + > > > > > > > > > > > conversionPath); > > > > > > > > > > > Object last = > > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > > conversionPath.get(chain.length - > > 2), > > > > > > > source, > > > > > > > > > > locale); > > > > > > > > > > > ((Copier) > > > > > > > > > copier).copy(destination, > > > > > > > > > > last, locale); > > > > > > > > > > > } > > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > > * @return List > > > > > > > > > > > */ > > > > > > > > > > > protected List > > > > > > > getConversionPath(Class > > > > > > > > > > destinationType, Class > > > > > > > > > > > sourceType) { > > > > > > > > > > > - if (sourceType != > > null) > > > > > { > > > > > > > > > > > - List > > withoutNull > > > > > = > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > sourceType, > > > > > > > > > 0, > > > > > > > > > > false); > > > > > > > > > > > - if > > (withoutNull > > > > > != > > > > > > > null) > > > > > > > > > { > > > > > > > > > > > - > > return > > > > > > > > > > withoutNull; > > > > > > > > > > > - } > > > > > > > > > > > - } > > > > > > > > > > > - return > > > > > > > > > > getConversionPath(destinationType, > > > > > sourceType, > > > > > > > 0, > > > > > > > > > > > true); > > > > > > > > > > > + return > > > > > > > > > > getConversionPath(destinationType, > > > > > sourceType, > > > > > > > 0); > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > > * @param allowNull > > > > > > > > > > > * @return List > > > > > > > > > > > */ > > > > > > > > > > > - private List > > > > > getConversionPath(Class > > > > > > > > > > destinationType, Class > > > > > > > > > > > sourceType, int index, boolean > > > > > allowNull) { > > > > > > > > > > > + private List > > > > > getConversionPath(Class > > > > > > > > > > destinationType, Class > > > > > > > > > > > sourceType, int index) { > > > > > > > > > > > Transformer[] chain > > = > > > > > > > getChain(); > > > > > > > > > > > Transformer c = > > > > > chain[index]; > > > > > > > > > > > if (index + 1 == > > > > > > > chain.length) { > > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > > } > > > > > > > > > > > return > > null; > > > > > > > > > > > } > > > > > > > > > > > + List > > possibleResult = > > > > > null; > > > > > > > > > > > Class[] available = > > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > > for (int i = 0; i < > > > > > > > > > > available.length; i++) { > > > > > > > > > > > - if > > (available[i] > > > > > == > > > > > > > null > > > > > > > > > > && !allowNull) { > > > > > > > > > > > - > > > > > continue; > > > > > > > > > > > - } > > > > > > > > > > > if > > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > > available[i], sourceType)) { > > > > > > > > > > > - > > List > > > > > tail = > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > available[i], > > > > > > > > > > index + 1, allowNull); > > > > > > > > > > > + > > List > > > > > tail = > > > > > > > > > > > getConversionPath(destinationType, > > > > > > > available[i], > > > > > > > > > > index + 1); > > > > > > > > > > > if > > (tail > > > > > != > > > > > > > null) > > > > > > > > > { > > > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > > available[i]); > > > > > > > > > > > - > > > > > > > return > > > > > > > > > > tail; > > > > > > > > > > > + > > > > > if > > > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > > > index)) { > > > > > > > > > > > + > > > > > > > > > > return tail; > > > > > > > > > > > + > > > > > } > > > > > > > > > > > + > > > > > > > > > > possibleResult = tail; > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > } > > > > > > > > > > > - return null; > > > > > > > > > > > + return > > possibleResult; > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > + private boolean > > isPrecise(List > > > > > > > > > > conversionPath, Class sourceType, > > > > > > > > > > > int index) { > > > > > > > > > > > + Transformer[] > > chain = > > > > > > > > > getChain(); > > > > > > > > > > > + Class > > currentSource = > > > > > > > > > sourceType; > > > > > > > > > > > + int i = 0; > > > > > > > > > > > + for (Iterator iter > > = > > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > > + Class > > > > > currentDest = > > > > > > > > > > (Class) iter.next(); > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > > + i], currentDest, > > > > > > > > > > > + > > > > > > > > > > currentSource)) { > > > > > > > > > > > + > > return > > > > > > > false; > > > > > > > > > > > + } > > > > > > > > > > > + > > currentSource = > > > > > > > > > > currentDest; > > > > > > > > > > > + } > > > > > > > > > > > + return true; > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > /** > > > > > > > > > > > * Get the components array > > > > > narrowed > > > > > > > to a > > > > > > > > > > Transformer[]. > > > > > > > > > > > * @return Transformer[] > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > (revision > > > > > > > > > > > 0) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > (revision > > > > > > > > > > > 0) > > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > > +/* > > > > > > > > > > > + * Copyright 2008 the original > > author > > > > > or > > > > > > > > > authors. > > > > > > > > > > > + * > > > > > > > > > > > + * Licensed under the Apache > > License, > > > > > > > Version > > > > > > > > > 2.0 > > > > > > > > > > (the "License"); you > > > > > > > > > > > may not > > > > > > > > > > > + * use this file except in > > compliance > > > > > with > > > > > > > the > > > > > > > > > > License. You may obtain a > > > > > > > > > > > copy of > > > > > > > > > > > + * the License at > > > > > > > > > > > + * > > > > > > > > > > > + * > > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > > + * > > > > > > > > > > > + * Unless required by applicable > > law or > > > > > > > agreed > > > > > > > > > to > > > > > > > > > > in writing, software > > > > > > > > > > > + * distributed under the License > > is > > > > > > > distributed > > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > > WITHOUT > > > > > > > > > > > + * WARRANTIES OR CONDITIONS OF > > ANY > > > > > KIND, > > > > > > > either > > > > > > > > > > express or implied. See > > > > > > > > > > > the > > > > > > > > > > > + * License for the specific > > language > > > > > > > governing > > > > > > > > > > permissions and > > > > > > > > > > > limitations under > > > > > > > > > > > + * the License. > > > > > > > > > > > + */ > > > > > > > > > > > +package net.sf.morph.transform; > > > > > > > > > > > + > > > > > > > > > > > +/** > > > > > > > > > > > + * Defines a converter whose > > operation > > > > > may > > > > > > > > > result > > > > > > > > > > in a loss of data > > > > > > > > > > > precision. > > > > > > > > > > > + * > > > > > > > > > > > + * @author mbenson > > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > > + */ > > > > > > > > > > > +public interface > > ImpreciseConverter > > > > > extends > > > > > > > > > > Converter { > > > > > > > > > > > + /** > > > > > > > > > > > + * Learn whether the > > specified > > > > > > > > > conversion > > > > > > > > > > might yield an imprecise > > > > > > > > > > > result. > > > > > > > > > > > + * @param destinationClass > > > > > > > > > > > + * @param sourceClass > > > > > > > > > > > + * @return boolean > > > > > > > > > > > + */ > > > > > > > > > > > + boolean > > > > > isImpreciseConversion(Class > > > > > > > > > > destinationClass, Class > > > > > > > > > > > sourceClass); > > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > (revision 362) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > +import > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * Converts an object to a textual > > > > > > > > > representation > > > > > > > > > > by calling the object's > > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > > */ > > > > > > > > > > > -public class > > ObjectToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > +public class > > ObjectToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter, > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > private Converter > > textConverter; > > > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > > /** > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > protected boolean > > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > > return true; > > > > > > > > > > > } > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > (revision 361) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > > > import > > > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > - * Converts basic text types into > > > > > primtive > > > > > > > > > > numbers or {@link > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > + * Converts basic text types into > > > > > primitive > > > > > > > > > > numbers or {@link > > > > > > > > > > > java.lang.Number} > > > > > > > > > > > * objects. > > > > > > > > > > > * > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > (revision 363) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > +import > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * Converts {@link > > java.lang.Number}s > > > > > into > > > > > > > basic > > > > > > > > > > text types ({@link > > > > > > > > > > > java.lang.String}, > > > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > > > */ > > > > > > > > > > > -public class > > NumberToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > +public class > > NumberToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > + ImpreciseConverter > > { > > > > > > > > > > > > > > > > > > > > > > private Converter > > textConverter; > > > > > > > > > > > private Converter > > > > > numberConverter; > > > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > * Get the number converter > > used > > > > > by > > > > > > > this > > > > > > > > > > NumberToTextConverter. > > > > > > > > > > > * @return Converter > > > > > > > > > > > */ > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > (revision 360) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > +import > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * Converts the basic time types > > ({@link > > > > > > > > > > java.util.Date} and > > > > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > * @since Dec 31, 2004 > > > > > > > > > > > */ > > > > > > > > > > > -public class TimeToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > +public class TimeToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > + ImpreciseConverter > > { > > > > > > > > > > > > > > > > > > > > > > private DateFormat > > dateFormat; > > > > > > > > > > > private Converter > > timeConverter; > > > > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > > > > /** > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > protected boolean > > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > > return true; > > > > > > > > > > > } > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > (revision 357) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > import > > net.sf.morph.util.ClassUtils; > > > > > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > > > > > * @since Jan 2, 2005 > > > > > > > > > > > */ > > > > > > > > > > > public class TextConverter > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter, > > > > > > > > > > > - > > ExplicitTransformer { > > > > > > > > > > > + > > ExplicitTransformer, > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > > > private static final Class > > > > > > > CHAR_SEQUENCE > > > > > > > > > = > > > > > > > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > > > > > ClassUtils > > > > > > > > > > > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > > > > > > > s.add(Character.class); > > > > > > > > > > > s.add(char.class); > > > > > > > > > > > s.add(null); > > > > > > > > > > > - if (CHAR_SEQUENCE > > != > > > > > null) { > > > > > > > > > > > - > > > > > > > s.add(CHAR_SEQUENCE); > > > > > > > > > > > - try { > > > > > > > > > > > - > > > > > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > > > > > > > StringBuffer.class.getConstructor(new > > > > > > > Class[] { > > > > > > > > > > String.class })); > > > > > > > > > > > - } catch > > > > > (Exception > > > > > > > e) { > > > > > > > > > > > - > > //nope > > > > > > > > > > > - } > > > > > > > > > > > - } > > > > > > > > > > > + > > s.add(CHAR_SEQUENCE); > > > > > > > > > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > > > > > = > > > > > > > > > > (Class[]) s.toArray(new > > > > > > > > > > > Class[s.size()]); > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > > > > > } > > > > > > > > > > > return new > > > > > > > > > > Character(string.charAt(0)); > > > > > > > > > > > } > > > > > > > > > > > - if > > (destinationClass == > > > > > > > > > > String.class) { > > > > > > > > > > > + if > > (destinationClass == > > > > > > > > > > String.class > > > > > > > > > > > + || > > > > > > > > > > (destinationClass == CHAR_SEQUENCE > > && > > > > > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > > > > > return > > string; > > > > > > > > > > > } > > > > > > > > > > > if > > (destinationClass == > > > > > > > > > > byte[].class) { > > > > > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > > > > > /** > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > > > sourceClass)) { > > > > > > > > > > > + return > > true; > > > > > > > > > > > + } > > > > > > > > > > > + return > > > > > > > isChar(destinationClass) > > > > > > > > > && > > > > > > > > > > !isChar(sourceClass); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > protected boolean > > > > > > > > > > isAutomaticallyHandlingNulls() { > > > > > > > > > > > return > > !isEmptyNull(); > > > > > > > > > > > } > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > (revision 362) > > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > (working copy) > > > > > > > > > > > @@ -20,8 +20,10 @@ > > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > > import > > > > > net.sf.morph.transform.Converter; > > > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > > +import > > > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > > +import > > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * Converts boolean values to text > > > > > values. > > > > > > > > > > Subclasses can build in > > > > > > > > > > > support for > > > > > > > > > > > @@ -32,10 +34,10 @@ > > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > > * @since Jan 9, 2005 > > > > > > > > > > > */ > > > > > > > > > > > -public class > > BooleanToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter { > > > > > > > > > > > - > > > > > > > > > > > +public class > > BooleanToTextConverter > > > > > extends > > > > > > > > > > BaseTransformer implements > > > > > > > > > > > DecoratedConverter, > > ImpreciseConverter { > > > > > > > > > > > + > > > > > > > > > > > private static final > > Class[] > > > > > > > SOURCE_TYPES > > > > > > > > > = > > > > > > > > > > { Boolean.class, > > > > > > > > > > > boolean.class }; > > > > > > > > > > > - > > > > > > > > > > > + > > > > > > > > > > > private Converter > > textConverter; > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > @@ -93,9 +95,16 @@ > > > > > > > > > > > /** > > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > > */ > > > > > > > > > > > + protected boolean > > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > > destinationClass, Class > > sourceClass) { > > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > > + } > > > > > > > > > > > + > > > > > > > > > > > + /** > > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > > + */ > > > > > > > > > > > protected boolean > > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > > return true; > > > > > > > > > > > - } > > > > > > > > > > > + } > > > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > > * Get the text converter > > used by > > > > > > > this > > > > > > > > > > BaseToPrettyTextConverter. > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > >... [truncated message content] |
From: Matt B. <gud...@ya...> - 2008-01-30 17:00:53
|
Matt S: At your convenience, you may want to review the extension point I just added to BasePropertyNameCopier to allow a subclass to override the preferredTransformationType of a given copy operation. Then again, you may not. ;) br, Matt B ____________________________________________________________________________________ Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs |
From: Matt B. <gud...@ya...> - 2008-01-30 15:15:24
|
--- Matt Sgarlata <mat...@sp...> wrote: > To clarify, I am +0 on ImpreciseTransformer. I am > -1 on > PrecisionTransformer, but of course I am all ears if > you would like me to > change my vote on that one ;) Hmm, I committed what I had for ImpreciseConverter, refactored to ImpreciseTransformer. I began to implement ImpreciseTransformer for PropertyNameMatchingCopier, with the idea that if properties exist for the source object that don't exist on the destination object, then that is imprecise. The only problem is that Reflectors work on objects rather than classes. So I can't tell this info at the class level. Do you have any suggestions? -Matt B > > Matt > > On Jan 25, 2008 4:41 PM, Matt Sgarlata > <mat...@sp...> > wrote: > > > Oh boy, it's an Apache pop quiz! If I remember > correctly, I am +0 to > > indicate I support the feature's addition, but I > do not plan on actively > > working on it myself. > > > > Just to remind you, I believe I have already fixed > the issue that > > ImpreciseTransformer is intended to address by > ensuring order of components > > is always maintained. However, I see no problem > with having 2 alternative > > solutions to the issue. > > > > Matt > > > > > > On Jan 25, 2008 2:59 PM, Matt Benson > <gud...@ya...> wrote: > > > > > Where did you end up on the ImpreciseTransformer > idea? > > > +1, -1, or +0? > > > > > > -Matt > > > > > > --- Matt Sgarlata > <mat...@sp...> > > > wrote: > > > > > > > I see what you mean. I prefer > ImpreciseTransformer > > > > to PrecisionTransformer > > > > because of the difficulty of assigning a > numeric > > > > value for the degree of > > > > precision. I think that assignment is going > to end > > > > up arbitrary and > > > > confusing pretty quickly. > ImpreciseTransformer also > > > > would probably make the > > > > logic for determining the conversion path > simpler. > > > > > > > > In terms of using different paths for > different > > > > source and destination > > > > combos, I think perhaps the best solution in > such a > > > > case would be to just > > > > make a bunch of individual AssemblerCopiers > with > > > > individual paths, and then > > > > add them all together using the > > > > SimpleDelegatingTransformer. > > > > > > > > Matt > > > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > You have a point, though I guess my aim in > > > > avoiding > > > > > such a thing was that--usually--the path is > simple > > > > > enough to determine given source and dest > classes. > > > > > Secondly, you might use a different path > depending > > > > on > > > > > available source/dest combos, so the > configuration > > > > > might be a little more complex. :| As for > where > > > > > converters with awareness of "precision" > might be > > > > > useful, I can't say that I know of another > context > > > > > right now, but at the very least I would say > it > > > > might > > > > > be useful knowledge for both number and text > > > > types. > > > > > > > > > > -Matt > > > > > > > > > > --- Matt Sgarlata > > > > <mat...@sp...> > > > > > wrote: > > > > > > > > > > > I agree, that does sound like it could end > up > > > > being > > > > > > somewhat arbitrary. I > > > > > > know the original impetus for this was > that > > > > > > configuration of the > > > > > > ChainedTransformer could be a real pain in > the > > > > neck. > > > > > > Are there other > > > > > > situations where the information provided > by > > > > > > ImplicitTransformer or > > > > > > PrecisionTransformer might be useful? I > guess > > > > what > > > > > > I'm getting at here is, > > > > > > what is the requirement we are trying to > solve? > > > > > > Perhaps if we think about > > > > > > it in a new way a different solution will > > > > present > > > > > > itself. > > > > > > > > > > > > Perhaps an alternative could be to > introduce a > > > > new > > > > > > setTransformationPath(Class[] path) method > to > > > > the > > > > > > ChainedTransformer. That > > > > > > would make configuration a snap, even if > you > > > > were > > > > > > trying to use dependency > > > > > > injection for the configuration. > > > > > > > > > > > > Matt S > > > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > More on this: what do you think about > the > > > > concept > > > > > > of > > > > > > > something like a PrecisionTransformer > that > > > > returns > > > > > > a > > > > > > > float precision from 0.0 to 1.0 given a > > > > > > > destinationClass and a sourceClass? > These > > > > might > > > > > > be > > > > > > > somewhat arbitrary, or calculated (like > with > > > > > > numeric > > > > > > > types), but they might allow a little > more > > > > > > > informedness on the part of the > consumer. > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > --- Matt Benson <gud...@ya...> > wrote: > > > > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > > <mat...@sp...> > > > > > > > > wrote: > > > > > > > > > > > > > > > > > I have been thinking more about this > > > > approach, > > > > > > and > > > > > > > > > it's really starting to > > > > > > > > > grow on me. I do have one concern > though, > > > > can > > > > > > > > this > > > > > > > > > approach be extended to > > > > > > > > > Copiers? For example, a Map -> > Object > > > > copy > > > > > > could > > > > > > > > > probably be considered an > > > > > > > > > imprecise transformation because the > Map > > > > may > > > > > > have > > > > > > > > > more keys than the Object > > > > > > > > > has properties. > > > > > > > > > > > > > > > > I thought about this as well. It > could be > > > > done; > > > > > > it > > > > > > > > might be slightly complex calculating > the > > > > > > > > "precision" > > > > > > > > of a PropertyNameMatchingCopier--I > would > > > > think > > > > > > an > > > > > > > > explicitly specified PNMatchingC would > be > > > > > > precise; > > > > > > > > an > > > > > > > > imprecise one would be one using > property > > > > name > > > > > > > > discovery and where the properties of > the > > > > source > > > > > > are > > > > > > > > not all available on the destination. > > > > > > There--the > > > > > > > > hard > > > > > > > > part of that one is over. :) I will > work > > > > on > > > > > > > > ImpreciseConverter -> > ImpreciseTransformer > > > > > > extends > > > > > > > > Transformer and other semantic changes > as > > > > time > > > > > > > > permits. Your ordering changes are, I > > > > expect, > > > > > > fine > > > > > > > > by > > > > > > > > me as well. :) > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, I also > like > > > > the > > > > > > idea > > > > > > > > > of cleaning up the > > > > > > > > > internal implementation in Morph so > that > > > > > > ordering > > > > > > > > of > > > > > > > > > source and destination > > > > > > > > > classes is preserved for the > following > > > > > > reasons: > > > > > > > > > 1) for at least some portion of > users, > > > > setting > > > > > > the > > > > > > > > > order of source and > > > > > > > > > destination classes will make sense > as an > > > > > > > > indication > > > > > > > > > of the transformer's > > > > > > > > > preferences for performing > transformations > > > > (so > > > > > > for > > > > > > > > > this class of users, > > > > > > > > > creating new transformers that play > nicely > > > > > > with > > > > > > > > the > > > > > > > > > ChainedTransformerTestCase will be > > > > simpler) > > > > > > > > > 2) I think a general change from > using > > > > > > HashSets to > > > > > > > > > ordered sets in Morph's > > > > > > > > > implementation will mean > transformations > > > > > > happen > > > > > > > > more > > > > > > > > > consistently across > > > > > > > > > JVMs and across time on the same > JVM, > > > > leading > > > > > > to a > > > > > > > > > more stable platform > > > > > > > > > > > > > > > > > > So, what I did is I basically went > through > > > > the > > > > > > > > Morph > > > > > > > > > codebase and replaced > > > > > > > > > HashSets with ordered sets > (preference > > > > order > > > > > > is: > > > > > > > > JDK > > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > > Commons-collections ListOrderedSet, > copy > > > > of > > > > > > > > > ListOrderedSet in > > > > > > > > > net.sf.morph.util). I was never > able to > > > > > > modify > > > > > > > > the > > > > > > > > > ChainedTransformerTestCase so that > it > > > > > > consistently > > > > > > > > > threw an error. However, > > > > > > > > > after working on the test case long > > > > enough, > > > > > > > > > eventually something changed in > > > > > > > > > my environment so that the test > started to > > > > > > fail. > > > > > > > > I > > > > > > > > > did my change of > > > > > > > > > HashSets to ordered sets, and that > was > > > > able to > > > > > > fix > > > > > > > > > the broken test. > > > > > > > > > > > > > > > > > > I checked in my changes for you to > take a > > > > look > > > > > > > > at... > > > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > > Be a better friend, newshound, and > > > > > > > > > > know-it-all with Yahoo! Mobile. > Try it > > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > (revision 357) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > /* > > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > > original > > > > > > > > author > > > > > > > > > or authors. > > > > > > > > > > + * Copyright 2004-2005, 2007-2008 > the > > > > > > original > > > > > > > > > author or authors. > > > > > > > > > > * > > > > > > > > > > * Licensed under the Apache > License, > > > > > > Version > > > > > > > > 2.0 > > > > > > > > > (the "License"); you may > > > > > > > > > > not > > > > > > > > > > * use this file except in > compliance > > > > with > > > > > > the > > > > > > > > > License. You may obtain a > > > > > > > > > > copy of > > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > import > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > > */ > > > > > > > > > > public class > > > > SimpleDelegatingTransformer > > > > > > > > extends > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > implements > > > > > > > > > > - SpecializableComposite, > > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > > DecoratedCopier, > DecoratedConverter, > > > > > > Cloneable { > > > > > > > > > > + > SpecializableComposite, > > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > > DecoratedCopier, > > > > > > > > > > + > DecoratedConverter, > > > > > > Cloneable, > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > //TODO extract > > > > > > BaseDelegatingTransformer > > > > > > > > > with pluggable delegate > > > > > > > > > > selection > > > > > > > > > > > > > > > > > > > > - > > > > > > > > > > private static class > > > > MapThreadLocal > > > > > > > > extends > > > > > > > > > ThreadLocal { > > > > > > > > > > protected Object > > > > > > initialValue() { > > > > > > > > > > return new > > > > HashMap(); > > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > private Specializer > specializer; > > > > > > > > > > + private boolean > > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > > > private transient > ThreadLocal > > > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > > = > > > > > > new > > > > > > > > > MapThreadLocal(); > > > > > > > > > > private transient > ThreadLocal > > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > > + > > > > > > sourceClass), > > > > > > > > > destinationClass, > > > > > > > > > > sourceClass); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > > () > > > > > > > > > > */ > > > > > > > > > > protected Class[] > > > > > > getSourceClassesImpl() > > > > > > > > > throws Exception { > > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > > * if no > suitable > > > > > > transformer > > > > > > > > > could be found > > > > > > > > > > */ > > > > > > > > > > private Transformer > > > > > > getTransformer(Class > > > > > > > > > transformerType, Class > > > > > > > > > > destinationClass, Class > sourceClass) > > > > throws > > > > > > > > > TransformationException { > > > > > > > > > > + Transformer > candidate = > > > > > > null; > > > > > > > > > > for (int i = 0; i < > > > > > > > > > components.length; i++) { > > > > > > > > > > // if the > > > > transformer > > > > > > is > > > > > > > > > the correct type > > > > > > > > > > Transformer > > > > > > transformer = > > > > > > > > > (Transformer) > > > > > > > > > > components[i]; > > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > > // > if the > > > > > > > > > transformer is capable of > > > > > > > > > > performing the transformation > > > > > > > > > > if > > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > > + > > > > if > > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > > + > > > > > > > > > > > > > > > > > && candidate == > > > > > > > > > > null > > > > > > > > > > + > > > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > > + > > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > > + > > > > > > > > > candidate = transformer; > > > > > > > > > > + > > > > > > > > > continue; > > > > > > > > > > + > > > > } > > > > > > > > > > > > > > if > > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > > > return > > > > > > > > > transformer; > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > - > > > > > > > > > > + if > (candidate != > > > > > > null) { > > > > > > > > > > + > return > > > > > > > > candidate; > > > > > > > > > > + } > > > > > > > > > > } > > > > > > > > > > throw new > > > > > > > > TransformationException( > > > > > > > > > > "Could not > find a > > > > > > > > > transformer that can transform > > > > > > > > > > objects of " > > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > > > source); > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > + * Get the > > > > > > preferPreciseTransformers. > > > > > > > > > > + * @return boolean > > > > > > > > > > + */ > > > > > > > > > > + public boolean > > > > > > > > > isPreferPreciseTransformers() { > > > > > > > > > > + return > > > > > > > > preferPreciseTransformers; > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * Set the > > > > > > preferPreciseTransformers. > > > > > > > > > Default false. > > > > > > > > > > + * @param > > > > preferPreciseTransformers > > > > > > the > > > > > > > > > boolean to set > > > > > > > > > > + */ > > > > > > > > > > + public void > > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > > + > > > > > > this.preferPreciseTransformers = > > > > > > > > > > preferPreciseTransformers; > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > } > > > > > > > > > > \ No newline at end of file > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > (revision 358) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > > + * Implementation of > > > > > > > > isImpreciseConversion > > > > > > > > > > + * @param destinationClass > > > > > > > > > > + * @param sourceClass > > > > > > > > > > + * @return > > > > > > > > > > + */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > destinationClass > > > > == > > > > > > null > > > > > > > > && > > > > > > > > > sourceClass != null; > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * Learn whether the > specified > > > > > > > > conversion > > > > > > > > > yields an imprecise > > > > > > > > > > result. > > > > > > > > > > + * @param destinationClass > > > > > > > > > > + * @param sourceClass > > > > > > > > > > + * @return boolean > > > > > > > > > > + */ > > > > > > > > > > + public final boolean > > > > > > > > > isImpreciseConversion(Class > > > > destinationClass, > > > > > > > > > > Class sourceClass) { > > > > > > > > > > + try { > > > > > > > > > > + return > > > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > > sourceClass); > > > > > > > > > > + } catch (Exception > e) { > > > > > > > > > > + if (e > instanceof > > > > > > > > > RuntimeException && > > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > > + > throw > > > > > > > > > (RuntimeException) e; > > > > > > > > > > + } > > > > > > > > > > + throw new > > > > > > > > > TransformationException("Could not > > > > > > > > > > determine if conversion of " > > > > > > > > > > + > > > > + > > > > > > > > > sourceClass + " to " + > > > > > > > > > > destinationClass > > > > > > > > > > + > > > > + " > > > > > > > > > results in a loss of > > > > > > > > > > precision", e); > > > > > > > > > > + } > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > // property getters and setters > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > (revision 357) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > > /* > > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > > original > > > > > > > > author > > > > > > > > > or authors. > > > > > > > > > > + * Copyright 2004-2005, 2007-2008 > the > > > > > > original > > > > > > > > > author or authors. > > > > > > > > > > * > > > > > > > > > > * Licensed under the Apache > License, > > > > > > Version > > > > > > > > 2.0 > > > > > > > > > (the "License"); you may > > > > > > > > > > not > > > > > > > > > > * use this file except in > compliance > > > > with > > > > > > the > > > > > > > > > License. You may obtain a > > > > > > > > > > copy of > > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > > package > > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > > +import java.util.Iterator; > > > > > > > > > > import java.util.List; > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > import > > > > net.sf.morph.transform.Transformer; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > > */ > > > > > > > > > > public class ChainedTransformer > extends > > > > > > > > > BaseCompositeTransformer > > > > > > > > > > implements > > > > > > > > > > - > DecoratedConverter, > > > > > > > > > DecoratedCopier, ExplicitTransformer > { > > > > > > > > > > + > DecoratedConverter, > > > > > > > > > DecoratedCopier, > ExplicitTransformer, > > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > private Converter > copyConverter; > > > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + List > conversionPath = > > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > > sourceClass); > > > > > > > > > > + return > > > > > > > > !isPrecise(conversionPath, > > > > > > > > > sourceClass, 0); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > * Get the converter used > when > > > > using > > > > > > a > > > > > > > > > ChainedTransformer as a > > > > > > > > > > Copier. > > > > > > > > > > * @return > > > > > > > > > > */ > > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > > throw new > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > > > "Chained > > > > > > > > > conversion path could not > > > > > > > > > > be determined"); > > > > > > > > > > } > > > > > > > > > > + log.debug("Using > chained > > > > > > > > > conversion path " + > > > > > > > > > > conversionPath); > > > > > > > > > > Object o = source; > > > > > > > > > > for (int i = 0; i < > > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > > o = > > > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > > conversionPath.get(i), o, locale); > > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > > throw new > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > source, null, > > > > > > > > > > > > > > > > "Chained > > > > > > > > > conversion path could not > > > > > > > > > > be determined"); > > > > > > > > > > } > > > > > > > > > > + log.debug("Using > chained > > > > > > > > > conversion path " + > > > > > > > > > > conversionPath); > > > > > > > > > > Object last = > > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > > conversionPath.get(chain.length - > 2), > > > > > > source, > > > > > > > > > locale); > > > > > > > > > > ((Copier) > > > > > > > > copier).copy(destination, > > > > > > > > > last, locale); > > > > > > > > > > } > > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > > * @return List > > > > > > > > > > */ > > > > > > > > > > protected List > > > > > > getConversionPath(Class > > > > > > > > > destinationType, Class > > > > > > > > > > sourceType) { > > > > > > > > > > - if (sourceType != > null) > > > > { > > > > > > > > > > - List > withoutNull > > > > = > > > > > > > > > > getConversionPath(destinationType, > > > > > > sourceType, > > > > > > > > 0, > > > > > > > > > false); > > > > > > > > > > - if > (withoutNull > > > > != > > > > > > null) > > > > > > > > { > > > > > > > > > > - > return > > > > > > > > > withoutNull; > > > > > > > > > > - } > > > > > > > > > > - } > > > > > > > > > > - return > > > > > > > > > getConversionPath(destinationType, > > > > sourceType, > > > > > > 0, > > > > > > > > > > true); > > > > > > > > > > + return > > > > > > > > > getConversionPath(destinationType, > > > > sourceType, > > > > > > 0); > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > > * @param allowNull > > > > > > > > > > * @return List > > > > > > > > > > */ > > > > > > > > > > - private List > > > > getConversionPath(Class > > > > > > > > > destinationType, Class > > > > > > > > > > sourceType, int index, boolean > > > > allowNull) { > > > > > > > > > > + private List > > > > getConversionPath(Class > > > > > > > > > destinationType, Class > > > > > > > > > > sourceType, int index) { > > > > > > > > > > Transformer[] chain > = > > > > > > getChain(); > > > > > > > > > > Transformer c = > > > > chain[index]; > > > > > > > > > > if (index + 1 == > > > > > > chain.length) { > > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > > } > > > > > > > > > > return > null; > > > > > > > > > > } > > > > > > > > > > + List > possibleResult = > > > > null; > > > > > > > > > > Class[] available = > > > > > > > > > c.getDestinationClasses(); > > > > > > > > > > for (int i = 0; i < > > > > > > > > > available.length; i++) { > > > > > > > > > > - if > (available[i] > > > > == > > > > > > null > > > > > > > > > && !allowNull) { > > > > > > > > > > - > > > > continue; > > > > > > > > > > - } > > > > > > > > > > if > > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > > available[i], sourceType)) { > > > > > > > > > > - > List > > > > tail = > > > > > > > > > > getConversionPath(destinationType, > > > > > > available[i], > > > > > > > > > index + 1, allowNull); > > > > > > > > > > + > List > > > > tail = > > > > > > > > > > getConversionPath(destinationType, > > > > > > available[i], > > > > > > > > > index + 1); > > > > > > > > > > if > (tail > > > > != > > > > > > null) > > > > > > > > { > > > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > > available[i]); > > > > > > > > > > - > > > > > > return > > > > > > > > > tail; > > > > > > > > > > + > > > > if > > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > > index)) { > > > > > > > > > > + > > > > > > > > > return tail; > > > > > > > > > > + > > > > } > > > > > > > > > > + > > > > > > > > > possibleResult = tail; > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > } > > > > > > > > > > - return null; > > > > > > > > > > + return > possibleResult; > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > + private boolean > isPrecise(List > > > > > > > > > conversionPath, Class sourceType, > > > > > > > > > > int index) { > > > > > > > > > > + Transformer[] > chain = > > > > > > > > getChain(); > > > > > > > > > > + Class > currentSource = > > > > > > > > sourceType; > > > > > > > > > > + int i = 0; > > > > > > > > > > + for (Iterator iter > = > > > > > > > > > conversionPath.iterator(); > > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > > + Class > > > > currentDest = > > > > > > > > > (Class) iter.next(); > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > > + i], currentDest, > > > > > > > > > > + > > > > > > > > > currentSource)) { > > > > > > > > > > + > return > > > > > > false; > > > > > > > > > > + } > > > > > > > > > > + > currentSource = > > > > > > > > > currentDest; > > > > > > > > > > + } > > > > > > > > > > + return true; > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > /** > > > > > > > > > > * Get the components array > > > > narrowed > > > > > > to a > > > > > > > > > Transformer[]. > > > > > > > > > > * @return Transformer[] > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > (revision > > > > > > > > > > 0) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > (revision > > > > > > > > > > 0) > > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > > +/* > > > > > > > > > > + * Copyright 2008 the original > author > > > > or > > > > > > > > authors. > > > > > > > > > > + * > > > > > > > > > > + * Licensed under the Apache > License, > > > > > > Version > > > > > > > > 2.0 > > > > > > > > > (the "License"); you > > > > > > > > > > may not > > > > > > > > > > + * use this file except in > compliance > > > > with > > > > > > the > > > > > > > > > License. You may obtain a > > > > > > > > > > copy of > > > > > > > > > > + * the License at > > > > > > > > > > + * > > > > > > > > > > + * > > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > > + * > > > > > > > > > > + * Unless required by applicable > law or > > > > > > agreed > > > > > > > > to > > > > > > > > > in writing, software > > > > > > > > > > + * distributed under the License > is > > > > > > distributed > > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > > WITHOUT > > > > > > > > > > + * WARRANTIES OR CONDITIONS OF > ANY > > > > KIND, > > > > > > either > > > > > > > > > express or implied. See > > > > > > > > > > the > > > > > > > > > > + * License for the specific > language > > > > > > governing > > > > > > > > > permissions and > > > > > > > > > > limitations under > > > > > > > > > > + * the License. > > > > > > > > > > + */ > > > > > > > > > > +package net.sf.morph.transform; > > > > > > > > > > + > > > > > > > > > > +/** > > > > > > > > > > + * Defines a converter whose > operation > > > > may > > > > > > > > result > > > > > > > > > in a loss of data > > > > > > > > > > precision. > > > > > > > > > > + * > > > > > > > > > > + * @author mbenson > > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > > + */ > > > > > > > > > > +public interface > ImpreciseConverter > > > > extends > > > > > > > > > Converter { > > > > > > > > > > + /** > > > > > > > > > > + * Learn whether the > specified > > > > > > > > conversion > > > > > > > > > might yield an imprecise > > > > > > > > > > result. > > > > > > > > > > + * @param destinationClass > > > > > > > > > > + * @param sourceClass > > > > > > > > > > + * @return boolean > > > > > > > > > > + */ > > > > > > > > > > + boolean > > > > isImpreciseConversion(Class > > > > > > > > > destinationClass, Class > > > > > > > > > > sourceClass); > > > > > > > > > > +} > > > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > > Name: svn:eol-style > > > > > > > > > > + native > > > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > (revision 362) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > import > > > > net.sf.morph.transform.Converter; > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > +import > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * Converts an object to a textual > > > > > > > > representation > > > > > > > > > by calling the object's > > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > > */ > > > > > > > > > > -public class > ObjectToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter { > > > > > > > > > > +public class > ObjectToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > private Converter > textConverter; > > > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > protected boolean > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > return true; > > > > > > > > > > } > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > (revision 361) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > > import > > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > - * Converts basic text types into > > > > primtive > > > > > > > > > numbers or {@link > > > > > > > > > > java.lang.Number} > > > > > > > > > > + * Converts basic text types into > > > > primitive > > > > > > > > > numbers or {@link > > > > > > > > > > java.lang.Number} > > > > > > > > > > * objects. > > > > > > > > > > * > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > (revision 363) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > import > > > > net.sf.morph.transform.Converter; > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > +import > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * Converts {@link > java.lang.Number}s > > > > into > > > > > > basic > > > > > > > > > text types ({@link > > > > > > > > > > java.lang.String}, > > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > > */ > > > > > > > > > > -public class > NumberToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter { > > > > > > > > > > +public class > NumberToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > > > > > > > > > > + ImpreciseConverter > { > > > > > > > > > > > > > > > > > > > > private Converter > textConverter; > > > > > > > > > > private Converter > > > > numberConverter; > > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > * Get the number converter > used > > > > by > > > > > > this > > > > > > > > > NumberToTextConverter. > > > > > > > > > > * @return Converter > > > > > > > > > > */ > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > (revision 360) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > import > > > > net.sf.morph.transform.Converter; > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > +import > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * Converts the basic time types > ({@link > > > > > > > > > java.util.Date} and > > > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > * @since Dec 31, 2004 > > > > > > > > > > */ > > > > > > > > > > -public class TimeToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter { > > > > > > > > > > +public class TimeToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > > > > > > > > > > + ImpreciseConverter > { > > > > > > > > > > > > > > > > > > > > private DateFormat > dateFormat; > > > > > > > > > > private Converter > timeConverter; > > > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > protected boolean > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > return true; > > > > > > > > > > } > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > (revision 357) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > import > net.sf.morph.util.ClassUtils; > > > > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > > > > * @since Jan 2, 2005 > > > > > > > > > > */ > > > > > > > > > > public class TextConverter > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > > > > > > > > > > - > ExplicitTransformer { > > > > > > > > > > + > ExplicitTransformer, > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > > > private static final Class > > > > > > CHAR_SEQUENCE > > > > > > > > = > > > > > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > > > > ClassUtils > > > > > > > > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > > > > > s.add(Character.class); > > > > > > > > > > s.add(char.class); > > > > > > > > > > s.add(null); > > > > > > > > > > - if (CHAR_SEQUENCE > != > > > > null) { > > > > > > > > > > - > > > > > > s.add(CHAR_SEQUENCE); > > > > > > > > > > - try { > > > > > > > > > > - > > > > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > > > > > StringBuffer.class.getConstructor(new > > > > > > Class[] { > > > > > > > > > String.class })); > > > > > > > > > > - } catch > > > > (Exception > > > > > > e) { > > > > > > > > > > - > //nope > > > > > > > > > > - } > > > > > > > > > > - } > > > > > > > > > > + > s.add(CHAR_SEQUENCE); > > > > > > > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > > > > = > > > > > > > > > (Class[]) s.toArray(new > > > > > > > > > > Class[s.size()]); > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > > > > } > > > > > > > > > > return new > > > > > > > > > Character(string.charAt(0)); > > > > > > > > > > } > > > > > > > > > > - if > (destinationClass == > > > > > > > > > String.class) { > > > > > > > > > > + if > (destinationClass == > > > > > > > > > String.class > > > > > > > > > > + || > > > > > > > > > (destinationClass == CHAR_SEQUENCE > && > > > > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > > > > return > string; > > > > > > > > > > } > > > > > > > > > > if > (destinationClass == > > > > > > > > > byte[].class) { > > > > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > > sourceClass)) { > > > > > > > > > > + return > true; > > > > > > > > > > + } > > > > > > > > > > + return > > > > > > isChar(destinationClass) > > > > > > > > && > > > > > > > > > !isChar(sourceClass); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > protected boolean > > > > > > > > > isAutomaticallyHandlingNulls() { > > > > > > > > > > return > !isEmptyNull(); > > > > > > > > > > } > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > (revision 362) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -20,8 +20,10 @@ > > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > > import > > > > net.sf.morph.transform.Converter; > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > +import > > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * Converts boolean values to text > > > > values. > > > > > > > > > Subclasses can build in > > > > > > > > > > support for > > > > > > > > > > @@ -32,10 +34,10 @@ > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > * @since Jan 9, 2005 > > > > > > > > > > */ > > > > > > > > > > -public class > BooleanToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter { > > > > > > > > > > - > > > > > > > > > > +public class > BooleanToTextConverter > > > > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > ImpreciseConverter { > > > > > > > > > > + > > > > > > > > > > private static final > Class[] > > > > > > SOURCE_TYPES > > > > > > > > = > > > > > > > > > { Boolean.class, > > > > > > > > > > boolean.class }; > > > > > > > > > > - > > > > > > > > > > + > > > > > > > > > > private Converter > textConverter; > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > @@ -93,9 +95,16 @@ > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > > destinationClass, String.class); > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > protected boolean > > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > > return true; > > > > > > > > > > - } > > > > > > > > > > + } > > > > > > > > > > > > > > > > > > > > /** > > > > > > > > > > * Get the text converter > used by > > > > > > this > > > > > > > > > BaseToPrettyTextConverter. > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > (revision 363) > > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > (working copy) > > > > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > > > import > > > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > > +import > > > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > > import > > > > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > > @@ -31,8 +32,8 @@ > > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > > * @since Dec 14, 2004 > > > > > > > > > > */ > > > > > > > > > > -public class NumberConverter > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter { > > > > > > > > > > - > > > > > > > > > > +public class NumberConverter > extends > > > > > > > > > BaseTransformer implements > > > > > > > > > > DecoratedConverter, > ImpreciseConverter { > > > > > > > > > > + > > > > > > > > > > private static final > Class[] > > > > > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > > > > > Number.class, > byte.class, > > > > > > > > > short.class, int.class, > > > > > > > > > > long.class, > > > > > > > > > > float.class, > > > > double.class, > > > > > > null > > > > > > > > > > @@ -116,9 +117,20 @@ > > > > > > > > > > /** > > > > > > > > > > * {@inheritDoc} > > > > > > > > > > */ > > > > > > > > > > + protected boolean > > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > > destinationClass, Class > sourceClass) { > > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > > sourceClass) > > > > > > > > > > + || > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > > > > > + > > > > > > > > > sourceClass) < 0; > > > > > > > > > > + } > > > > > > > > > > + > > > > > > > > > > + /** > > > > > > > > > > + * {@inheritDoc} > > > > > > > > > > + */ > > > > > > > > > > protected Object > > > > convertImpl(Class > > > > > > > > > destinationClass, Object source, > > > > > > > > > > Locale locale) > throws > > > > > > Exception { > > > > > > > > > > - > > > > > > > > > > + if > (destinationClass == > > > > > > null) { > > > > > > > > > > + return > null; > > > > > > > > > > + } > > > > > > > > > > if > > > > > > > > (destinationClass.isPrimitive() > > > > > > > > > && source == null) { > > > > > > > > > > throw new > > > > > > > > > > TransformationException(destinationClass, > > > > > > > > > > source); > > > > > > > > > > } > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > ... [truncated message content] |
From: Matt S. <mat...@sp...> - 2008-01-25 21:43:44
|
To clarify, I am +0 on ImpreciseTransformer. I am -1 on PrecisionTransformer, but of course I am all ears if you would like me to change my vote on that one ;) Matt On Jan 25, 2008 4:41 PM, Matt Sgarlata <mat...@sp...> wrote: > Oh boy, it's an Apache pop quiz! If I remember correctly, I am +0 to > indicate I support the feature's addition, but I do not plan on actively > working on it myself. > > Just to remind you, I believe I have already fixed the issue that > ImpreciseTransformer is intended to address by ensuring order of components > is always maintained. However, I see no problem with having 2 alternative > solutions to the issue. > > Matt > > > On Jan 25, 2008 2:59 PM, Matt Benson <gud...@ya...> wrote: > > > Where did you end up on the ImpreciseTransformer idea? > > +1, -1, or +0? > > > > -Matt > > > > --- Matt Sgarlata <mat...@sp...> > > wrote: > > > > > I see what you mean. I prefer ImpreciseTransformer > > > to PrecisionTransformer > > > because of the difficulty of assigning a numeric > > > value for the degree of > > > precision. I think that assignment is going to end > > > up arbitrary and > > > confusing pretty quickly. ImpreciseTransformer also > > > would probably make the > > > logic for determining the conversion path simpler. > > > > > > In terms of using different paths for different > > > source and destination > > > combos, I think perhaps the best solution in such a > > > case would be to just > > > make a bunch of individual AssemblerCopiers with > > > individual paths, and then > > > add them all together using the > > > SimpleDelegatingTransformer. > > > > > > Matt > > > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > You have a point, though I guess my aim in > > > avoiding > > > > such a thing was that--usually--the path is simple > > > > enough to determine given source and dest classes. > > > > Secondly, you might use a different path depending > > > on > > > > available source/dest combos, so the configuration > > > > might be a little more complex. :| As for where > > > > converters with awareness of "precision" might be > > > > useful, I can't say that I know of another context > > > > right now, but at the very least I would say it > > > might > > > > be useful knowledge for both number and text > > > types. > > > > > > > > -Matt > > > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > > wrote: > > > > > > > > > I agree, that does sound like it could end up > > > being > > > > > somewhat arbitrary. I > > > > > know the original impetus for this was that > > > > > configuration of the > > > > > ChainedTransformer could be a real pain in the > > > neck. > > > > > Are there other > > > > > situations where the information provided by > > > > > ImplicitTransformer or > > > > > PrecisionTransformer might be useful? I guess > > > what > > > > > I'm getting at here is, > > > > > what is the requirement we are trying to solve? > > > > > Perhaps if we think about > > > > > it in a new way a different solution will > > > present > > > > > itself. > > > > > > > > > > Perhaps an alternative could be to introduce a > > > new > > > > > setTransformationPath(Class[] path) method to > > > the > > > > > ChainedTransformer. That > > > > > would make configuration a snap, even if you > > > were > > > > > trying to use dependency > > > > > injection for the configuration. > > > > > > > > > > Matt S > > > > > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > > > <gud...@ya...> wrote: > > > > > > > > > > > More on this: what do you think about the > > > concept > > > > > of > > > > > > something like a PrecisionTransformer that > > > returns > > > > > a > > > > > > float precision from 0.0 to 1.0 given a > > > > > > destinationClass and a sourceClass? These > > > might > > > > > be > > > > > > somewhat arbitrary, or calculated (like with > > > > > numeric > > > > > > types), but they might allow a little more > > > > > > informedness on the part of the consumer. > > > > > > > > > > > > -Matt B > > > > > > > > > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > > <mat...@sp...> > > > > > > > wrote: > > > > > > > > > > > > > > > I have been thinking more about this > > > approach, > > > > > and > > > > > > > > it's really starting to > > > > > > > > grow on me. I do have one concern though, > > > can > > > > > > > this > > > > > > > > approach be extended to > > > > > > > > Copiers? For example, a Map -> Object > > > copy > > > > > could > > > > > > > > probably be considered an > > > > > > > > imprecise transformation because the Map > > > may > > > > > have > > > > > > > > more keys than the Object > > > > > > > > has properties. > > > > > > > > > > > > > > I thought about this as well. It could be > > > done; > > > > > it > > > > > > > might be slightly complex calculating the > > > > > > > "precision" > > > > > > > of a PropertyNameMatchingCopier--I would > > > think > > > > > an > > > > > > > explicitly specified PNMatchingC would be > > > > > precise; > > > > > > > an > > > > > > > imprecise one would be one using property > > > name > > > > > > > discovery and where the properties of the > > > source > > > > > are > > > > > > > not all available on the destination. > > > > > There--the > > > > > > > hard > > > > > > > part of that one is over. :) I will work > > > on > > > > > > > ImpreciseConverter -> ImpreciseTransformer > > > > > extends > > > > > > > Transformer and other semantic changes as > > > time > > > > > > > permits. Your ordering changes are, I > > > expect, > > > > > fine > > > > > > > by > > > > > > > me as well. :) > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > In addition to your approach, I also like > > > the > > > > > idea > > > > > > > > of cleaning up the > > > > > > > > internal implementation in Morph so that > > > > > ordering > > > > > > > of > > > > > > > > source and destination > > > > > > > > classes is preserved for the following > > > > > reasons: > > > > > > > > 1) for at least some portion of users, > > > setting > > > > > the > > > > > > > > order of source and > > > > > > > > destination classes will make sense as an > > > > > > > indication > > > > > > > > of the transformer's > > > > > > > > preferences for performing transformations > > > (so > > > > > for > > > > > > > > this class of users, > > > > > > > > creating new transformers that play nicely > > > > > with > > > > > > > the > > > > > > > > ChainedTransformerTestCase will be > > > simpler) > > > > > > > > 2) I think a general change from using > > > > > HashSets to > > > > > > > > ordered sets in Morph's > > > > > > > > implementation will mean transformations > > > > > happen > > > > > > > more > > > > > > > > consistently across > > > > > > > > JVMs and across time on the same JVM, > > > leading > > > > > to a > > > > > > > > more stable platform > > > > > > > > > > > > > > > > So, what I did is I basically went through > > > the > > > > > > > Morph > > > > > > > > codebase and replaced > > > > > > > > HashSets with ordered sets (preference > > > order > > > > > is: > > > > > > > JDK > > > > > > > > 1.4 LinkedHashSet, > > > > > > > > Commons-collections ListOrderedSet, copy > > > of > > > > > > > > ListOrderedSet in > > > > > > > > net.sf.morph.util). I was never able to > > > > > modify > > > > > > > the > > > > > > > > ChainedTransformerTestCase so that it > > > > > consistently > > > > > > > > threw an error. However, > > > > > > > > after working on the test case long > > > enough, > > > > > > > > eventually something changed in > > > > > > > > my environment so that the test started to > > > > > fail. > > > > > > > I > > > > > > > > did my change of > > > > > > > > HashSets to ordered sets, and that was > > > able to > > > > > fix > > > > > > > > the broken test. > > > > > > > > > > > > > > > > I checked in my changes for you to take a > > > look > > > > > > > at... > > > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > > Be a better friend, newshound, and > > > > > > > > > know-it-all with Yahoo! Mobile. Try it > > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > (revision 357) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > (working copy) > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > /* > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > original > > > > > > > author > > > > > > > > or authors. > > > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > > > original > > > > > > > > author or authors. > > > > > > > > > * > > > > > > > > > * Licensed under the Apache License, > > > > > Version > > > > > > > 2.0 > > > > > > > > (the "License"); you may > > > > > > > > > not > > > > > > > > > * use this file except in compliance > > > with > > > > > the > > > > > > > > License. You may obtain a > > > > > > > > > copy of > > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > import > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > net.sf.morph.transform.NodeCopier; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > import > > > net.sf.morph.transform.Transformer; > > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > > * @since Dec 12, 2004 > > > > > > > > > */ > > > > > > > > > public class > > > SimpleDelegatingTransformer > > > > > > > extends > > > > > > > > BaseCompositeTransformer > > > > > > > > > implements > > > > > > > > > - SpecializableComposite, > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > DecoratedCopier, DecoratedConverter, > > > > > Cloneable { > > > > > > > > > + SpecializableComposite, > > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > > DecoratedCopier, > > > > > > > > > + DecoratedConverter, > > > > > Cloneable, > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > //TODO extract > > > > > BaseDelegatingTransformer > > > > > > > > with pluggable delegate > > > > > > > > > selection > > > > > > > > > > > > > > > > > > - > > > > > > > > > private static class > > > MapThreadLocal > > > > > > > extends > > > > > > > > ThreadLocal { > > > > > > > > > protected Object > > > > > initialValue() { > > > > > > > > > return new > > > HashMap(); > > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > private Specializer specializer; > > > > > > > > > + private boolean > > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > > > private transient ThreadLocal > > > > > > > > > visitedSourceToDestinationMapThreadLocal > > > = > > > > > new > > > > > > > > MapThreadLocal(); > > > > > > > > > private transient ThreadLocal > > > > > > > > stackDepthThreadLocal = new > > > > > > > > > StackDepthThreadLocal(); > > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > > (getTransformer(destinationClass, > > > > > > > > > + > > > > > sourceClass), > > > > > > > > destinationClass, > > > > > > > > > sourceClass); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl > > () > > > > > > > > > */ > > > > > > > > > protected Class[] > > > > > getSourceClassesImpl() > > > > > > > > throws Exception { > > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > > * if no suitable > > > > > transformer > > > > > > > > could be found > > > > > > > > > */ > > > > > > > > > private Transformer > > > > > getTransformer(Class > > > > > > > > transformerType, Class > > > > > > > > > destinationClass, Class sourceClass) > > > throws > > > > > > > > TransformationException { > > > > > > > > > + Transformer candidate = > > > > > null; > > > > > > > > > for (int i = 0; i < > > > > > > > > components.length; i++) { > > > > > > > > > // if the > > > transformer > > > > > is > > > > > > > > the correct type > > > > > > > > > Transformer > > > > > transformer = > > > > > > > > (Transformer) > > > > > > > > > components[i]; > > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > > // if the > > > > > > > > transformer is capable of > > > > > > > > > performing the transformation > > > > > > > > > if > > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > > > transformer, > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > + > > > if > > > > > > > > (isPreferPreciseTransformers() > > > > > > > > > + > > > > > > > > > > > > > > > && candidate == > > > > > > > > > null > > > > > > > > > + > > > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > > + > > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > > + > > > > > > > > candidate = transformer; > > > > > > > > > + > > > > > > > > continue; > > > > > > > > > + > > > } > > > > > > > > > > > > if > > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > > > return > > > > > > > > transformer; > > > > > > > > > } > > > > > > > > > } > > > > > > > > > - > > > > > > > > > + if (candidate != > > > > > null) { > > > > > > > > > + return > > > > > > > candidate; > > > > > > > > > + } > > > > > > > > > } > > > > > > > > > throw new > > > > > > > TransformationException( > > > > > > > > > "Could not find a > > > > > > > > transformer that can transform > > > > > > > > > objects of " > > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > > source); > > > > > > > > > } > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > + * Get the > > > > > preferPreciseTransformers. > > > > > > > > > + * @return boolean > > > > > > > > > + */ > > > > > > > > > + public boolean > > > > > > > > isPreferPreciseTransformers() { > > > > > > > > > + return > > > > > > > preferPreciseTransformers; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * Set the > > > > > preferPreciseTransformers. > > > > > > > > Default false. > > > > > > > > > + * @param > > > preferPreciseTransformers > > > > > the > > > > > > > > boolean to set > > > > > > > > > + */ > > > > > > > > > + public void > > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > > preferPreciseTransformers) { > > > > > > > > > + > > > > > this.preferPreciseTransformers = > > > > > > > > > preferPreciseTransformers; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > } > > > > > > > > > \ No newline at end of file > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > (revision 358) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > (working copy) > > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > > } > > > > > > > > > } > > > > > > > > > > > > > > > > > > + /** > > > > > > > > > + * Implementation of > > > > > > > isImpreciseConversion > > > > > > > > > + * @param destinationClass > > > > > > > > > + * @param sourceClass > > > > > > > > > + * @return > > > > > > > > > + */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return destinationClass > > > == > > > > > null > > > > > > > && > > > > > > > > sourceClass != null; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * Learn whether the specified > > > > > > > conversion > > > > > > > > yields an imprecise > > > > > > > > > result. > > > > > > > > > + * @param destinationClass > > > > > > > > > + * @param sourceClass > > > > > > > > > + * @return boolean > > > > > > > > > + */ > > > > > > > > > + public final boolean > > > > > > > > isImpreciseConversion(Class > > > destinationClass, > > > > > > > > > Class sourceClass) { > > > > > > > > > + try { > > > > > > > > > + return > > > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > > sourceClass); > > > > > > > > > + } catch (Exception e) { > > > > > > > > > + if (e instanceof > > > > > > > > RuntimeException && > > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > > + throw > > > > > > > > (RuntimeException) e; > > > > > > > > > + } > > > > > > > > > + throw new > > > > > > > > TransformationException("Could not > > > > > > > > > determine if conversion of " > > > > > > > > > + > > > + > > > > > > > > sourceClass + " to " + > > > > > > > > > destinationClass > > > > > > > > > + > > > + " > > > > > > > > results in a loss of > > > > > > > > > precision", e); > > > > > > > > > + } > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > // property getters and setters > > > > > > > > > > > > > > > > > > /** > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > (revision 357) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > (working copy) > > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > > /* > > > > > > > > > - * Copyright 2004-2005, 2007 the > > > original > > > > > > > author > > > > > > > > or authors. > > > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > > > original > > > > > > > > author or authors. > > > > > > > > > * > > > > > > > > > * Licensed under the Apache License, > > > > > Version > > > > > > > 2.0 > > > > > > > > (the "License"); you may > > > > > > > > > not > > > > > > > > > * use this file except in compliance > > > with > > > > > the > > > > > > > > License. You may obtain a > > > > > > > > > copy of > > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > > package > > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > > +import java.util.Iterator; > > > > > > > > > import java.util.List; > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > import > > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > import > > > net.sf.morph.transform.Transformer; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > > * @since Nov 24, 2004 > > > > > > > > > */ > > > > > > > > > public class ChainedTransformer extends > > > > > > > > BaseCompositeTransformer > > > > > > > > > implements > > > > > > > > > - DecoratedConverter, > > > > > > > > DecoratedCopier, ExplicitTransformer { > > > > > > > > > + DecoratedConverter, > > > > > > > > DecoratedCopier, ExplicitTransformer, > > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + List conversionPath = > > > > > > > > getConversionPath(destinationClass, > > > > > > > > > sourceClass); > > > > > > > > > + return > > > > > > > !isPrecise(conversionPath, > > > > > > > > sourceClass, 0); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > * Get the converter used when > > > using > > > > > a > > > > > > > > ChainedTransformer as a > > > > > > > > > Copier. > > > > > > > > > * @return > > > > > > > > > */ > > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > > throw new > > > > > > > > TransformationException(destinationClass, > > > > > > > > > sourceType, null, > > > > > > > > > > > > > > "Chained > > > > > > > > conversion path could not > > > > > > > > > be determined"); > > > > > > > > > } > > > > > > > > > + log.debug("Using chained > > > > > > > > conversion path " + > > > > > > > > > conversionPath); > > > > > > > > > Object o = source; > > > > > > > > > for (int i = 0; i < > > > > > > > > conversionPath.size(); i++) { > > > > > > > > > o = > > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > > conversionPath.get(i), o, locale); > > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > > throw new > > > > > > > > TransformationException(destinationClass, > > > > > > > > > source, null, > > > > > > > > > > > > > > "Chained > > > > > > > > conversion path could not > > > > > > > > > be determined"); > > > > > > > > > } > > > > > > > > > + log.debug("Using chained > > > > > > > > conversion path " + > > > > > > > > > conversionPath); > > > > > > > > > Object last = > > > > > > > > getCopyConverter().convert((Class) > > > > > > > > > conversionPath.get(chain.length - 2), > > > > > source, > > > > > > > > locale); > > > > > > > > > ((Copier) > > > > > > > copier).copy(destination, > > > > > > > > last, locale); > > > > > > > > > } > > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > > * @return List > > > > > > > > > */ > > > > > > > > > protected List > > > > > getConversionPath(Class > > > > > > > > destinationType, Class > > > > > > > > > sourceType) { > > > > > > > > > - if (sourceType != null) > > > { > > > > > > > > > - List withoutNull > > > = > > > > > > > > > getConversionPath(destinationType, > > > > > sourceType, > > > > > > > 0, > > > > > > > > false); > > > > > > > > > - if (withoutNull > > > != > > > > > null) > > > > > > > { > > > > > > > > > - return > > > > > > > > withoutNull; > > > > > > > > > - } > > > > > > > > > - } > > > > > > > > > - return > > > > > > > > getConversionPath(destinationType, > > > sourceType, > > > > > 0, > > > > > > > > > true); > > > > > > > > > + return > > > > > > > > getConversionPath(destinationType, > > > sourceType, > > > > > 0); > > > > > > > > > } > > > > > > > > > > > > > > > > > > /** > > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > > * @param allowNull > > > > > > > > > * @return List > > > > > > > > > */ > > > > > > > > > - private List > > > getConversionPath(Class > > > > > > > > destinationType, Class > > > > > > > > > sourceType, int index, boolean > > > allowNull) { > > > > > > > > > + private List > > > getConversionPath(Class > > > > > > > > destinationType, Class > > > > > > > > > sourceType, int index) { > > > > > > > > > Transformer[] chain = > > > > > getChain(); > > > > > > > > > Transformer c = > > > chain[index]; > > > > > > > > > if (index + 1 == > > > > > chain.length) { > > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > > } > > > > > > > > > return null; > > > > > > > > > } > > > > > > > > > + List possibleResult = > > > null; > > > > > > > > > Class[] available = > > > > > > > > c.getDestinationClasses(); > > > > > > > > > for (int i = 0; i < > > > > > > > > available.length; i++) { > > > > > > > > > - if (available[i] > > > == > > > > > null > > > > > > > > && !allowNull) { > > > > > > > > > - > > > continue; > > > > > > > > > - } > > > > > > > > > if > > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > > available[i], sourceType)) { > > > > > > > > > - List > > > tail = > > > > > > > > > getConversionPath(destinationType, > > > > > available[i], > > > > > > > > index + 1, allowNull); > > > > > > > > > + List > > > tail = > > > > > > > > > getConversionPath(destinationType, > > > > > available[i], > > > > > > > > index + 1); > > > > > > > > > if (tail > > > != > > > > > null) > > > > > > > { > > > > > > > > > > > > > > > > tail.add(0, > > > > > > > > available[i]); > > > > > > > > > - > > > > > return > > > > > > > > tail; > > > > > > > > > + > > > if > > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > > index)) { > > > > > > > > > + > > > > > > > > return tail; > > > > > > > > > + > > > } > > > > > > > > > + > > > > > > > > possibleResult = tail; > > > > > > > > > } > > > > > > > > > } > > > > > > > > > } > > > > > > > > > - return null; > > > > > > > > > + return possibleResult; > > > > > > > > > } > > > > > > > > > > > > > > > > > > + private boolean isPrecise(List > > > > > > > > conversionPath, Class sourceType, > > > > > > > > > int index) { > > > > > > > > > + Transformer[] chain = > > > > > > > getChain(); > > > > > > > > > + Class currentSource = > > > > > > > sourceType; > > > > > > > > > + int i = 0; > > > > > > > > > + for (Iterator iter = > > > > > > > > conversionPath.iterator(); > > > > > > > > > iter.hasNext(); i++) { > > > > > > > > > + Class > > > currentDest = > > > > > > > > (Class) iter.next(); > > > > > > > > > + if > > > > > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > > + i], currentDest, > > > > > > > > > + > > > > > > > > currentSource)) { > > > > > > > > > + return > > > > > false; > > > > > > > > > + } > > > > > > > > > + currentSource = > > > > > > > > currentDest; > > > > > > > > > + } > > > > > > > > > + return true; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > /** > > > > > > > > > * Get the components array > > > narrowed > > > > > to a > > > > > > > > Transformer[]. > > > > > > > > > * @return Transformer[] > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > (revision > > > > > > > > > 0) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > (revision > > > > > > > > > 0) > > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > > +/* > > > > > > > > > + * Copyright 2008 the original author > > > or > > > > > > > authors. > > > > > > > > > + * > > > > > > > > > + * Licensed under the Apache License, > > > > > Version > > > > > > > 2.0 > > > > > > > > (the "License"); you > > > > > > > > > may not > > > > > > > > > + * use this file except in compliance > > > with > > > > > the > > > > > > > > License. You may obtain a > > > > > > > > > copy of > > > > > > > > > + * the License at > > > > > > > > > + * > > > > > > > > > + * > > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > > + * > > > > > > > > > + * Unless required by applicable law or > > > > > agreed > > > > > > > to > > > > > > > > in writing, software > > > > > > > > > + * distributed under the License is > > > > > distributed > > > > > > > > on an "AS IS" BASIS, > > > > > > > > > WITHOUT > > > > > > > > > + * WARRANTIES OR CONDITIONS OF ANY > > > KIND, > > > > > either > > > > > > > > express or implied. See > > > > > > > > > the > > > > > > > > > + * License for the specific language > > > > > governing > > > > > > > > permissions and > > > > > > > > > limitations under > > > > > > > > > + * the License. > > > > > > > > > + */ > > > > > > > > > +package net.sf.morph.transform; > > > > > > > > > + > > > > > > > > > +/** > > > > > > > > > + * Defines a converter whose operation > > > may > > > > > > > result > > > > > > > > in a loss of data > > > > > > > > > precision. > > > > > > > > > + * > > > > > > > > > + * @author mbenson > > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > > + */ > > > > > > > > > +public interface ImpreciseConverter > > > extends > > > > > > > > Converter { > > > > > > > > > + /** > > > > > > > > > + * Learn whether the specified > > > > > > > conversion > > > > > > > > might yield an imprecise > > > > > > > > > result. > > > > > > > > > + * @param destinationClass > > > > > > > > > + * @param sourceClass > > > > > > > > > + * @return boolean > > > > > > > > > + */ > > > > > > > > > + boolean > > > isImpreciseConversion(Class > > > > > > > > destinationClass, Class > > > > > > > > > sourceClass); > > > > > > > > > +} > > > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > > Name: svn:eol-style > > > > > > > > > + native > > > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > (revision 362) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > import > > > net.sf.morph.transform.Converter; > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > +import > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Converts an object to a textual > > > > > > > representation > > > > > > > > by calling the object's > > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Dec 24, 2004 > > > > > > > > > */ > > > > > > > > > -public class ObjectToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter { > > > > > > > > > +public class ObjectToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > destinationClass, String.class); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > protected boolean > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > return true; > > > > > > > > > } > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > (revision 361) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > > import > > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > - * Converts basic text types into > > > primtive > > > > > > > > numbers or {@link > > > > > > > > > java.lang.Number} > > > > > > > > > + * Converts basic text types into > > > primitive > > > > > > > > numbers or {@link > > > > > > > > > java.lang.Number} > > > > > > > > > * objects. > > > > > > > > > * > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > (revision 363) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > import > > > net.sf.morph.transform.Converter; > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > +import > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Converts {@link java.lang.Number}s > > > into > > > > > basic > > > > > > > > text types ({@link > > > > > > > > > java.lang.String}, > > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Jan 26, 2006 > > > > > > > > > */ > > > > > > > > > -public class NumberToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter { > > > > > > > > > +public class NumberToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, > > > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > private Converter > > > numberConverter; > > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > > } > > > > > > > > > > > > > > > > > > /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > destinationClass, String.class); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > * Get the number converter used > > > by > > > > > this > > > > > > > > NumberToTextConverter. > > > > > > > > > * @return Converter > > > > > > > > > */ > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > (revision 360) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > import > > > net.sf.morph.transform.Converter; > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > +import > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Converts the basic time types ({@link > > > > > > > > java.util.Date} and > > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Dec 31, 2004 > > > > > > > > > */ > > > > > > > > > -public class TimeToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter { > > > > > > > > > +public class TimeToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, > > > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > > > > > private DateFormat dateFormat; > > > > > > > > > private Converter timeConverter; > > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > destinationClass, String.class); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > protected boolean > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > return true; > > > > > > > > > } > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > (revision 357) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > import net.sf.morph.util.ClassUtils; > > > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > > > * @since Jan 2, 2005 > > > > > > > > > */ > > > > > > > > > public class TextConverter extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, > > > > > > > > > - ExplicitTransformer { > > > > > > > > > + ExplicitTransformer, > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > private static final Class > > > > > CHAR_SEQUENCE > > > > > > > = > > > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > > > ClassUtils > > > > > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > > > s.add(Character.class); > > > > > > > > > s.add(char.class); > > > > > > > > > s.add(null); > > > > > > > > > - if (CHAR_SEQUENCE != > > > null) { > > > > > > > > > - > > > > > s.add(CHAR_SEQUENCE); > > > > > > > > > - try { > > > > > > > > > - > > > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > > > StringBuffer.class.getConstructor(new > > > > > Class[] { > > > > > > > > String.class })); > > > > > > > > > - } catch > > > (Exception > > > > > e) { > > > > > > > > > - //nope > > > > > > > > > - } > > > > > > > > > - } > > > > > > > > > + s.add(CHAR_SEQUENCE); > > > > > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > > > = > > > > > > > > (Class[]) s.toArray(new > > > > > > > > > Class[s.size()]); > > > > > > > > > } > > > > > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > > > } > > > > > > > > > return new > > > > > > > > Character(string.charAt(0)); > > > > > > > > > } > > > > > > > > > - if (destinationClass == > > > > > > > > String.class) { > > > > > > > > > + if (destinationClass == > > > > > > > > String.class > > > > > > > > > + || > > > > > > > > (destinationClass == CHAR_SEQUENCE && > > > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > > > return string; > > > > > > > > > } > > > > > > > > > if (destinationClass == > > > > > > > > byte[].class) { > > > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + if > > > > > > > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > sourceClass)) { > > > > > > > > > + return true; > > > > > > > > > + } > > > > > > > > > + return > > > > > isChar(destinationClass) > > > > > > > && > > > > > > > > !isChar(sourceClass); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > protected boolean > > > > > > > > isAutomaticallyHandlingNulls() { > > > > > > > > > return !isEmptyNull(); > > > > > > > > > } > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > (revision 362) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -20,8 +20,10 @@ > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > import > > > net.sf.morph.transform.Converter; > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > +import > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Converts boolean values to text > > > values. > > > > > > > > Subclasses can build in > > > > > > > > > support for > > > > > > > > > @@ -32,10 +34,10 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Jan 9, 2005 > > > > > > > > > */ > > > > > > > > > -public class BooleanToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter { > > > > > > > > > - > > > > > > > > > +public class BooleanToTextConverter > > > extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > + > > > > > > > > > private static final Class[] > > > > > SOURCE_TYPES > > > > > > > = > > > > > > > > { Boolean.class, > > > > > > > > > boolean.class }; > > > > > > > > > - > > > > > > > > > + > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > @@ -93,9 +95,16 @@ > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > destinationClass, String.class); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > protected boolean > > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > > return true; > > > > > > > > > - } > > > > > > > > > + } > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Get the text converter used by > > > > > this > > > > > > > > BaseToPrettyTextConverter. > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > (revision 363) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > > @@ -31,8 +32,8 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Dec 14, 2004 > > > > > > > > > */ > > > > > > > > > -public class NumberConverter extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter { > > > > > > > > > - > > > > > > > > > +public class NumberConverter extends > > > > > > > > BaseTransformer implements > > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > + > > > > > > > > > private static final Class[] > > > > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > > > > Number.class, byte.class, > > > > > > > > short.class, int.class, > > > > > > > > > long.class, > > > > > > > > > float.class, > > > double.class, > > > > > null > > > > > > > > > @@ -116,9 +117,20 @@ > > > > > > > > > /** > > > > > > > > > * {@inheritDoc} > > > > > > > > > */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > > > > sourceClass) > > > > > > > > > + || > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > > > > + > > > > > > > > sourceClass) < 0; > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > protected Object > > > convertImpl(Class > > > > > > > > destinationClass, Object source, > > > > > > > > > Locale locale) throws > > > > > Exception { > > > > > > > > > - > > > > > > > > > + if (destinationClass == > > > > > null) { > > > > > > > > > + return null; > > > > > > > > > + } > > > > > > > > > if > > > > > > > (destinationClass.isPrimitive() > > > > > > > > && source == null) { > > > > > > > > > throw new > > > > > > > > TransformationException(destinationClass, > > > > > > > > > source); > > > > > > > > > } > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > (revision 362) > > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > (working copy) > > > > > > > > > @@ -18,7 +18,9 @@ > > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > > import > > > net.sf.morph.transform.Converter; > > > > > > > > > import > > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > > +import > > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > > > > > +import > > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > > > /** > > > > > > > > > * Base class for converts that convert > > > > > objects > > > > > > > to > > > > > > > > a pretty > > > > > > > > > programmer-friendly > > > > > > > > > @@ -27,7 +29,8 @@ > > > > > > > > > * @author Matt Sgarlata > > > > > > > > > * @since Feb 15, 2005 > > > > > > > > > */ > > > > > > > > > -public abstract class > > > > > BaseToPrettyTextConverter > > > > > > > > extends > > > > > > > > > BaseReflectorTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > > +public abstract class > > > > > BaseToPrettyTextConverter > > > > > > > > extends > > > > > > > > > BaseReflectorTransformer > > > > > > > > > + implements > > > > > DecoratedConverter, > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > > > private String prefix; > > > > > > > > > private String suffix; > > > > > > > > > @@ -161,4 +164,19 @@ > > > > > > > > > public void > > > setShowNullValues(boolean > > > > > > > > showNullValues) { > > > > > > > > > this.showNullValues = > > > > > > > > showNullValues; > > > > > > > > > } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > + protected boolean > > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > > destinationClass, sourceClass); > > > > > > > > > + } > > > > > > > > > + > > > > > > > > > + /** > > > > > > > > > + * Get the intermediate class > > > passed > > > > > to > > > > > > > > the text converter. > > > > > > > > > + * @return > > > > > > > > > + */ > > > > > > > > > + protected Class > > > > > getIntermediateClass() { > > > > > > > > > + return > > > StringBuffer.class; > > > > > > > > > + } > > > > > > > > > } > > > > > > > > > Index: > > > > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > > --- > > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > (revision 365) > > > > > > > > > +++ > > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > (working copy) > > > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > > > import java.lang.reflect.Method; > > > > > > > > > import java.math.BigDecimal; > > > > > > > > > import java.math.BigInteger; > > > > > > > > > +import java.util.Comparator; > > > > > > > > > import java.util.HashMap; > > > > > > > > > import java.util.HashSet; > > > > > > > > > import java.util.Iterator; > > > > > > > > > @@ -69,6 +70,31 @@ > > > > > > > > > } > > > > > > > > > } > > > > > > > > > > > > > > > > > > + private static class > > > > > > > NarrownessComparator > > > > > > > > implements Comparator { > > > > > > > > > + /** > > > > > > > > > + * {@inheritDoc} > > > > > > > > > + */ > > > > > > > > > + public int > > > compare(Object > > > > > arg0, > > > > > > > > Object arg1) { > > > > > > > > > + if (arg0 == > > > arg1) { > > > > > > > > > + return > > > 0; > > > > > > > > > + } > > > > > > > > > + Class c0 = > > > > > > > get... [truncated message content] |
From: Matt S. <mat...@sp...> - 2008-01-25 21:42:05
|
Oh boy, it's an Apache pop quiz! If I remember correctly, I am +0 to indicate I support the feature's addition, but I do not plan on actively working on it myself. Just to remind you, I believe I have already fixed the issue that ImpreciseTransformer is intended to address by ensuring order of components is always maintained. However, I see no problem with having 2 alternative solutions to the issue. Matt On Jan 25, 2008 2:59 PM, Matt Benson <gud...@ya...> wrote: > Where did you end up on the ImpreciseTransformer idea? > +1, -1, or +0? > > -Matt > > --- Matt Sgarlata <mat...@sp...> > wrote: > > > I see what you mean. I prefer ImpreciseTransformer > > to PrecisionTransformer > > because of the difficulty of assigning a numeric > > value for the degree of > > precision. I think that assignment is going to end > > up arbitrary and > > confusing pretty quickly. ImpreciseTransformer also > > would probably make the > > logic for determining the conversion path simpler. > > > > In terms of using different paths for different > > source and destination > > combos, I think perhaps the best solution in such a > > case would be to just > > make a bunch of individual AssemblerCopiers with > > individual paths, and then > > add them all together using the > > SimpleDelegatingTransformer. > > > > Matt > > > > On Jan 10, 2008 12:14 PM, Matt Benson > > <gud...@ya...> wrote: > > > > > You have a point, though I guess my aim in > > avoiding > > > such a thing was that--usually--the path is simple > > > enough to determine given source and dest classes. > > > Secondly, you might use a different path depending > > on > > > available source/dest combos, so the configuration > > > might be a little more complex. :| As for where > > > converters with awareness of "precision" might be > > > useful, I can't say that I know of another context > > > right now, but at the very least I would say it > > might > > > be useful knowledge for both number and text > > types. > > > > > > -Matt > > > > > > --- Matt Sgarlata > > <mat...@sp...> > > > wrote: > > > > > > > I agree, that does sound like it could end up > > being > > > > somewhat arbitrary. I > > > > know the original impetus for this was that > > > > configuration of the > > > > ChainedTransformer could be a real pain in the > > neck. > > > > Are there other > > > > situations where the information provided by > > > > ImplicitTransformer or > > > > PrecisionTransformer might be useful? I guess > > what > > > > I'm getting at here is, > > > > what is the requirement we are trying to solve? > > > > Perhaps if we think about > > > > it in a new way a different solution will > > present > > > > itself. > > > > > > > > Perhaps an alternative could be to introduce a > > new > > > > setTransformationPath(Class[] path) method to > > the > > > > ChainedTransformer. That > > > > would make configuration a snap, even if you > > were > > > > trying to use dependency > > > > injection for the configuration. > > > > > > > > Matt S > > > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > More on this: what do you think about the > > concept > > > > of > > > > > something like a PrecisionTransformer that > > returns > > > > a > > > > > float precision from 0.0 to 1.0 given a > > > > > destinationClass and a sourceClass? These > > might > > > > be > > > > > somewhat arbitrary, or calculated (like with > > > > numeric > > > > > types), but they might allow a little more > > > > > informedness on the part of the consumer. > > > > > > > > > > -Matt B > > > > > > > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > > <mat...@sp...> > > > > > > wrote: > > > > > > > > > > > > > I have been thinking more about this > > approach, > > > > and > > > > > > > it's really starting to > > > > > > > grow on me. I do have one concern though, > > can > > > > > > this > > > > > > > approach be extended to > > > > > > > Copiers? For example, a Map -> Object > > copy > > > > could > > > > > > > probably be considered an > > > > > > > imprecise transformation because the Map > > may > > > > have > > > > > > > more keys than the Object > > > > > > > has properties. > > > > > > > > > > > > I thought about this as well. It could be > > done; > > > > it > > > > > > might be slightly complex calculating the > > > > > > "precision" > > > > > > of a PropertyNameMatchingCopier--I would > > think > > > > an > > > > > > explicitly specified PNMatchingC would be > > > > precise; > > > > > > an > > > > > > imprecise one would be one using property > > name > > > > > > discovery and where the properties of the > > source > > > > are > > > > > > not all available on the destination. > > > > There--the > > > > > > hard > > > > > > part of that one is over. :) I will work > > on > > > > > > ImpreciseConverter -> ImpreciseTransformer > > > > extends > > > > > > Transformer and other semantic changes as > > time > > > > > > permits. Your ordering changes are, I > > expect, > > > > fine > > > > > > by > > > > > > me as well. :) > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > In addition to your approach, I also like > > the > > > > idea > > > > > > > of cleaning up the > > > > > > > internal implementation in Morph so that > > > > ordering > > > > > > of > > > > > > > source and destination > > > > > > > classes is preserved for the following > > > > reasons: > > > > > > > 1) for at least some portion of users, > > setting > > > > the > > > > > > > order of source and > > > > > > > destination classes will make sense as an > > > > > > indication > > > > > > > of the transformer's > > > > > > > preferences for performing transformations > > (so > > > > for > > > > > > > this class of users, > > > > > > > creating new transformers that play nicely > > > > with > > > > > > the > > > > > > > ChainedTransformerTestCase will be > > simpler) > > > > > > > 2) I think a general change from using > > > > HashSets to > > > > > > > ordered sets in Morph's > > > > > > > implementation will mean transformations > > > > happen > > > > > > more > > > > > > > consistently across > > > > > > > JVMs and across time on the same JVM, > > leading > > > > to a > > > > > > > more stable platform > > > > > > > > > > > > > > So, what I did is I basically went through > > the > > > > > > Morph > > > > > > > codebase and replaced > > > > > > > HashSets with ordered sets (preference > > order > > > > is: > > > > > > JDK > > > > > > > 1.4 LinkedHashSet, > > > > > > > Commons-collections ListOrderedSet, copy > > of > > > > > > > ListOrderedSet in > > > > > > > net.sf.morph.util). I was never able to > > > > modify > > > > > > the > > > > > > > ChainedTransformerTestCase so that it > > > > consistently > > > > > > > threw an error. However, > > > > > > > after working on the test case long > > enough, > > > > > > > eventually something changed in > > > > > > > my environment so that the test started to > > > > fail. > > > > > > I > > > > > > > did my change of > > > > > > > HashSets to ordered sets, and that was > > able to > > > > fix > > > > > > > the broken test. > > > > > > > > > > > > > > I checked in my changes for you to take a > > look > > > > > > at... > > > > > > > > > > > > > > Matt S > > > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > > Be a better friend, newshound, and > > > > > > > > know-it-all with Yahoo! Mobile. Try it > > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > (revision 357) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > (working copy) > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > /* > > > > > > > > - * Copyright 2004-2005, 2007 the > > original > > > > > > author > > > > > > > or authors. > > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > > original > > > > > > > author or authors. > > > > > > > > * > > > > > > > > * Licensed under the Apache License, > > > > Version > > > > > > 2.0 > > > > > > > (the "License"); you may > > > > > > > > not > > > > > > > > * use this file except in compliance > > with > > > > the > > > > > > > License. You may obtain a > > > > > > > > copy of > > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > import > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > import > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > net.sf.morph.transform.NodeCopier; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > net.sf.morph.transform.Transformer; > > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > > * @since Dec 12, 2004 > > > > > > > > */ > > > > > > > > public class > > SimpleDelegatingTransformer > > > > > > extends > > > > > > > BaseCompositeTransformer > > > > > > > > implements > > > > > > > > - SpecializableComposite, > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > DecoratedCopier, DecoratedConverter, > > > > Cloneable { > > > > > > > > + SpecializableComposite, > > > > > > > ExplicitTransformer, Transformer, > > > > > > > > DecoratedCopier, > > > > > > > > + DecoratedConverter, > > > > Cloneable, > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > //TODO extract > > > > BaseDelegatingTransformer > > > > > > > with pluggable delegate > > > > > > > > selection > > > > > > > > > > > > > > > > - > > > > > > > > private static class > > MapThreadLocal > > > > > > extends > > > > > > > ThreadLocal { > > > > > > > > protected Object > > > > initialValue() { > > > > > > > > return new > > HashMap(); > > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > > } > > > > > > > > > > > > > > > > private Specializer specializer; > > > > > > > > + private boolean > > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > > > private transient ThreadLocal > > > > > > > > visitedSourceToDestinationMapThreadLocal > > = > > > > new > > > > > > > MapThreadLocal(); > > > > > > > > private transient ThreadLocal > > > > > > > stackDepthThreadLocal = new > > > > > > > > StackDepthThreadLocal(); > > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > + */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > > (getTransformer(destinationClass, > > > > > > > > + > > > > sourceClass), > > > > > > > destinationClass, > > > > > > > > sourceClass); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > > > > */ > > > > > > > > protected Class[] > > > > getSourceClassesImpl() > > > > > > > throws Exception { > > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > > * if no suitable > > > > transformer > > > > > > > could be found > > > > > > > > */ > > > > > > > > private Transformer > > > > getTransformer(Class > > > > > > > transformerType, Class > > > > > > > > destinationClass, Class sourceClass) > > throws > > > > > > > TransformationException { > > > > > > > > + Transformer candidate = > > > > null; > > > > > > > > for (int i = 0; i < > > > > > > > components.length; i++) { > > > > > > > > // if the > > transformer > > > > is > > > > > > > the correct type > > > > > > > > Transformer > > > > transformer = > > > > > > > (Transformer) > > > > > > > > components[i]; > > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > > // if the > > > > > > > transformer is capable of > > > > > > > > performing the transformation > > > > > > > > if > > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > > > transformer, > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > + > > if > > > > > > > (isPreferPreciseTransformers() > > > > > > > > + > > > > > > > > > > > > > && candidate == > > > > > > > > null > > > > > > > > + > > > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > > + > > > > > > > > destinationClass, sourceClass)) { > > > > > > > > + > > > > > > > candidate = transformer; > > > > > > > > + > > > > > > > continue; > > > > > > > > + > > } > > > > > > > > > > if > > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > > > return > > > > > > > transformer; > > > > > > > > } > > > > > > > > } > > > > > > > > - > > > > > > > > + if (candidate != > > > > null) { > > > > > > > > + return > > > > > > candidate; > > > > > > > > + } > > > > > > > > } > > > > > > > > throw new > > > > > > TransformationException( > > > > > > > > "Could not find a > > > > > > > transformer that can transform > > > > > > > > objects of " > > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > > source); > > > > > > > > } > > > > > > > > > > > > > > > > + /** > > > > > > > > + * Get the > > > > preferPreciseTransformers. > > > > > > > > + * @return boolean > > > > > > > > + */ > > > > > > > > + public boolean > > > > > > > isPreferPreciseTransformers() { > > > > > > > > + return > > > > > > preferPreciseTransformers; > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * Set the > > > > preferPreciseTransformers. > > > > > > > Default false. > > > > > > > > + * @param > > preferPreciseTransformers > > > > the > > > > > > > boolean to set > > > > > > > > + */ > > > > > > > > + public void > > > > > > > setPreferPreciseTransformers(boolean > > > > > > > > preferPreciseTransformers) { > > > > > > > > + > > > > this.preferPreciseTransformers = > > > > > > > > preferPreciseTransformers; > > > > > > > > + } > > > > > > > > + > > > > > > > > } > > > > > > > > \ No newline at end of file > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > (revision 358) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > (working copy) > > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > > } > > > > > > > > } > > > > > > > > > > > > > > > > + /** > > > > > > > > + * Implementation of > > > > > > isImpreciseConversion > > > > > > > > + * @param destinationClass > > > > > > > > + * @param sourceClass > > > > > > > > + * @return > > > > > > > > + */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return destinationClass > > == > > > > null > > > > > > && > > > > > > > sourceClass != null; > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * Learn whether the specified > > > > > > conversion > > > > > > > yields an imprecise > > > > > > > > result. > > > > > > > > + * @param destinationClass > > > > > > > > + * @param sourceClass > > > > > > > > + * @return boolean > > > > > > > > + */ > > > > > > > > + public final boolean > > > > > > > isImpreciseConversion(Class > > destinationClass, > > > > > > > > Class sourceClass) { > > > > > > > > + try { > > > > > > > > + return > > > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > > sourceClass); > > > > > > > > + } catch (Exception e) { > > > > > > > > + if (e instanceof > > > > > > > RuntimeException && > > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > > + throw > > > > > > > (RuntimeException) e; > > > > > > > > + } > > > > > > > > + throw new > > > > > > > TransformationException("Could not > > > > > > > > determine if conversion of " > > > > > > > > + > > + > > > > > > > sourceClass + " to " + > > > > > > > > destinationClass > > > > > > > > + > > + " > > > > > > > results in a loss of > > > > > > > > precision", e); > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > // property getters and setters > > > > > > > > > > > > > > > > /** > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > (revision 357) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > (working copy) > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > /* > > > > > > > > - * Copyright 2004-2005, 2007 the > > original > > > > > > author > > > > > > > or authors. > > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > > original > > > > > > > author or authors. > > > > > > > > * > > > > > > > > * Licensed under the Apache License, > > > > Version > > > > > > 2.0 > > > > > > > (the "License"); you may > > > > > > > > not > > > > > > > > * use this file except in compliance > > with > > > > the > > > > > > > License. You may obtain a > > > > > > > > copy of > > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > > package > > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > > +import java.util.Iterator; > > > > > > > > import java.util.List; > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > import > > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > > import > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > net.sf.morph.transform.Transformer; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > > * @since Nov 24, 2004 > > > > > > > > */ > > > > > > > > public class ChainedTransformer extends > > > > > > > BaseCompositeTransformer > > > > > > > > implements > > > > > > > > - DecoratedConverter, > > > > > > > DecoratedCopier, ExplicitTransformer { > > > > > > > > + DecoratedConverter, > > > > > > > DecoratedCopier, ExplicitTransformer, > > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > > } > > > > > > > > > > > > > > > > /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + List conversionPath = > > > > > > > getConversionPath(destinationClass, > > > > > > > > sourceClass); > > > > > > > > + return > > > > > > !isPrecise(conversionPath, > > > > > > > sourceClass, 0); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > * Get the converter used when > > using > > > > a > > > > > > > ChainedTransformer as a > > > > > > > > Copier. > > > > > > > > * @return > > > > > > > > */ > > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > > throw new > > > > > > > TransformationException(destinationClass, > > > > > > > > sourceType, null, > > > > > > > > > > > > "Chained > > > > > > > conversion path could not > > > > > > > > be determined"); > > > > > > > > } > > > > > > > > + log.debug("Using chained > > > > > > > conversion path " + > > > > > > > > conversionPath); > > > > > > > > Object o = source; > > > > > > > > for (int i = 0; i < > > > > > > > conversionPath.size(); i++) { > > > > > > > > o = > > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > > conversionPath.get(i), o, locale); > > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > > throw new > > > > > > > TransformationException(destinationClass, > > > > > > > > source, null, > > > > > > > > > > > > "Chained > > > > > > > conversion path could not > > > > > > > > be determined"); > > > > > > > > } > > > > > > > > + log.debug("Using chained > > > > > > > conversion path " + > > > > > > > > conversionPath); > > > > > > > > Object last = > > > > > > > getCopyConverter().convert((Class) > > > > > > > > conversionPath.get(chain.length - 2), > > > > source, > > > > > > > locale); > > > > > > > > ((Copier) > > > > > > copier).copy(destination, > > > > > > > last, locale); > > > > > > > > } > > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > > * @return List > > > > > > > > */ > > > > > > > > protected List > > > > getConversionPath(Class > > > > > > > destinationType, Class > > > > > > > > sourceType) { > > > > > > > > - if (sourceType != null) > > { > > > > > > > > - List withoutNull > > = > > > > > > > > getConversionPath(destinationType, > > > > sourceType, > > > > > > 0, > > > > > > > false); > > > > > > > > - if (withoutNull > > != > > > > null) > > > > > > { > > > > > > > > - return > > > > > > > withoutNull; > > > > > > > > - } > > > > > > > > - } > > > > > > > > - return > > > > > > > getConversionPath(destinationType, > > sourceType, > > > > 0, > > > > > > > > true); > > > > > > > > + return > > > > > > > getConversionPath(destinationType, > > sourceType, > > > > 0); > > > > > > > > } > > > > > > > > > > > > > > > > /** > > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > > * @param allowNull > > > > > > > > * @return List > > > > > > > > */ > > > > > > > > - private List > > getConversionPath(Class > > > > > > > destinationType, Class > > > > > > > > sourceType, int index, boolean > > allowNull) { > > > > > > > > + private List > > getConversionPath(Class > > > > > > > destinationType, Class > > > > > > > > sourceType, int index) { > > > > > > > > Transformer[] chain = > > > > getChain(); > > > > > > > > Transformer c = > > chain[index]; > > > > > > > > if (index + 1 == > > > > chain.length) { > > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > > } > > > > > > > > return null; > > > > > > > > } > > > > > > > > + List possibleResult = > > null; > > > > > > > > Class[] available = > > > > > > > c.getDestinationClasses(); > > > > > > > > for (int i = 0; i < > > > > > > > available.length; i++) { > > > > > > > > - if (available[i] > > == > > > > null > > > > > > > && !allowNull) { > > > > > > > > - > > continue; > > > > > > > > - } > > > > > > > > if > > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > > available[i], sourceType)) { > > > > > > > > - List > > tail = > > > > > > > > getConversionPath(destinationType, > > > > available[i], > > > > > > > index + 1, allowNull); > > > > > > > > + List > > tail = > > > > > > > > getConversionPath(destinationType, > > > > available[i], > > > > > > > index + 1); > > > > > > > > if (tail > > != > > > > null) > > > > > > { > > > > > > > > > > > > > > tail.add(0, > > > > > > > available[i]); > > > > > > > > - > > > > return > > > > > > > tail; > > > > > > > > + > > if > > > > > > > (isPrecise(tail, sourceType, > > > > > > > > index)) { > > > > > > > > + > > > > > > > return tail; > > > > > > > > + > > } > > > > > > > > + > > > > > > > possibleResult = tail; > > > > > > > > } > > > > > > > > } > > > > > > > > } > > > > > > > > - return null; > > > > > > > > + return possibleResult; > > > > > > > > } > > > > > > > > > > > > > > > > + private boolean isPrecise(List > > > > > > > conversionPath, Class sourceType, > > > > > > > > int index) { > > > > > > > > + Transformer[] chain = > > > > > > getChain(); > > > > > > > > + Class currentSource = > > > > > > sourceType; > > > > > > > > + int i = 0; > > > > > > > > + for (Iterator iter = > > > > > > > conversionPath.iterator(); > > > > > > > > iter.hasNext(); i++) { > > > > > > > > + Class > > currentDest = > > > > > > > (Class) iter.next(); > > > > > > > > + if > > > > > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > > + i], currentDest, > > > > > > > > + > > > > > > > currentSource)) { > > > > > > > > + return > > > > false; > > > > > > > > + } > > > > > > > > + currentSource = > > > > > > > currentDest; > > > > > > > > + } > > > > > > > > + return true; > > > > > > > > + } > > > > > > > > + > > > > > > > > /** > > > > > > > > * Get the components array > > narrowed > > > > to a > > > > > > > Transformer[]. > > > > > > > > * @return Transformer[] > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > (revision > > > > > > > > 0) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > (revision > > > > > > > > 0) > > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > > +/* > > > > > > > > + * Copyright 2008 the original author > > or > > > > > > authors. > > > > > > > > + * > > > > > > > > + * Licensed under the Apache License, > > > > Version > > > > > > 2.0 > > > > > > > (the "License"); you > > > > > > > > may not > > > > > > > > + * use this file except in compliance > > with > > > > the > > > > > > > License. You may obtain a > > > > > > > > copy of > > > > > > > > + * the License at > > > > > > > > + * > > > > > > > > + * > > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > > + * > > > > > > > > + * Unless required by applicable law or > > > > agreed > > > > > > to > > > > > > > in writing, software > > > > > > > > + * distributed under the License is > > > > distributed > > > > > > > on an "AS IS" BASIS, > > > > > > > > WITHOUT > > > > > > > > + * WARRANTIES OR CONDITIONS OF ANY > > KIND, > > > > either > > > > > > > express or implied. See > > > > > > > > the > > > > > > > > + * License for the specific language > > > > governing > > > > > > > permissions and > > > > > > > > limitations under > > > > > > > > + * the License. > > > > > > > > + */ > > > > > > > > +package net.sf.morph.transform; > > > > > > > > + > > > > > > > > +/** > > > > > > > > + * Defines a converter whose operation > > may > > > > > > result > > > > > > > in a loss of data > > > > > > > > precision. > > > > > > > > + * > > > > > > > > + * @author mbenson > > > > > > > > + * @since Morph 1.0.2 > > > > > > > > + */ > > > > > > > > +public interface ImpreciseConverter > > extends > > > > > > > Converter { > > > > > > > > + /** > > > > > > > > + * Learn whether the specified > > > > > > conversion > > > > > > > might yield an imprecise > > > > > > > > result. > > > > > > > > + * @param destinationClass > > > > > > > > + * @param sourceClass > > > > > > > > + * @return boolean > > > > > > > > + */ > > > > > > > > + boolean > > isImpreciseConversion(Class > > > > > > > destinationClass, Class > > > > > > > > sourceClass); > > > > > > > > +} > > > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > > Name: svn:eol-style > > > > > > > > + native > > > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > (revision 362) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > +import > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > /** > > > > > > > > * Converts an object to a textual > > > > > > representation > > > > > > > by calling the object's > > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Dec 24, 2004 > > > > > > > > */ > > > > > > > > -public class ObjectToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > +public class ObjectToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > destinationClass, String.class); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > protected boolean > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > return true; > > > > > > > > } > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > (revision 361) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > > import > > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > > > /** > > > > > > > > - * Converts basic text types into > > primtive > > > > > > > numbers or {@link > > > > > > > > java.lang.Number} > > > > > > > > + * Converts basic text types into > > primitive > > > > > > > numbers or {@link > > > > > > > > java.lang.Number} > > > > > > > > * objects. > > > > > > > > * > > > > > > > > * @author Matt Sgarlata > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > (revision 363) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > +import > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > /** > > > > > > > > * Converts {@link java.lang.Number}s > > into > > > > basic > > > > > > > text types ({@link > > > > > > > > java.lang.String}, > > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Jan 26, 2006 > > > > > > > > */ > > > > > > > > -public class NumberToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > +public class NumberToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, > > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > > private Converter > > numberConverter; > > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > > } > > > > > > > > > > > > > > > > /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > destinationClass, String.class); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > * Get the number converter used > > by > > > > this > > > > > > > NumberToTextConverter. > > > > > > > > * @return Converter > > > > > > > > */ > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > (revision 360) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > +import > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > /** > > > > > > > > * Converts the basic time types ({@link > > > > > > > java.util.Date} and > > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Dec 31, 2004 > > > > > > > > */ > > > > > > > > -public class TimeToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > +public class TimeToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, > > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > > > private DateFormat dateFormat; > > > > > > > > private Converter timeConverter; > > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > destinationClass, String.class); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > protected boolean > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > return true; > > > > > > > > } > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > (revision 357) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > import > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > import net.sf.morph.util.ClassUtils; > > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > > * @since Jan 2, 2005 > > > > > > > > */ > > > > > > > > public class TextConverter extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, > > > > > > > > - ExplicitTransformer { > > > > > > > > + ExplicitTransformer, > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > private static final Class > > > > CHAR_SEQUENCE > > > > > > = > > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > > ClassUtils > > > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > > s.add(Character.class); > > > > > > > > s.add(char.class); > > > > > > > > s.add(null); > > > > > > > > - if (CHAR_SEQUENCE != > > null) { > > > > > > > > - > > > > s.add(CHAR_SEQUENCE); > > > > > > > > - try { > > > > > > > > - > > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > > StringBuffer.class.getConstructor(new > > > > Class[] { > > > > > > > String.class })); > > > > > > > > - } catch > > (Exception > > > > e) { > > > > > > > > - //nope > > > > > > > > - } > > > > > > > > - } > > > > > > > > + s.add(CHAR_SEQUENCE); > > > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > > = > > > > > > > (Class[]) s.toArray(new > > > > > > > > Class[s.size()]); > > > > > > > > } > > > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > > } > > > > > > > > return new > > > > > > > Character(string.charAt(0)); > > > > > > > > } > > > > > > > > - if (destinationClass == > > > > > > > String.class) { > > > > > > > > + if (destinationClass == > > > > > > > String.class > > > > > > > > + || > > > > > > > (destinationClass == CHAR_SEQUENCE && > > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > > return string; > > > > > > > > } > > > > > > > > if (destinationClass == > > > > > > > byte[].class) { > > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + if > > > > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > > sourceClass)) { > > > > > > > > + return true; > > > > > > > > + } > > > > > > > > + return > > > > isChar(destinationClass) > > > > > > && > > > > > > > !isChar(sourceClass); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > protected boolean > > > > > > > isAutomaticallyHandlingNulls() { > > > > > > > > return !isEmptyNull(); > > > > > > > > } > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > (revision 362) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -20,8 +20,10 @@ > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > +import > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > /** > > > > > > > > * Converts boolean values to text > > values. > > > > > > > Subclasses can build in > > > > > > > > support for > > > > > > > > @@ -32,10 +34,10 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Jan 9, 2005 > > > > > > > > */ > > > > > > > > -public class BooleanToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > - > > > > > > > > +public class BooleanToTextConverter > > extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > + > > > > > > > > private static final Class[] > > > > SOURCE_TYPES > > > > > > = > > > > > > > { Boolean.class, > > > > > > > > boolean.class }; > > > > > > > > - > > > > > > > > + > > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > > > /** > > > > > > > > @@ -93,9 +95,16 @@ > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > destinationClass, String.class); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > protected boolean > > > > > > > isWrappingRuntimeExceptions() { > > > > > > > > return true; > > > > > > > > - } > > > > > > > > + } > > > > > > > > > > > > > > > > /** > > > > > > > > * Get the text converter used by > > > > this > > > > > > > BaseToPrettyTextConverter. > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > (revision 363) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > > > > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > > > import > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > > @@ -31,8 +32,8 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Dec 14, 2004 > > > > > > > > */ > > > > > > > > -public class NumberConverter extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter { > > > > > > > > - > > > > > > > > +public class NumberConverter extends > > > > > > > BaseTransformer implements > > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > + > > > > > > > > private static final Class[] > > > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > > > Number.class, byte.class, > > > > > > > short.class, int.class, > > > > > > > > long.class, > > > > > > > > float.class, > > double.class, > > > > null > > > > > > > > @@ -116,9 +117,20 @@ > > > > > > > > /** > > > > > > > > * {@inheritDoc} > > > > > > > > */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > > > sourceClass) > > > > > > > > + || > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > > > + > > > > > > > sourceClass) < 0; > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > protected Object > > convertImpl(Class > > > > > > > destinationClass, Object source, > > > > > > > > Locale locale) throws > > > > Exception { > > > > > > > > - > > > > > > > > + if (destinationClass == > > > > null) { > > > > > > > > + return null; > > > > > > > > + } > > > > > > > > if > > > > > > (destinationClass.isPrimitive() > > > > > > > && source == null) { > > > > > > > > throw new > > > > > > > TransformationException(destinationClass, > > > > > > > > source); > > > > > > > > } > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > (revision 362) > > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > (working copy) > > > > > > > > @@ -18,7 +18,9 @@ > > > > > > > > import net.sf.morph.Defaults; > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import > > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > > > > +import > > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > > > /** > > > > > > > > * Base class for converts that convert > > > > objects > > > > > > to > > > > > > > a pretty > > > > > > > > programmer-friendly > > > > > > > > @@ -27,7 +29,8 @@ > > > > > > > > * @author Matt Sgarlata > > > > > > > > * @since Feb 15, 2005 > > > > > > > > */ > > > > > > > > -public abstract class > > > > BaseToPrettyTextConverter > > > > > > > extends > > > > > > > > BaseReflectorTransformer implements > > > > > > > DecoratedConverter { > > > > > > > > +public abstract class > > > > BaseToPrettyTextConverter > > > > > > > extends > > > > > > > > BaseReflectorTransformer > > > > > > > > + implements > > > > DecoratedConverter, > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > > > private String prefix; > > > > > > > > private String suffix; > > > > > > > > @@ -161,4 +164,19 @@ > > > > > > > > public void > > setShowNullValues(boolean > > > > > > > showNullValues) { > > > > > > > > this.showNullValues = > > > > > > > showNullValues; > > > > > > > > } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > + protected boolean > > > > > > > isImpreciseConversionImpl(Class > > > > > > > > destinationClass, Class sourceClass) { > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > > destinationClass, sourceClass); > > > > > > > > + } > > > > > > > > + > > > > > > > > + /** > > > > > > > > + * Get the intermediate class > > passed > > > > to > > > > > > > the text converter. > > > > > > > > + * @return > > > > > > > > + */ > > > > > > > > + protected Class > > > > getIntermediateClass() { > > > > > > > > + return > > StringBuffer.class; > > > > > > > > + } > > > > > > > > } > > > > > > > > Index: > > > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > (revision 365) > > > > > > > > +++ > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > (working copy) > > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > > import java.lang.reflect.Method; > > > > > > > > import java.math.BigDecimal; > > > > > > > > import java.math.BigInteger; > > > > > > > > +import java.util.Comparator; > > > > > > > > import java.util.HashMap; > > > > > > > > import java.util.HashSet; > > > > > > > > import java.util.Iterator; > > > > > > > > @@ -69,6 +70,31 @@ > > > > > > > > } > > > > > > > > } > > > > > > > > > > > > > > > > + private static class > > > > > > NarrownessComparator > > > > > > > implements Comparator { > > > > > > > > + /** > > > > > > > > + * {@inheritDoc} > > > > > > > > + */ > > > > > > > > + public int > > compare(Object > > > > arg0, > > > > > > > Object arg1) { > > > > > > > > + if (arg0 == > > arg1) { > > > > > > > > + return > > 0; > > > > > > > > + } > > > > > > > > + Class c0 = > > > > > > getType(arg0); > > > > > > > > + Class c1 = > > > > > > getType(arg1); > > > > > > > > + if (c0 == c1 || > > c0 > > > > == > > > > > > null > > > > > > > || c1 == null) { > > > > > > > > + return > > 0; > > > > > > > > + } > > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > > > > + } > > > > > > > > + > > > > > > > > + private Class > > getType(Object > > > > o) > > > > > > { > > > > > > > > + if > > > > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > > > > + return > > > > (Class) > > > > > > o; > > > > > > > > + } > > > > > > > > + Class test = > > > > > > > ClassUtils.getClass(o); > > > > > > > > + return > > > > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? > > test > > > > > > > > : null; > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > /** > > > > > > > > * A Map of BigDecimals keyed by > > > > Class > > > > > > that > > > > > > > indicate the maximum > > > > > > > > value that > > > > > > > > * the given (Number) Class may > > taken > > > > on. > > > > > > > > @@ -80,11 +106,16 @@ > > > > > > > > * the given (Number) Class may > > taken > > > > on. > > > > > > > > */ > > > > > > > > public static final Map > > > > > > MINIMUMS_FOR_TYPES; > > > > > > > > - > > > > > > > > - public static final Map > > > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > > > > > > > - public static final Map > > > > > > NUMBER_FACTORIES; > > > > > > > > + /** > > > > > > > > + * Comparator of class/object > > type > > > > > > > narrowness. > > > > > > > > + */ > > > > > > > > + public static final Comparator > > > > > > > NARROWNESS_COMPARATOR = new > > > > > > > > NarrownessComparator(); > > > > > > > > > > > > > > > > + private static final Map > > > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > + > > > > > > > > + private static final Map > > > > > > NUMBER_FACTORIES; > > > > > > > > + > > > > > > > > /** > > > > > > > > * Used by {@link > > > > > > > NumberUtils#isNumber(Class)}. > > > > > > > > */ > > > > > > > > Index: > > > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > > --- > > > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > (revision 357) > > > > > > > > +++ > > > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > (working copy) > > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > > /* > > > > > > > > - * Copyright 2004-2005, 2007 the > > original > > > > > > author > > > > > > > or authors. > > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > > original > > > > > > > author or authors. > > > > > > > > * > > > > > > > > * Licensed under the Apache License, > > > > Version > > > > > > 2.0 > > > > > > > (the "License"); you may > > > > > > > > not > > > > > > > > * use this file except in compliance > > with > > > > the > > > > > > > License. You may obtain a > > > > > > > > copy of > > > > > > > > @@ -26,6 +26,7 @@ > > > > > > > > import > > net.sf.morph.transform.Converter; > > > > > > > > import net.sf.morph.transform.Copier; > > > > > > > > import > > > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > > +import > > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > > import > > > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > > import > > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > > > > } > > > > > > > > > > > > > > > > /** > > > > > > > > + * Learn whether > > > > > > > <code>transformer... [truncated message content] |
From: Matt B. <gud...@ya...> - 2008-01-25 19:59:22
|
Where did you end up on the ImpreciseTransformer idea? +1, -1, or +0? -Matt --- Matt Sgarlata <mat...@sp...> wrote: > I see what you mean. I prefer ImpreciseTransformer > to PrecisionTransformer > because of the difficulty of assigning a numeric > value for the degree of > precision. I think that assignment is going to end > up arbitrary and > confusing pretty quickly. ImpreciseTransformer also > would probably make the > logic for determining the conversion path simpler. > > In terms of using different paths for different > source and destination > combos, I think perhaps the best solution in such a > case would be to just > make a bunch of individual AssemblerCopiers with > individual paths, and then > add them all together using the > SimpleDelegatingTransformer. > > Matt > > On Jan 10, 2008 12:14 PM, Matt Benson > <gud...@ya...> wrote: > > > You have a point, though I guess my aim in > avoiding > > such a thing was that--usually--the path is simple > > enough to determine given source and dest classes. > > Secondly, you might use a different path depending > on > > available source/dest combos, so the configuration > > might be a little more complex. :| As for where > > converters with awareness of "precision" might be > > useful, I can't say that I know of another context > > right now, but at the very least I would say it > might > > be useful knowledge for both number and text > types. > > > > -Matt > > > > --- Matt Sgarlata > <mat...@sp...> > > wrote: > > > > > I agree, that does sound like it could end up > being > > > somewhat arbitrary. I > > > know the original impetus for this was that > > > configuration of the > > > ChainedTransformer could be a real pain in the > neck. > > > Are there other > > > situations where the information provided by > > > ImplicitTransformer or > > > PrecisionTransformer might be useful? I guess > what > > > I'm getting at here is, > > > what is the requirement we are trying to solve? > > > Perhaps if we think about > > > it in a new way a different solution will > present > > > itself. > > > > > > Perhaps an alternative could be to introduce a > new > > > setTransformationPath(Class[] path) method to > the > > > ChainedTransformer. That > > > would make configuration a snap, even if you > were > > > trying to use dependency > > > injection for the configuration. > > > > > > Matt S > > > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > More on this: what do you think about the > concept > > > of > > > > something like a PrecisionTransformer that > returns > > > a > > > > float precision from 0.0 to 1.0 given a > > > > destinationClass and a sourceClass? These > might > > > be > > > > somewhat arbitrary, or calculated (like with > > > numeric > > > > types), but they might allow a little more > > > > informedness on the part of the consumer. > > > > > > > > -Matt B > > > > > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > > > > > > > > > > --- Matt Sgarlata > > > > > <mat...@sp...> > > > > > wrote: > > > > > > > > > > > I have been thinking more about this > approach, > > > and > > > > > > it's really starting to > > > > > > grow on me. I do have one concern though, > can > > > > > this > > > > > > approach be extended to > > > > > > Copiers? For example, a Map -> Object > copy > > > could > > > > > > probably be considered an > > > > > > imprecise transformation because the Map > may > > > have > > > > > > more keys than the Object > > > > > > has properties. > > > > > > > > > > I thought about this as well. It could be > done; > > > it > > > > > might be slightly complex calculating the > > > > > "precision" > > > > > of a PropertyNameMatchingCopier--I would > think > > > an > > > > > explicitly specified PNMatchingC would be > > > precise; > > > > > an > > > > > imprecise one would be one using property > name > > > > > discovery and where the properties of the > source > > > are > > > > > not all available on the destination. > > > There--the > > > > > hard > > > > > part of that one is over. :) I will work > on > > > > > ImpreciseConverter -> ImpreciseTransformer > > > extends > > > > > Transformer and other semantic changes as > time > > > > > permits. Your ordering changes are, I > expect, > > > fine > > > > > by > > > > > me as well. :) > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > In addition to your approach, I also like > the > > > idea > > > > > > of cleaning up the > > > > > > internal implementation in Morph so that > > > ordering > > > > > of > > > > > > source and destination > > > > > > classes is preserved for the following > > > reasons: > > > > > > 1) for at least some portion of users, > setting > > > the > > > > > > order of source and > > > > > > destination classes will make sense as an > > > > > indication > > > > > > of the transformer's > > > > > > preferences for performing transformations > (so > > > for > > > > > > this class of users, > > > > > > creating new transformers that play nicely > > > with > > > > > the > > > > > > ChainedTransformerTestCase will be > simpler) > > > > > > 2) I think a general change from using > > > HashSets to > > > > > > ordered sets in Morph's > > > > > > implementation will mean transformations > > > happen > > > > > more > > > > > > consistently across > > > > > > JVMs and across time on the same JVM, > leading > > > to a > > > > > > more stable platform > > > > > > > > > > > > So, what I did is I basically went through > the > > > > > Morph > > > > > > codebase and replaced > > > > > > HashSets with ordered sets (preference > order > > > is: > > > > > JDK > > > > > > 1.4 LinkedHashSet, > > > > > > Commons-collections ListOrderedSet, copy > of > > > > > > ListOrderedSet in > > > > > > net.sf.morph.util). I was never able to > > > modify > > > > > the > > > > > > ChainedTransformerTestCase so that it > > > consistently > > > > > > threw an error. However, > > > > > > after working on the test case long > enough, > > > > > > eventually something changed in > > > > > > my environment so that the test started to > > > fail. > > > > > I > > > > > > did my change of > > > > > > HashSets to ordered sets, and that was > able to > > > fix > > > > > > the broken test. > > > > > > > > > > > > I checked in my changes for you to take a > look > > > > > at... > > > > > > > > > > > > Matt S > > > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > > <gud...@ya...> wrote: > > > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > > Be a better friend, newshound, and > > > > > > > know-it-all with Yahoo! Mobile. Try it > now. > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > (revision 357) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > (working copy) > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > /* > > > > > > > - * Copyright 2004-2005, 2007 the > original > > > > > author > > > > > > or authors. > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > > author or authors. > > > > > > > * > > > > > > > * Licensed under the Apache License, > > > Version > > > > > 2.0 > > > > > > (the "License"); you may > > > > > > > not > > > > > > > * use this file except in compliance > with > > > the > > > > > > License. You may obtain a > > > > > > > copy of > > > > > > > @@ -35,6 +35,7 @@ > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > import > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > import > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > net.sf.morph.transform.NodeCopier; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > > @@ -93,11 +94,11 @@ > > > > > > > * @since Dec 12, 2004 > > > > > > > */ > > > > > > > public class > SimpleDelegatingTransformer > > > > > extends > > > > > > BaseCompositeTransformer > > > > > > > implements > > > > > > > - SpecializableComposite, > > > > > > ExplicitTransformer, Transformer, > > > > > > > DecoratedCopier, DecoratedConverter, > > > Cloneable { > > > > > > > + SpecializableComposite, > > > > > > ExplicitTransformer, Transformer, > > > > > > > DecoratedCopier, > > > > > > > + DecoratedConverter, > > > Cloneable, > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > //TODO extract > > > BaseDelegatingTransformer > > > > > > with pluggable delegate > > > > > > > selection > > > > > > > > > > > > > > - > > > > > > > private static class > MapThreadLocal > > > > > extends > > > > > > ThreadLocal { > > > > > > > protected Object > > > initialValue() { > > > > > > > return new > HashMap(); > > > > > > > @@ -138,6 +139,7 @@ > > > > > > > } > > > > > > > > > > > > > > private Specializer specializer; > > > > > > > + private boolean > > > > > preferPreciseTransformers; > > > > > > > > > > > > > > private transient ThreadLocal > > > > > > > visitedSourceToDestinationMapThreadLocal > = > > > new > > > > > > MapThreadLocal(); > > > > > > > private transient ThreadLocal > > > > > > stackDepthThreadLocal = new > > > > > > > StackDepthThreadLocal(); > > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > + */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > TransformerUtils.isImpreciseConversion > > > > > > > (getTransformer(destinationClass, > > > > > > > + > > > sourceClass), > > > > > > destinationClass, > > > > > > > sourceClass); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > > > */ > > > > > > > protected Class[] > > > getSourceClassesImpl() > > > > > > throws Exception { > > > > > > > @@ -477,6 +487,7 @@ > > > > > > > * if no suitable > > > transformer > > > > > > could be found > > > > > > > */ > > > > > > > private Transformer > > > getTransformer(Class > > > > > > transformerType, Class > > > > > > > destinationClass, Class sourceClass) > throws > > > > > > TransformationException { > > > > > > > + Transformer candidate = > > > null; > > > > > > > for (int i = 0; i < > > > > > > components.length; i++) { > > > > > > > // if the > transformer > > > is > > > > > > the correct type > > > > > > > Transformer > > > transformer = > > > > > > (Transformer) > > > > > > > components[i]; > > > > > > > @@ -484,6 +495,13 @@ > > > > > > > // if the > > > > > > transformer is capable of > > > > > > > performing the transformation > > > > > > > if > > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > > > transformer, > > > > > > > destinationClass, sourceClass)) { > > > > > > > + > if > > > > > > (isPreferPreciseTransformers() > > > > > > > + > > > > > > > > > > > && candidate == > > > > > > > null > > > > > > > + > > > > > > > > > > > && > > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > > + > > > > > > > destinationClass, sourceClass)) { > > > > > > > + > > > > > > candidate = transformer; > > > > > > > + > > > > > > continue; > > > > > > > + > } > > > > > > > > if > > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > > > return > > > > > > transformer; > > > > > > > } > > > > > > > } > > > > > > > - > > > > > > > + if (candidate != > > > null) { > > > > > > > + return > > > > > candidate; > > > > > > > + } > > > > > > > } > > > > > > > throw new > > > > > TransformationException( > > > > > > > "Could not find a > > > > > > transformer that can transform > > > > > > > objects of " > > > > > > > @@ -612,4 +632,20 @@ > > > > > > > source); > > > > > > > } > > > > > > > > > > > > > > + /** > > > > > > > + * Get the > > > preferPreciseTransformers. > > > > > > > + * @return boolean > > > > > > > + */ > > > > > > > + public boolean > > > > > > isPreferPreciseTransformers() { > > > > > > > + return > > > > > preferPreciseTransformers; > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * Set the > > > preferPreciseTransformers. > > > > > > Default false. > > > > > > > + * @param > preferPreciseTransformers > > > the > > > > > > boolean to set > > > > > > > + */ > > > > > > > + public void > > > > > > setPreferPreciseTransformers(boolean > > > > > > > preferPreciseTransformers) { > > > > > > > + > > > this.preferPreciseTransformers = > > > > > > > preferPreciseTransformers; > > > > > > > + } > > > > > > > + > > > > > > > } > > > > > > > \ No newline at end of file > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > (revision 358) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > (working copy) > > > > > > > @@ -570,6 +570,35 @@ > > > > > > > } > > > > > > > } > > > > > > > > > > > > > > + /** > > > > > > > + * Implementation of > > > > > isImpreciseConversion > > > > > > > + * @param destinationClass > > > > > > > + * @param sourceClass > > > > > > > + * @return > > > > > > > + */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return destinationClass > == > > > null > > > > > && > > > > > > sourceClass != null; > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * Learn whether the specified > > > > > conversion > > > > > > yields an imprecise > > > > > > > result. > > > > > > > + * @param destinationClass > > > > > > > + * @param sourceClass > > > > > > > + * @return boolean > > > > > > > + */ > > > > > > > + public final boolean > > > > > > isImpreciseConversion(Class > destinationClass, > > > > > > > Class sourceClass) { > > > > > > > + try { > > > > > > > + return > > > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > > sourceClass); > > > > > > > + } catch (Exception e) { > > > > > > > + if (e instanceof > > > > > > RuntimeException && > > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > > + throw > > > > > > (RuntimeException) e; > > > > > > > + } > > > > > > > + throw new > > > > > > TransformationException("Could not > > > > > > > determine if conversion of " > > > > > > > + > + > > > > > > sourceClass + " to " + > > > > > > > destinationClass > > > > > > > + > + " > > > > > > results in a loss of > > > > > > > precision", e); > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > // property getters and setters > > > > > > > > > > > > > > /** > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > (revision 357) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > (working copy) > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > /* > > > > > > > - * Copyright 2004-2005, 2007 the > original > > > > > author > > > > > > or authors. > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > > author or authors. > > > > > > > * > > > > > > > * Licensed under the Apache License, > > > Version > > > > > 2.0 > > > > > > (the "License"); you may > > > > > > > not > > > > > > > * use this file except in compliance > with > > > the > > > > > > License. You may obtain a > > > > > > > copy of > > > > > > > @@ -16,6 +16,7 @@ > > > > > > > package > > > net.sf.morph.transform.transformers; > > > > > > > > > > > > > > import java.util.ArrayList; > > > > > > > +import java.util.Iterator; > > > > > > > import java.util.List; > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > import > > > net.sf.morph.transform.DecoratedCopier; > > > > > > > import > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > > import > > > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > > @@ -40,7 +42,7 @@ > > > > > > > * @since Nov 24, 2004 > > > > > > > */ > > > > > > > public class ChainedTransformer extends > > > > > > BaseCompositeTransformer > > > > > > > implements > > > > > > > - DecoratedConverter, > > > > > > DecoratedCopier, ExplicitTransformer { > > > > > > > + DecoratedConverter, > > > > > > DecoratedCopier, ExplicitTransformer, > > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > > } > > > > > > > > > > > > > > /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + List conversionPath = > > > > > > getConversionPath(destinationClass, > > > > > > > sourceClass); > > > > > > > + return > > > > > !isPrecise(conversionPath, > > > > > > sourceClass, 0); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > * Get the converter used when > using > > > a > > > > > > ChainedTransformer as a > > > > > > > Copier. > > > > > > > * @return > > > > > > > */ > > > > > > > @@ -113,6 +123,7 @@ > > > > > > > throw new > > > > > > TransformationException(destinationClass, > > > > > > > sourceType, null, > > > > > > > > > > "Chained > > > > > > conversion path could not > > > > > > > be determined"); > > > > > > > } > > > > > > > + log.debug("Using chained > > > > > > conversion path " + > > > > > > > conversionPath); > > > > > > > Object o = source; > > > > > > > for (int i = 0; i < > > > > > > conversionPath.size(); i++) { > > > > > > > o = > > > > > > getConverter(chain[i]).convert((Class) > > > > > > > conversionPath.get(i), o, locale); > > > > > > > @@ -144,6 +155,7 @@ > > > > > > > throw new > > > > > > TransformationException(destinationClass, > > > > > > > source, null, > > > > > > > > > > "Chained > > > > > > conversion path could not > > > > > > > be determined"); > > > > > > > } > > > > > > > + log.debug("Using chained > > > > > > conversion path " + > > > > > > > conversionPath); > > > > > > > Object last = > > > > > > getCopyConverter().convert((Class) > > > > > > > conversionPath.get(chain.length - 2), > > > source, > > > > > > locale); > > > > > > > ((Copier) > > > > > copier).copy(destination, > > > > > > last, locale); > > > > > > > } > > > > > > > @@ -192,13 +204,7 @@ > > > > > > > * @return List > > > > > > > */ > > > > > > > protected List > > > getConversionPath(Class > > > > > > destinationType, Class > > > > > > > sourceType) { > > > > > > > - if (sourceType != null) > { > > > > > > > - List withoutNull > = > > > > > > > getConversionPath(destinationType, > > > sourceType, > > > > > 0, > > > > > > false); > > > > > > > - if (withoutNull > != > > > null) > > > > > { > > > > > > > - return > > > > > > withoutNull; > > > > > > > - } > > > > > > > - } > > > > > > > - return > > > > > > getConversionPath(destinationType, > sourceType, > > > 0, > > > > > > > true); > > > > > > > + return > > > > > > getConversionPath(destinationType, > sourceType, > > > 0); > > > > > > > } > > > > > > > > > > > > > > /** > > > > > > > @@ -210,7 +216,7 @@ > > > > > > > * @param allowNull > > > > > > > * @return List > > > > > > > */ > > > > > > > - private List > getConversionPath(Class > > > > > > destinationType, Class > > > > > > > sourceType, int index, boolean > allowNull) { > > > > > > > + private List > getConversionPath(Class > > > > > > destinationType, Class > > > > > > > sourceType, int index) { > > > > > > > Transformer[] chain = > > > getChain(); > > > > > > > Transformer c = > chain[index]; > > > > > > > if (index + 1 == > > > chain.length) { > > > > > > > @@ -221,22 +227,38 @@ > > > > > > > } > > > > > > > return null; > > > > > > > } > > > > > > > + List possibleResult = > null; > > > > > > > Class[] available = > > > > > > c.getDestinationClasses(); > > > > > > > for (int i = 0; i < > > > > > > available.length; i++) { > > > > > > > - if (available[i] > == > > > null > > > > > > && !allowNull) { > > > > > > > - > continue; > > > > > > > - } > > > > > > > if > > > > > > (TransformerUtils.isTransformable(c, > > > > > > > available[i], sourceType)) { > > > > > > > - List > tail = > > > > > > > getConversionPath(destinationType, > > > available[i], > > > > > > index + 1, allowNull); > > > > > > > + List > tail = > > > > > > > getConversionPath(destinationType, > > > available[i], > > > > > > index + 1); > > > > > > > if (tail > != > > > null) > > > > > { > > > > > > > > > > > > tail.add(0, > > > > > > available[i]); > > > > > > > - > > > return > > > > > > tail; > > > > > > > + > if > > > > > > (isPrecise(tail, sourceType, > > > > > > > index)) { > > > > > > > + > > > > > > return tail; > > > > > > > + > } > > > > > > > + > > > > > > possibleResult = tail; > > > > > > > } > > > > > > > } > > > > > > > } > > > > > > > - return null; > > > > > > > + return possibleResult; > > > > > > > } > > > > > > > > > > > > > > + private boolean isPrecise(List > > > > > > conversionPath, Class sourceType, > > > > > > > int index) { > > > > > > > + Transformer[] chain = > > > > > getChain(); > > > > > > > + Class currentSource = > > > > > sourceType; > > > > > > > + int i = 0; > > > > > > > + for (Iterator iter = > > > > > > conversionPath.iterator(); > > > > > > > iter.hasNext(); i++) { > > > > > > > + Class > currentDest = > > > > > > (Class) iter.next(); > > > > > > > + if > > > > > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > > + i], currentDest, > > > > > > > + > > > > > > currentSource)) { > > > > > > > + return > > > false; > > > > > > > + } > > > > > > > + currentSource = > > > > > > currentDest; > > > > > > > + } > > > > > > > + return true; > > > > > > > + } > > > > > > > + > > > > > > > /** > > > > > > > * Get the components array > narrowed > > > to a > > > > > > Transformer[]. > > > > > > > * @return Transformer[] > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > (revision > > > > > > > 0) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > (revision > > > > > > > 0) > > > > > > > @@ -0,0 +1,32 @@ > > > > > > > +/* > > > > > > > + * Copyright 2008 the original author > or > > > > > authors. > > > > > > > + * > > > > > > > + * Licensed under the Apache License, > > > Version > > > > > 2.0 > > > > > > (the "License"); you > > > > > > > may not > > > > > > > + * use this file except in compliance > with > > > the > > > > > > License. You may obtain a > > > > > > > copy of > > > > > > > + * the License at > > > > > > > + * > > > > > > > + * > > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > > + * > > > > > > > + * Unless required by applicable law or > > > agreed > > > > > to > > > > > > in writing, software > > > > > > > + * distributed under the License is > > > distributed > > > > > > on an "AS IS" BASIS, > > > > > > > WITHOUT > > > > > > > + * WARRANTIES OR CONDITIONS OF ANY > KIND, > > > either > > > > > > express or implied. See > > > > > > > the > > > > > > > + * License for the specific language > > > governing > > > > > > permissions and > > > > > > > limitations under > > > > > > > + * the License. > > > > > > > + */ > > > > > > > +package net.sf.morph.transform; > > > > > > > + > > > > > > > +/** > > > > > > > + * Defines a converter whose operation > may > > > > > result > > > > > > in a loss of data > > > > > > > precision. > > > > > > > + * > > > > > > > + * @author mbenson > > > > > > > + * @since Morph 1.0.2 > > > > > > > + */ > > > > > > > +public interface ImpreciseConverter > extends > > > > > > Converter { > > > > > > > + /** > > > > > > > + * Learn whether the specified > > > > > conversion > > > > > > might yield an imprecise > > > > > > > result. > > > > > > > + * @param destinationClass > > > > > > > + * @param sourceClass > > > > > > > + * @return boolean > > > > > > > + */ > > > > > > > + boolean > isImpreciseConversion(Class > > > > > > destinationClass, Class > > > > > > > sourceClass); > > > > > > > +} > > > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > > Name: svn:eol-style > > > > > > > + native > > > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > (revision 362) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > (working copy) > > > > > > > @@ -20,7 +20,9 @@ > > > > > > > import net.sf.morph.Defaults; > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > /** > > > > > > > * Converts an object to a textual > > > > > representation > > > > > > by calling the object's > > > > > > > @@ -32,7 +34,7 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Dec 24, 2004 > > > > > > > */ > > > > > > > -public class ObjectToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter { > > > > > > > +public class ObjectToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > destinationClass, String.class); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > protected boolean > > > > > > isWrappingRuntimeExceptions() { > > > > > > > return true; > > > > > > > } > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > (revision 361) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > (working copy) > > > > > > > @@ -32,7 +32,7 @@ > > > > > > > import > > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > > > /** > > > > > > > - * Converts basic text types into > primtive > > > > > > numbers or {@link > > > > > > > java.lang.Number} > > > > > > > + * Converts basic text types into > primitive > > > > > > numbers or {@link > > > > > > > java.lang.Number} > > > > > > > * objects. > > > > > > > * > > > > > > > * @author Matt Sgarlata > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > (revision 363) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > (working copy) > > > > > > > @@ -21,7 +21,9 @@ > > > > > > > import net.sf.morph.Defaults; > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > /** > > > > > > > * Converts {@link java.lang.Number}s > into > > > basic > > > > > > text types ({@link > > > > > > > java.lang.String}, > > > > > > > @@ -30,7 +32,8 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Jan 26, 2006 > > > > > > > */ > > > > > > > -public class NumberToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter { > > > > > > > +public class NumberToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > private Converter textConverter; > > > > > > > private Converter > numberConverter; > > > > > > > @@ -58,6 +61,13 @@ > > > > > > > } > > > > > > > > > > > > > > /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > destinationClass, String.class); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > * Get the number converter used > by > > > this > > > > > > NumberToTextConverter. > > > > > > > * @return Converter > > > > > > > */ > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > (revision 360) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > (working copy) > > > > > > > @@ -22,7 +22,9 @@ > > > > > > > import net.sf.morph.Defaults; > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > /** > > > > > > > * Converts the basic time types ({@link > > > > > > java.util.Date} and > > > > > > > @@ -33,7 +35,8 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Dec 31, 2004 > > > > > > > */ > > > > > > > -public class TimeToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter { > > > > > > > +public class TimeToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, > > > > > > > + ImpreciseConverter { > > > > > > > > > > > > > > private DateFormat dateFormat; > > > > > > > private Converter timeConverter; > > > > > > > @@ -55,6 +58,13 @@ > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > destinationClass, String.class); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > protected boolean > > > > > > isWrappingRuntimeExceptions() { > > > > > > > return true; > > > > > > > } > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > (revision 357) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > (working copy) > > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > import > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > import net.sf.morph.util.ClassUtils; > > > > > > > @@ -43,7 +44,7 @@ > > > > > > > * @since Jan 2, 2005 > > > > > > > */ > > > > > > > public class TextConverter extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, > > > > > > > - ExplicitTransformer { > > > > > > > + ExplicitTransformer, > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > private static final Class > > > CHAR_SEQUENCE > > > > > = > > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > ClassUtils > > > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > > @@ -62,14 +63,7 @@ > > > > > > > s.add(Character.class); > > > > > > > s.add(char.class); > > > > > > > s.add(null); > > > > > > > - if (CHAR_SEQUENCE != > null) { > > > > > > > - > > > s.add(CHAR_SEQUENCE); > > > > > > > - try { > > > > > > > - > > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > > StringBuffer.class.getConstructor(new > > > Class[] { > > > > > > String.class })); > > > > > > > - } catch > (Exception > > > e) { > > > > > > > - //nope > > > > > > > - } > > > > > > > - } > > > > > > > + s.add(CHAR_SEQUENCE); > > > > > > > > SOURCE_AND_DESTINATION_TYPES > > > = > > > > > > (Class[]) s.toArray(new > > > > > > > Class[s.size()]); > > > > > > > } > > > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > > } > > > > > > > return new > > > > > > Character(string.charAt(0)); > > > > > > > } > > > > > > > - if (destinationClass == > > > > > > String.class) { > > > > > > > + if (destinationClass == > > > > > > String.class > > > > > > > + || > > > > > > (destinationClass == CHAR_SEQUENCE && > > > > > > > CHAR_SEQUENCE != null)) { > > > > > > > return string; > > > > > > > } > > > > > > > if (destinationClass == > > > > > > byte[].class) { > > > > > > > @@ -152,6 +147,16 @@ > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + if > > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > > sourceClass)) { > > > > > > > + return true; > > > > > > > + } > > > > > > > + return > > > isChar(destinationClass) > > > > > && > > > > > > !isChar(sourceClass); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > protected boolean > > > > > > isAutomaticallyHandlingNulls() { > > > > > > > return !isEmptyNull(); > > > > > > > } > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > (revision 362) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > (working copy) > > > > > > > @@ -20,8 +20,10 @@ > > > > > > > import net.sf.morph.Defaults; > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > /** > > > > > > > * Converts boolean values to text > values. > > > > > > Subclasses can build in > > > > > > > support for > > > > > > > @@ -32,10 +34,10 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Jan 9, 2005 > > > > > > > */ > > > > > > > -public class BooleanToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter { > > > > > > > - > > > > > > > +public class BooleanToTextConverter > extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > + > > > > > > > private static final Class[] > > > SOURCE_TYPES > > > > > = > > > > > > { Boolean.class, > > > > > > > boolean.class }; > > > > > > > - > > > > > > > + > > > > > > > private Converter textConverter; > > > > > > > > > > > > > > /** > > > > > > > @@ -93,9 +95,16 @@ > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > destinationClass, String.class); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > protected boolean > > > > > > isWrappingRuntimeExceptions() { > > > > > > > return true; > > > > > > > - } > > > > > > > + } > > > > > > > > > > > > > > /** > > > > > > > * Get the text converter used by > > > this > > > > > > BaseToPrettyTextConverter. > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > (revision 363) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > (working copy) > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > import java.util.Locale; > > > > > > > > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > > > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > > @@ -31,8 +32,8 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Dec 14, 2004 > > > > > > > */ > > > > > > > -public class NumberConverter extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter { > > > > > > > - > > > > > > > +public class NumberConverter extends > > > > > > BaseTransformer implements > > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > + > > > > > > > private static final Class[] > > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > > Number.class, byte.class, > > > > > > short.class, int.class, > > > > > > > long.class, > > > > > > > float.class, > double.class, > > > null > > > > > > > @@ -116,9 +117,20 @@ > > > > > > > /** > > > > > > > * {@inheritDoc} > > > > > > > */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > > sourceClass) > > > > > > > + || > > > > > > > > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > > + > > > > > > sourceClass) < 0; > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > protected Object > convertImpl(Class > > > > > > destinationClass, Object source, > > > > > > > Locale locale) throws > > > Exception { > > > > > > > - > > > > > > > + if (destinationClass == > > > null) { > > > > > > > + return null; > > > > > > > + } > > > > > > > if > > > > > (destinationClass.isPrimitive() > > > > > > && source == null) { > > > > > > > throw new > > > > > > TransformationException(destinationClass, > > > > > > > source); > > > > > > > } > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > (revision 362) > > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > (working copy) > > > > > > > @@ -18,7 +18,9 @@ > > > > > > > import net.sf.morph.Defaults; > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import > > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > > > /** > > > > > > > * Base class for converts that convert > > > objects > > > > > to > > > > > > a pretty > > > > > > > programmer-friendly > > > > > > > @@ -27,7 +29,8 @@ > > > > > > > * @author Matt Sgarlata > > > > > > > * @since Feb 15, 2005 > > > > > > > */ > > > > > > > -public abstract class > > > BaseToPrettyTextConverter > > > > > > extends > > > > > > > BaseReflectorTransformer implements > > > > > > DecoratedConverter { > > > > > > > +public abstract class > > > BaseToPrettyTextConverter > > > > > > extends > > > > > > > BaseReflectorTransformer > > > > > > > + implements > > > DecoratedConverter, > > > > > > ImpreciseConverter { > > > > > > > > > > > > > > private String prefix; > > > > > > > private String suffix; > > > > > > > @@ -161,4 +164,19 @@ > > > > > > > public void > setShowNullValues(boolean > > > > > > showNullValues) { > > > > > > > this.showNullValues = > > > > > > showNullValues; > > > > > > > } > > > > > > > + > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > + protected boolean > > > > > > isImpreciseConversionImpl(Class > > > > > > > destinationClass, Class sourceClass) { > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > > destinationClass, sourceClass); > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > + * Get the intermediate class > passed > > > to > > > > > > the text converter. > > > > > > > + * @return > > > > > > > + */ > > > > > > > + protected Class > > > getIntermediateClass() { > > > > > > > + return > StringBuffer.class; > > > > > > > + } > > > > > > > } > > > > > > > Index: > > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > (revision 365) > > > > > > > +++ > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > (working copy) > > > > > > > @@ -19,6 +19,7 @@ > > > > > > > import java.lang.reflect.Method; > > > > > > > import java.math.BigDecimal; > > > > > > > import java.math.BigInteger; > > > > > > > +import java.util.Comparator; > > > > > > > import java.util.HashMap; > > > > > > > import java.util.HashSet; > > > > > > > import java.util.Iterator; > > > > > > > @@ -69,6 +70,31 @@ > > > > > > > } > > > > > > > } > > > > > > > > > > > > > > + private static class > > > > > NarrownessComparator > > > > > > implements Comparator { > > > > > > > + /** > > > > > > > + * {@inheritDoc} > > > > > > > + */ > > > > > > > + public int > compare(Object > > > arg0, > > > > > > Object arg1) { > > > > > > > + if (arg0 == > arg1) { > > > > > > > + return > 0; > > > > > > > + } > > > > > > > + Class c0 = > > > > > getType(arg0); > > > > > > > + Class c1 = > > > > > getType(arg1); > > > > > > > + if (c0 == c1 || > c0 > > > == > > > > > null > > > > > > || c1 == null) { > > > > > > > + return > 0; > > > > > > > + } > > > > > > > + return > > > > > > > > > > > > > > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > > > + } > > > > > > > + > > > > > > > + private Class > getType(Object > > > o) > > > > > { > > > > > > > + if > > > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > > > + return > > > (Class) > > > > > o; > > > > > > > + } > > > > > > > + Class test = > > > > > > ClassUtils.getClass(o); > > > > > > > + return > > > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? > test > > > > > > > : null; > > > > > > > + } > > > > > > > + } > > > > > > > + > > > > > > > /** > > > > > > > * A Map of BigDecimals keyed by > > > Class > > > > > that > > > > > > indicate the maximum > > > > > > > value that > > > > > > > * the given (Number) Class may > taken > > > on. > > > > > > > @@ -80,11 +106,16 @@ > > > > > > > * the given (Number) Class may > taken > > > on. > > > > > > > */ > > > > > > > public static final Map > > > > > MINIMUMS_FOR_TYPES; > > > > > > > - > > > > > > > - public static final Map > > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > > > > > - public static final Map > > > > > NUMBER_FACTORIES; > > > > > > > + /** > > > > > > > + * Comparator of class/object > type > > > > > > narrowness. > > > > > > > + */ > > > > > > > + public static final Comparator > > > > > > NARROWNESS_COMPARATOR = new > > > > > > > NarrownessComparator(); > > > > > > > > > > > > > > + private static final Map > > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > + > > > > > > > + private static final Map > > > > > NUMBER_FACTORIES; > > > > > > > + > > > > > > > /** > > > > > > > * Used by {@link > > > > > > NumberUtils#isNumber(Class)}. > > > > > > > */ > > > > > > > Index: > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > > --- > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > (revision 357) > > > > > > > +++ > > > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > (working copy) > > > > > > > @@ -1,5 +1,5 @@ > > > > > > > /* > > > > > > > - * Copyright 2004-2005, 2007 the > original > > > > > author > > > > > > or authors. > > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > > author or authors. > > > > > > > * > > > > > > > * Licensed under the Apache License, > > > Version > > > > > 2.0 > > > > > > (the "License"); you may > > > > > > > not > > > > > > > * use this file except in compliance > with > > > the > > > > > > License. You may obtain a > > > > > > > copy of > > > > > > > @@ -26,6 +26,7 @@ > > > > > > > import > net.sf.morph.transform.Converter; > > > > > > > import net.sf.morph.transform.Copier; > > > > > > > import > > > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > > +import > > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > > import > > > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > > > } > > > > > > > > > > > > > > /** > > > > > > > + * Learn whether > > > > > > <code>transformer</code>'s conversion > > > > > > > + * of <code>sourceClass</code> > to > > > > > > <code>destinationClass</code> > > > > > > > might yield an imprecise result. > > > > > > > + * @param transformer > > > > > > > + * @param destinationClass > > > > > > > + * @param sourceClass > > > > > > > + * @return boolean > > > > > > > + * @see ImpreciseConverter > > > > > > > + */ > > > > > > > + public static boolean > > > > > > isImpreciseConversion(Transformer > > > > > > > transformer, > > > > > > > + Class > > > destinationClass, > > > > > > Class sourceClass) { > > > > > > > + if (transformer > instanceof > > > > > > ImpreciseConverter) { > > > > > > > + return > > > > > > ((ImpreciseConverter) > > > > > > > transformer).isImpreciseConversion( > > > > > > > + > > > > > > destinationClass, sourceClass); > > > > > > > + } > > > > > > > + return destinationClass > == > > > null > > > > > && > > > > > > sourceClass != null; > > > > > > > + } > > > > > > > + > > > > > > > + /** > > > > > > > * Performs a transformation of > one > > > > > object > > > > > > graph into another > > > > > > > object graph. > > > > > > > * > > > > > > > * @param destinationType > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > > > This SF.net email is sponsored by: > Microsoft > > > > > > > Defy all challenges. Microsoft(R) Visual > > > Studio > > > > > > 2005. > > > > > > > > > > > > > > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > > > > > _______________________________________________ > > > > > > > morph-developer mailing list > > > > > > > mor...@li... > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > This message is intended only for the > named > > > > > > recipient. If you are not the > > > > > > intended recipient, you are notified that > > > > > > disclosing, copying, distributing, > > > > > > or taking any action in reliance on the > > > contents > > > > > of > > > > > > this information is > > > > > > strictly prohibited. > > > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > > This SF.net email is sponsored by: > Microsoft > > > > > > Defy all challenges. Microsoft(R) Visual > > > Studio > > > > > > 2005. > > > > > > > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > > > > _______________________________________________ > > > > > > morph-developer mailing list > > > > > > mor...@li... > > > > > > > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > Looking for last minute shopping deals? > > > > > Find them fast with Yahoo! Search. > > > > > > > > > > > > > > > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > This SF.net email is sponsored by: Microsoft > > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > > > 2005. > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > _______________________________________________ > > > > > morph-developer mailing list > > > > > mor...@li... > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > Be a better friend, newshound, and > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > > > > > > > ----------... [truncated message content] |
From: Matt S. <mat...@sp...> - 2008-01-24 16:49:57
|
Thanks! I will try that out next time. Matt On Jan 24, 2008 11:03 AM, Matt Benson <gud...@ya...> wrote: > Hi Matt, > I was trying to build Morph on a different machine > today and I encountered similar problems. My main > machine may have a different version of Ivy; I'm not > sure. But it seems that it was trying to select an > older integration version of Composite even when I > republished it. To quickly work around that, simply > blow composite out of your local repo (should be under > .ivy in your home directory). If you still have > problems, Ant may be picking up an older version in > ivylib. Run ant clean-lib to make sure this isn't the > case. > > HTH, > Matt B > > > --- Matt Sgarlata <mat...@sp...> > wrote: > > > I thought I tried that and it didn't do the trick, > > but perhaps I missed > > something. I was messing with my build files to > > make my JARs named > > composite-1.1 and morph-1.1, so that could be part > > of the problem. > > > > In any case, I did manage to generate JARs for > > myself and I'm going to be > > trying them out in live production apps soon. If > > they work, then it will > > really be time to push them out for release. > > > > I was gunning to get a bug resolved today so I ended > > up just moving the > > method to Morph. It's probably more appropriate to > > put it there anyway. > > > > Matt > > > > On Jan 22, 2008 3:50 PM, Matt Benson > > <gud...@ya...> wrote: > > > > > Are you using the Ivy-dependent Ant build, then? > > If, > > > in composite, you run target "publish" it should > > make > > > an integration release available in your local Ivy > > > repository. > > > > > > HTH, > > > Matt B > > > > > > --- Matt Sgarlata > > > <Mat...@wh...> wrote: > > > > > > > I'm trying to run a Morph build, but it's > > picking up > > > > on an old version of > > > > Composite that does not have the > > > > ClassUtils.isCommonsCollections3Presentmethod > > > > defined. Any idea how I > > > > fix this? > > > > > > > > Thanks, > > > > > > > > Matt S > > > > > > > > -- > > > > This message is intended only for the named > > > > recipient. If you are not the > > > > intended recipient, you are notified that > > > > disclosing, copying, distributing, > > > > or taking any action in reliance on the contents > > of > > > > this information is > > > > strictly prohibited. > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual Studio > > > > 2008. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > Be a better friend, newshound, and > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > 2008. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > -- > > This message is intended only for the named > > recipient. If you are not the > > intended recipient, you are notified that > > disclosing, copying, distributing, > > or taking any action in reliance on the contents of > > this information is > > strictly prohibited. > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > > 2008. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Never miss a thing. Make Yahoo your home page. > http://www.yahoo.com/r/hs > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt B. <gud...@ya...> - 2008-01-24 16:03:59
|
Hi Matt, I was trying to build Morph on a different machine today and I encountered similar problems. My main machine may have a different version of Ivy; I'm not sure. But it seems that it was trying to select an older integration version of Composite even when I republished it. To quickly work around that, simply blow composite out of your local repo (should be under .ivy in your home directory). If you still have problems, Ant may be picking up an older version in ivylib. Run ant clean-lib to make sure this isn't the case. HTH, Matt B --- Matt Sgarlata <mat...@sp...> wrote: > I thought I tried that and it didn't do the trick, > but perhaps I missed > something. I was messing with my build files to > make my JARs named > composite-1.1 and morph-1.1, so that could be part > of the problem. > > In any case, I did manage to generate JARs for > myself and I'm going to be > trying them out in live production apps soon. If > they work, then it will > really be time to push them out for release. > > I was gunning to get a bug resolved today so I ended > up just moving the > method to Morph. It's probably more appropriate to > put it there anyway. > > Matt > > On Jan 22, 2008 3:50 PM, Matt Benson > <gud...@ya...> wrote: > > > Are you using the Ivy-dependent Ant build, then? > If, > > in composite, you run target "publish" it should > make > > an integration release available in your local Ivy > > repository. > > > > HTH, > > Matt B > > > > --- Matt Sgarlata > > <Mat...@wh...> wrote: > > > > > I'm trying to run a Morph build, but it's > picking up > > > on an old version of > > > Composite that does not have the > > > ClassUtils.isCommonsCollections3Presentmethod > > > defined. Any idea how I > > > fix this? > > > > > > Thanks, > > > > > > Matt S > > > > > > -- > > > This message is intended only for the named > > > recipient. If you are not the > > > intended recipient, you are notified that > > > disclosing, copying, distributing, > > > or taking any action in reliance on the contents > of > > > this information is > > > strictly prohibited. > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2008. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Be a better friend, newshound, and > > know-it-all with Yahoo! Mobile. Try it now. > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > 2008. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio > 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs |
From: Matt B. <gud...@ya...> - 2008-01-22 22:05:49
|
Hmm, I just went into build.properties in each directory and changed project.version to 1.1${ver.ext}. You should be able to set ver.ext= i.e. blank to get the version #s you want. :| -Matt B --- Matt Sgarlata <mat...@sp...> wrote: > I thought I tried that and it didn't do the trick, > but perhaps I missed > something. I was messing with my build files to > make my JARs named > composite-1.1 and morph-1.1, so that could be part > of the problem. > > In any case, I did manage to generate JARs for > myself and I'm going to be > trying them out in live production apps soon. If > they work, then it will > really be time to push them out for release. > > I was gunning to get a bug resolved today so I ended > up just moving the > method to Morph. It's probably more appropriate to > put it there anyway. > > Matt > > On Jan 22, 2008 3:50 PM, Matt Benson > <gud...@ya...> wrote: > > > Are you using the Ivy-dependent Ant build, then? > If, > > in composite, you run target "publish" it should > make > > an integration release available in your local Ivy > > repository. > > > > HTH, > > Matt B > > > > --- Matt Sgarlata > > <Mat...@wh...> wrote: > > > > > I'm trying to run a Morph build, but it's > picking up > > > on an old version of > > > Composite that does not have the > > > ClassUtils.isCommonsCollections3Presentmethod > > > defined. Any idea how I > > > fix this? > > > > > > Thanks, > > > > > > Matt S > > > > > > -- > > > This message is intended only for the named > > > recipient. If you are not the > > > intended recipient, you are notified that > > > disclosing, copying, distributing, > > > or taking any action in reliance on the contents > of > > > this information is > > > strictly prohibited. > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2008. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Be a better friend, newshound, and > > know-it-all with Yahoo! Mobile. Try it now. > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > 2008. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio > 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ |
From: Matt S. <mat...@sp...> - 2008-01-22 21:50:43
|
I thought I tried that and it didn't do the trick, but perhaps I missed something. I was messing with my build files to make my JARs named composite-1.1 and morph-1.1, so that could be part of the problem. In any case, I did manage to generate JARs for myself and I'm going to be trying them out in live production apps soon. If they work, then it will really be time to push them out for release. I was gunning to get a bug resolved today so I ended up just moving the method to Morph. It's probably more appropriate to put it there anyway. Matt On Jan 22, 2008 3:50 PM, Matt Benson <gud...@ya...> wrote: > Are you using the Ivy-dependent Ant build, then? If, > in composite, you run target "publish" it should make > an integration release available in your local Ivy > repository. > > HTH, > Matt B > > --- Matt Sgarlata > <Mat...@wh...> wrote: > > > I'm trying to run a Morph build, but it's picking up > > on an old version of > > Composite that does not have the > > ClassUtils.isCommonsCollections3Presentmethod > > defined. Any idea how I > > fix this? > > > > Thanks, > > > > Matt S > > > > -- > > This message is intended only for the named > > recipient. If you are not the > > intended recipient, you are notified that > > disclosing, copying, distributing, > > or taking any action in reliance on the contents of > > this information is > > strictly prohibited. > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > > 2008. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Be a better friend, newshound, and > know-it-all with Yahoo! Mobile. Try it now. > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt B. <gud...@ya...> - 2008-01-22 20:50:13
|
Are you using the Ivy-dependent Ant build, then? If, in composite, you run target "publish" it should make an integration release available in your local Ivy repository. HTH, Matt B --- Matt Sgarlata <Mat...@wh...> wrote: > I'm trying to run a Morph build, but it's picking up > on an old version of > Composite that does not have the > ClassUtils.isCommonsCollections3Presentmethod > defined. Any idea how I > fix this? > > Thanks, > > Matt S > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio > 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ |
From: Matt S. <Mat...@wh...> - 2008-01-22 19:25:09
|
I'm trying to run a Morph build, but it's picking up on an old version of Composite that does not have the ClassUtils.isCommonsCollections3Presentmethod defined. Any idea how I fix this? Thanks, Matt S -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt S. <mat...@sp...> - 2008-01-10 18:05:32
|
I see what you mean. I prefer ImpreciseTransformer to PrecisionTransformer because of the difficulty of assigning a numeric value for the degree of precision. I think that assignment is going to end up arbitrary and confusing pretty quickly. ImpreciseTransformer also would probably make the logic for determining the conversion path simpler. In terms of using different paths for different source and destination combos, I think perhaps the best solution in such a case would be to just make a bunch of individual AssemblerCopiers with individual paths, and then add them all together using the SimpleDelegatingTransformer. Matt On Jan 10, 2008 12:14 PM, Matt Benson <gud...@ya...> wrote: > You have a point, though I guess my aim in avoiding > such a thing was that--usually--the path is simple > enough to determine given source and dest classes. > Secondly, you might use a different path depending on > available source/dest combos, so the configuration > might be a little more complex. :| As for where > converters with awareness of "precision" might be > useful, I can't say that I know of another context > right now, but at the very least I would say it might > be useful knowledge for both number and text types. > > -Matt > > --- Matt Sgarlata <mat...@sp...> > wrote: > > > I agree, that does sound like it could end up being > > somewhat arbitrary. I > > know the original impetus for this was that > > configuration of the > > ChainedTransformer could be a real pain in the neck. > > Are there other > > situations where the information provided by > > ImplicitTransformer or > > PrecisionTransformer might be useful? I guess what > > I'm getting at here is, > > what is the requirement we are trying to solve? > > Perhaps if we think about > > it in a new way a different solution will present > > itself. > > > > Perhaps an alternative could be to introduce a new > > setTransformationPath(Class[] path) method to the > > ChainedTransformer. That > > would make configuration a snap, even if you were > > trying to use dependency > > injection for the configuration. > > > > Matt S > > > > On Jan 10, 2008 11:24 AM, Matt Benson > > <gud...@ya...> wrote: > > > > > More on this: what do you think about the concept > > of > > > something like a PrecisionTransformer that returns > > a > > > float precision from 0.0 to 1.0 given a > > > destinationClass and a sourceClass? These might > > be > > > somewhat arbitrary, or calculated (like with > > numeric > > > types), but they might allow a little more > > > informedness on the part of the consumer. > > > > > > -Matt B > > > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > > > > > > > --- Matt Sgarlata > > > > <mat...@sp...> > > > > wrote: > > > > > > > > > I have been thinking more about this approach, > > and > > > > > it's really starting to > > > > > grow on me. I do have one concern though, can > > > > this > > > > > approach be extended to > > > > > Copiers? For example, a Map -> Object copy > > could > > > > > probably be considered an > > > > > imprecise transformation because the Map may > > have > > > > > more keys than the Object > > > > > has properties. > > > > > > > > I thought about this as well. It could be done; > > it > > > > might be slightly complex calculating the > > > > "precision" > > > > of a PropertyNameMatchingCopier--I would think > > an > > > > explicitly specified PNMatchingC would be > > precise; > > > > an > > > > imprecise one would be one using property name > > > > discovery and where the properties of the source > > are > > > > not all available on the destination. > > There--the > > > > hard > > > > part of that one is over. :) I will work on > > > > ImpreciseConverter -> ImpreciseTransformer > > extends > > > > Transformer and other semantic changes as time > > > > permits. Your ordering changes are, I expect, > > fine > > > > by > > > > me as well. :) > > > > > > > > -Matt B > > > > > > > > > > > > > > In addition to your approach, I also like the > > idea > > > > > of cleaning up the > > > > > internal implementation in Morph so that > > ordering > > > > of > > > > > source and destination > > > > > classes is preserved for the following > > reasons: > > > > > 1) for at least some portion of users, setting > > the > > > > > order of source and > > > > > destination classes will make sense as an > > > > indication > > > > > of the transformer's > > > > > preferences for performing transformations (so > > for > > > > > this class of users, > > > > > creating new transformers that play nicely > > with > > > > the > > > > > ChainedTransformerTestCase will be simpler) > > > > > 2) I think a general change from using > > HashSets to > > > > > ordered sets in Morph's > > > > > implementation will mean transformations > > happen > > > > more > > > > > consistently across > > > > > JVMs and across time on the same JVM, leading > > to a > > > > > more stable platform > > > > > > > > > > So, what I did is I basically went through the > > > > Morph > > > > > codebase and replaced > > > > > HashSets with ordered sets (preference order > > is: > > > > JDK > > > > > 1.4 LinkedHashSet, > > > > > Commons-collections ListOrderedSet, copy of > > > > > ListOrderedSet in > > > > > net.sf.morph.util). I was never able to > > modify > > > > the > > > > > ChainedTransformerTestCase so that it > > consistently > > > > > threw an error. However, > > > > > after working on the test case long enough, > > > > > eventually something changed in > > > > > my environment so that the test started to > > fail. > > > > I > > > > > did my change of > > > > > HashSets to ordered sets, and that was able to > > fix > > > > > the broken test. > > > > > > > > > > I checked in my changes for you to take a look > > > > at... > > > > > > > > > > Matt S > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > <gud...@ya...> wrote: > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > Be a better friend, newshound, and > > > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > > Version > > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -35,6 +35,7 @@ > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > net.sf.morph.transform.DecoratedCopier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import net.sf.morph.transform.NodeCopier; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import net.sf.morph.transform.Transformer; > > > > > > @@ -93,11 +94,11 @@ > > > > > > * @since Dec 12, 2004 > > > > > > */ > > > > > > public class SimpleDelegatingTransformer > > > > extends > > > > > BaseCompositeTransformer > > > > > > implements > > > > > > - SpecializableComposite, > > > > > ExplicitTransformer, Transformer, > > > > > > DecoratedCopier, DecoratedConverter, > > Cloneable { > > > > > > + SpecializableComposite, > > > > > ExplicitTransformer, Transformer, > > > > > > DecoratedCopier, > > > > > > + DecoratedConverter, > > Cloneable, > > > > > ImpreciseConverter { > > > > > > > > > > > > //TODO extract > > BaseDelegatingTransformer > > > > > with pluggable delegate > > > > > > selection > > > > > > > > > > > > - > > > > > > private static class MapThreadLocal > > > > extends > > > > > ThreadLocal { > > > > > > protected Object > > initialValue() { > > > > > > return new HashMap(); > > > > > > @@ -138,6 +139,7 @@ > > > > > > } > > > > > > > > > > > > private Specializer specializer; > > > > > > + private boolean > > > > preferPreciseTransformers; > > > > > > > > > > > > private transient ThreadLocal > > > > > > visitedSourceToDestinationMapThreadLocal = > > new > > > > > MapThreadLocal(); > > > > > > private transient ThreadLocal > > > > > stackDepthThreadLocal = new > > > > > > StackDepthThreadLocal(); > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > TransformerUtils.isImpreciseConversion > > > > > > (getTransformer(destinationClass, > > > > > > + > > sourceClass), > > > > > destinationClass, > > > > > > sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > > */ > > > > > > protected Class[] > > getSourceClassesImpl() > > > > > throws Exception { > > > > > > @@ -477,6 +487,7 @@ > > > > > > * if no suitable > > transformer > > > > > could be found > > > > > > */ > > > > > > private Transformer > > getTransformer(Class > > > > > transformerType, Class > > > > > > destinationClass, Class sourceClass) throws > > > > > TransformationException { > > > > > > + Transformer candidate = > > null; > > > > > > for (int i = 0; i < > > > > > components.length; i++) { > > > > > > // if the transformer > > is > > > > > the correct type > > > > > > Transformer > > transformer = > > > > > (Transformer) > > > > > > components[i]; > > > > > > @@ -484,6 +495,13 @@ > > > > > > // if the > > > > > transformer is capable of > > > > > > performing the transformation > > > > > > if > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > transformer, > > > > > > destinationClass, sourceClass)) { > > > > > > + if > > > > > (isPreferPreciseTransformers() > > > > > > + > > > > > > > > > && candidate == > > > > > > null > > > > > > + > > > > > > > > > && > > > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > + > > > > > > destinationClass, sourceClass)) { > > > > > > + > > > > > candidate = transformer; > > > > > > + > > > > > continue; > > > > > > + } > > > > > > if > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > > > > + > > > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > @@ -496,7 +514,9 @@ > > > > > > > > return > > > > > transformer; > > > > > > } > > > > > > } > > > > > > - > > > > > > + if (candidate != > > null) { > > > > > > + return > > > > candidate; > > > > > > + } > > > > > > } > > > > > > throw new > > > > TransformationException( > > > > > > "Could not find a > > > > > transformer that can transform > > > > > > objects of " > > > > > > @@ -612,4 +632,20 @@ > > > > > > source); > > > > > > } > > > > > > > > > > > > + /** > > > > > > + * Get the > > preferPreciseTransformers. > > > > > > + * @return boolean > > > > > > + */ > > > > > > + public boolean > > > > > isPreferPreciseTransformers() { > > > > > > + return > > > > preferPreciseTransformers; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Set the > > preferPreciseTransformers. > > > > > Default false. > > > > > > + * @param preferPreciseTransformers > > the > > > > > boolean to set > > > > > > + */ > > > > > > + public void > > > > > setPreferPreciseTransformers(boolean > > > > > > preferPreciseTransformers) { > > > > > > + > > this.preferPreciseTransformers = > > > > > > preferPreciseTransformers; > > > > > > + } > > > > > > + > > > > > > } > > > > > > \ No newline at end of file > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > (revision 358) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > (working copy) > > > > > > @@ -570,6 +570,35 @@ > > > > > > } > > > > > > } > > > > > > > > > > > > + /** > > > > > > + * Implementation of > > > > isImpreciseConversion > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return destinationClass == > > null > > > > && > > > > > sourceClass != null; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Learn whether the specified > > > > conversion > > > > > yields an imprecise > > > > > > result. > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + */ > > > > > > + public final boolean > > > > > isImpreciseConversion(Class destinationClass, > > > > > > Class sourceClass) { > > > > > > + try { > > > > > > + return > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass); > > > > > > + } catch (Exception e) { > > > > > > + if (e instanceof > > > > > RuntimeException && > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > + throw > > > > > (RuntimeException) e; > > > > > > + } > > > > > > + throw new > > > > > TransformationException("Could not > > > > > > determine if conversion of " > > > > > > + + > > > > > sourceClass + " to " + > > > > > > destinationClass > > > > > > + + " > > > > > results in a loss of > > > > > > precision", e); > > > > > > + } > > > > > > + } > > > > > > + > > > > > > // property getters and setters > > > > > > > > > > > > /** > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > > Version > > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -16,6 +16,7 @@ > > > > > > package > > net.sf.morph.transform.transformers; > > > > > > > > > > > > import java.util.ArrayList; > > > > > > +import java.util.Iterator; > > > > > > import java.util.List; > > > > > > import java.util.Locale; > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > net.sf.morph.transform.DecoratedCopier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import net.sf.morph.transform.Transformer; > > > > > > import > > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > @@ -40,7 +42,7 @@ > > > > > > * @since Nov 24, 2004 > > > > > > */ > > > > > > public class ChainedTransformer extends > > > > > BaseCompositeTransformer > > > > > > implements > > > > > > - DecoratedConverter, > > > > > DecoratedCopier, ExplicitTransformer { > > > > > > + DecoratedConverter, > > > > > DecoratedCopier, ExplicitTransformer, > > > > > > ImpreciseConverter { > > > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + List conversionPath = > > > > > getConversionPath(destinationClass, > > > > > > sourceClass); > > > > > > + return > > > > !isPrecise(conversionPath, > > > > > sourceClass, 0); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Get the converter used when using > > a > > > > > ChainedTransformer as a > > > > > > Copier. > > > > > > * @return > > > > > > */ > > > > > > @@ -113,6 +123,7 @@ > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > sourceType, null, > > > > > > > > "Chained > > > > > conversion path could not > > > > > > be determined"); > > > > > > } > > > > > > + log.debug("Using chained > > > > > conversion path " + > > > > > > conversionPath); > > > > > > Object o = source; > > > > > > for (int i = 0; i < > > > > > conversionPath.size(); i++) { > > > > > > o = > > > > > getConverter(chain[i]).convert((Class) > > > > > > conversionPath.get(i), o, locale); > > > > > > @@ -144,6 +155,7 @@ > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > source, null, > > > > > > > > "Chained > > > > > conversion path could not > > > > > > be determined"); > > > > > > } > > > > > > + log.debug("Using chained > > > > > conversion path " + > > > > > > conversionPath); > > > > > > Object last = > > > > > getCopyConverter().convert((Class) > > > > > > conversionPath.get(chain.length - 2), > > source, > > > > > locale); > > > > > > ((Copier) > > > > copier).copy(destination, > > > > > last, locale); > > > > > > } > > > > > > @@ -192,13 +204,7 @@ > > > > > > * @return List > > > > > > */ > > > > > > protected List > > getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType) { > > > > > > - if (sourceType != null) { > > > > > > - List withoutNull = > > > > > > getConversionPath(destinationType, > > sourceType, > > > > 0, > > > > > false); > > > > > > - if (withoutNull != > > null) > > > > { > > > > > > - return > > > > > withoutNull; > > > > > > - } > > > > > > - } > > > > > > - return > > > > > getConversionPath(destinationType, sourceType, > > 0, > > > > > > true); > > > > > > + return > > > > > getConversionPath(destinationType, sourceType, > > 0); > > > > > > } > > > > > > > > > > > > /** > > > > > > @@ -210,7 +216,7 @@ > > > > > > * @param allowNull > > > > > > * @return List > > > > > > */ > > > > > > - private List getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType, int index, boolean allowNull) { > > > > > > + private List getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType, int index) { > > > > > > Transformer[] chain = > > getChain(); > > > > > > Transformer c = chain[index]; > > > > > > if (index + 1 == > > chain.length) { > > > > > > @@ -221,22 +227,38 @@ > > > > > > } > > > > > > return null; > > > > > > } > > > > > > + List possibleResult = null; > > > > > > Class[] available = > > > > > c.getDestinationClasses(); > > > > > > for (int i = 0; i < > > > > > available.length; i++) { > > > > > > - if (available[i] == > > null > > > > > && !allowNull) { > > > > > > - continue; > > > > > > - } > > > > > > if > > > > > (TransformerUtils.isTransformable(c, > > > > > > available[i], sourceType)) { > > > > > > - List tail = > > > > > > getConversionPath(destinationType, > > available[i], > > > > > index + 1, allowNull); > > > > > > + List tail = > > > > > > getConversionPath(destinationType, > > available[i], > > > > > index + 1); > > > > > > if (tail != > > null) > > > > { > > > > > > > > > > tail.add(0, > > > > > available[i]); > > > > > > - > > return > > > > > tail; > > > > > > + if > > > > > (isPrecise(tail, sourceType, > > > > > > index)) { > > > > > > + > > > > > return tail; > > > > > > + } > > > > > > + > > > > > possibleResult = tail; > > > > > > } > > > > > > } > > > > > > } > > > > > > - return null; > > > > > > + return possibleResult; > > > > > > } > > > > > > > > > > > > + private boolean isPrecise(List > > > > > conversionPath, Class sourceType, > > > > > > int index) { > > > > > > + Transformer[] chain = > > > > getChain(); > > > > > > + Class currentSource = > > > > sourceType; > > > > > > + int i = 0; > > > > > > + for (Iterator iter = > > > > > conversionPath.iterator(); > > > > > > iter.hasNext(); i++) { > > > > > > + Class currentDest = > > > > > (Class) iter.next(); > > > > > > + if > > > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > + i], currentDest, > > > > > > + > > > > > currentSource)) { > > > > > > + return > > false; > > > > > > + } > > > > > > + currentSource = > > > > > currentDest; > > > > > > + } > > > > > > + return true; > > > > > > + } > > > > > > + > > > > > > /** > > > > > > * Get the components array narrowed > > to a > > > > > Transformer[]. > > > > > > * @return Transformer[] > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > (revision > > > > > > 0) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > (revision > > > > > > 0) > > > > > > @@ -0,0 +1,32 @@ > > > > > > +/* > > > > > > + * Copyright 2008 the original author or > > > > authors. > > > > > > + * > > > > > > + * Licensed under the Apache License, > > Version > > > > 2.0 > > > > > (the "License"); you > > > > > > may not > > > > > > + * use this file except in compliance with > > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > + * the License at > > > > > > + * > > > > > > + * > > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > + * > > > > > > + * Unless required by applicable law or > > agreed > > > > to > > > > > in writing, software > > > > > > + * distributed under the License is > > distributed > > > > > on an "AS IS" BASIS, > > > > > > WITHOUT > > > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, > > either > > > > > express or implied. See > > > > > > the > > > > > > + * License for the specific language > > governing > > > > > permissions and > > > > > > limitations under > > > > > > + * the License. > > > > > > + */ > > > > > > +package net.sf.morph.transform; > > > > > > + > > > > > > +/** > > > > > > + * Defines a converter whose operation may > > > > result > > > > > in a loss of data > > > > > > precision. > > > > > > + * > > > > > > + * @author mbenson > > > > > > + * @since Morph 1.0.2 > > > > > > + */ > > > > > > +public interface ImpreciseConverter extends > > > > > Converter { > > > > > > + /** > > > > > > + * Learn whether the specified > > > > conversion > > > > > might yield an imprecise > > > > > > result. > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + */ > > > > > > + boolean isImpreciseConversion(Class > > > > > destinationClass, Class > > > > > > sourceClass); > > > > > > +} > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > Name: svn:eol-style > > > > > > + native > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > (working copy) > > > > > > @@ -20,7 +20,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts an object to a textual > > > > representation > > > > > by calling the object's > > > > > > @@ -32,7 +34,7 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 24, 2004 > > > > > > */ > > > > > > -public class ObjectToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class ObjectToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > (revision 361) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > (working copy) > > > > > > @@ -32,7 +32,7 @@ > > > > > > import > > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > /** > > > > > > - * Converts basic text types into primtive > > > > > numbers or {@link > > > > > > java.lang.Number} > > > > > > + * Converts basic text types into primitive > > > > > numbers or {@link > > > > > > java.lang.Number} > > > > > > * objects. > > > > > > * > > > > > > * @author Matt Sgarlata > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > (revision 363) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > (working copy) > > > > > > @@ -21,7 +21,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts {@link java.lang.Number}s into > > basic > > > > > text types ({@link > > > > > > java.lang.String}, > > > > > > @@ -30,7 +32,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Jan 26, 2006 > > > > > > */ > > > > > > -public class NumberToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class NumberToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > + ImpreciseConverter { > > > > > > > > > > > > private Converter textConverter; > > > > > > private Converter numberConverter; > > > > > > @@ -58,6 +61,13 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Get the number converter used by > > this > > > > > NumberToTextConverter. > > > > > > * @return Converter > > > > > > */ > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > (revision 360) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > (working copy) > > > > > > @@ -22,7 +22,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts the basic time types ({@link > > > > > java.util.Date} and > > > > > > @@ -33,7 +35,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 31, 2004 > > > > > > */ > > > > > > -public class TimeToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class TimeToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > + ImpreciseConverter { > > > > > > > > > > > > private DateFormat dateFormat; > > > > > > private Converter timeConverter; > > > > > > @@ -55,6 +58,13 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > (working copy) > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > import net.sf.morph.util.ClassUtils; > > > > > > @@ -43,7 +44,7 @@ > > > > > > * @since Jan 2, 2005 > > > > > > */ > > > > > > public class TextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > - ExplicitTransformer { > > > > > > + ExplicitTransformer, > > > > > ImpreciseConverter { > > > > > > > > > > > > private static final Class > > CHAR_SEQUENCE > > > > = > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > ClassUtils > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > @@ -62,14 +63,7 @@ > > > > > > s.add(Character.class); > > > > > > s.add(char.class); > > > > > > s.add(null); > > > > > > - if (CHAR_SEQUENCE != null) { > > > > > > - > > s.add(CHAR_SEQUENCE); > > > > > > - try { > > > > > > - > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > StringBuffer.class.getConstructor(new > > Class[] { > > > > > String.class })); > > > > > > - } catch (Exception > > e) { > > > > > > - //nope > > > > > > - } > > > > > > - } > > > > > > + s.add(CHAR_SEQUENCE); > > > > > > SOURCE_AND_DESTINATION_TYPES > > = > > > > > (Class[]) s.toArray(new > > > > > > Class[s.size()]); > > > > > > } > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > } > > > > > > return new > > > > > Character(string.charAt(0)); > > > > > > } > > > > > > - if (destinationClass == > > > > > String.class) { > > > > > > + if (destinationClass == > > > > > String.class > > > > > > + || > > > > > (destinationClass == CHAR_SEQUENCE && > > > > > > CHAR_SEQUENCE != null)) { > > > > > > return string; > > > > > > } > > > > > > if (destinationClass == > > > > > byte[].class) { > > > > > > @@ -152,6 +147,16 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + if > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass)) { > > > > > > + return true; > > > > > > + } > > > > > > + return > > isChar(destinationClass) > > > > && > > > > > !isChar(sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isAutomaticallyHandlingNulls() { > > > > > > return !isEmptyNull(); > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > (working copy) > > > > > > @@ -20,8 +20,10 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts boolean values to text values. > > > > > Subclasses can build in > > > > > > support for > > > > > > @@ -32,10 +34,10 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Jan 9, 2005 > > > > > > */ > > > > > > -public class BooleanToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > - > > > > > > +public class BooleanToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > + > > > > > > private static final Class[] > > SOURCE_TYPES > > > > = > > > > > { Boolean.class, > > > > > > boolean.class }; > > > > > > - > > > > > > + > > > > > > private Converter textConverter; > > > > > > > > > > > > /** > > > > > > @@ -93,9 +95,16 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > - } > > > > > > + } > > > > > > > > > > > > /** > > > > > > * Get the text converter used by > > this > > > > > BaseToPrettyTextConverter. > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > (revision 363) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > (working copy) > > > > > > @@ -19,6 +19,7 @@ > > > > > > import java.util.Locale; > > > > > > > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > import > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > @@ -31,8 +32,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 14, 2004 > > > > > > */ > > > > > > -public class NumberConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > - > > > > > > +public class NumberConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > + > > > > > > private static final Class[] > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > Number.class, byte.class, > > > > > short.class, int.class, > > > > > > long.class, > > > > > > float.class, double.class, > > null > > > > > > @@ -116,9 +117,20 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass) > > > > > > + || > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > + > > > > > sourceClass) < 0; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected Object convertImpl(Class > > > > > destinationClass, Object source, > > > > > > Locale locale) throws > > Exception { > > > > > > - > > > > > > + if (destinationClass == > > null) { > > > > > > + return null; > > > > > > + } > > > > > > if > > > > (destinationClass.isPrimitive() > > > > > && source == null) { > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > source); > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > (working copy) > > > > > > @@ -18,7 +18,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Base class for converts that convert > > objects > > > > to > > > > > a pretty > > > > > > programmer-friendly > > > > > > @@ -27,7 +29,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Feb 15, 2005 > > > > > > */ > > > > > > -public abstract class > > BaseToPrettyTextConverter > > > > > extends > > > > > > BaseReflectorTransformer implements > > > > > DecoratedConverter { > > > > > > +public abstract class > > BaseToPrettyTextConverter > > > > > extends > > > > > > BaseReflectorTransformer > > > > > > + implements > > DecoratedConverter, > > > > > ImpreciseConverter { > > > > > > > > > > > > private String prefix; > > > > > > private String suffix; > > > > > > @@ -161,4 +164,19 @@ > > > > > > public void setShowNullValues(boolean > > > > > showNullValues) { > > > > > > this.showNullValues = > > > > > showNullValues; > > > > > > } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Get the intermediate class passed > > to > > > > > the text converter. > > > > > > + * @return > > > > > > + */ > > > > > > + protected Class > > getIntermediateClass() { > > > > > > + return StringBuffer.class; > > > > > > + } > > > > > > } > > > > > > Index: > > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > src/core/net/sf/morph/util/NumberUtils.java > > > > > (revision 365) > > > > > > +++ > > src/core/net/sf/morph/util/NumberUtils.java > > > > > (working copy) > > > > > > @@ -19,6 +19,7 @@ > > > > > > import java.lang.reflect.Method; > > > > > > import java.math.BigDecimal; > > > > > > import java.math.BigInteger; > > > > > > +import java.util.Comparator; > > > > > > import java.util.HashMap; > > > > > > import java.util.HashSet; > > > > > > import java.util.Iterator; > > > > > > @@ -69,6 +70,31 @@ > > > > > > } > > > > > > } > > > > > > > > > > > > + private static class > > > > NarrownessComparator > > > > > implements Comparator { > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + public int compare(Object > > arg0, > > > > > Object arg1) { > > > > > > + if (arg0 == arg1) { > > > > > > + return 0; > > > > > > + } > > > > > > + Class c0 = > > > > getType(arg0); > > > > > > + Class c1 = > > > > getType(arg1); > > > > > > + if (c0 == c1 || c0 > > == > > > > null > > > > > || c1 == null) { > > > > > > + return 0; > > > > > > + } > > > > > > + return > > > > > > > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > > + } > > > > > > + > > > > > > + private Class getType(Object > > o) > > > > { > > > > > > + if > > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > > + return > > (Class) > > > > o; > > > > > > + } > > > > > > + Class test = > > > > > ClassUtils.getClass(o); > > > > > > + return > > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > > > : null; > > > > > > + } > > > > > > + } > > > > > > + > > > > > > /** > > > > > > * A Map of BigDecimals keyed by > > Class > > > > that > > > > > indicate the maximum > > > > > > value that > > > > > > * the given (Number) Class may taken > > on. > > > > > > @@ -80,11 +106,16 @@ > > > > > > * the given (Number) Class may taken > > on. > > > > > > */ > > > > > > public static final Map > > > > MINIMUMS_FOR_TYPES; > > > > > > - > > > > > > - public static final Map > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > > > - public static final Map > > > > NUMBER_FACTORIES; > > > > > > + /** > > > > > > + * Comparator of class/object type > > > > > narrowness. > > > > > > + */ > > > > > > + public static final Comparator > > > > > NARROWNESS_COMPARATOR = new > > > > > > NarrownessComparator(); > > > > > > > > > > > > + private static final Map > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > + > > > > > > + private static final Map > > > > NUMBER_FACTORIES; > > > > > > + > > > > > > /** > > > > > > * Used by {@link > > > > > NumberUtils#isNumber(Class)}. > > > > > > */ > > > > > > Index: > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > (revision 357) > > > > > > +++ > > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > > Version > > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -26,6 +26,7 @@ > > > > > > import net.sf.morph.transform.Converter; > > > > > > import net.sf.morph.transform.Copier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import net.sf.morph.transform.Transformer; > > > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * Learn whether > > > > > <code>transformer</code>'s conversion > > > > > > + * of <code>sourceClass</code> to > > > > > <code>destinationClass</code> > > > > > > might yield an imprecise result. > > > > > > + * @param transformer > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + * @see ImpreciseConverter > > > > > > + */ > > > > > > + public static boolean > > > > > isImpreciseConversion(Transformer > > > > > > transformer, > > > > > > + Class > > destinationClass, > > > > > Class sourceClass) { > > > > > > + if (transformer instanceof > > > > > ImpreciseConverter) { > > > > > > + return > > > > > ((ImpreciseConverter) > > > > > > transformer).isImpreciseConversion( > > > > > > + > > > > > destinationClass, sourceClass); > > > > > > + } > > > > > > + return destinationClass == > > null > > > > && > > > > > sourceClass != null; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Performs a transformation of one > > > > object > > > > > graph into another > > > > > > object graph. > > > > > > * > > > > > > * @param destinationType > > > > > > > > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > > This SF.net email is sponsored by: Microsoft > > > > > > Defy all challenges. Microsoft(R) Visual > > Studio > > > > > 2005. > > > > > > > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > > > _______________________________________________ > > > > > > morph-developer mailing list > > > > > > mor...@li... > > > > > > > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > This message is intended only for the named > > > > > recipient. If you are not the > > > > > intended recipient, you are notified that > > > > > disclosing, copying, distributing, > > > > > or taking any action in reliance on the > > contents > > > > of > > > > > this information is > > > > > strictly prohibited. > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > This SF.net email is sponsored by: Microsoft > > > > > Defy all challenges. Microsoft(R) Visual > > Studio > > > > > 2005. > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > > _______________________________________________ > > > > > morph-developer mailing list > > > > > mor...@li... > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > Looking for last minute shopping deals? > > > > Find them fast with Yahoo! Search. > > > > > > > > > > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual Studio > > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > Be a better friend, newshound, and > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > ------------------------------------------------------------------------- > > > Check out the new SourceForge.net Marketplace. > > > It's the best place to buy or sell services for > > > just about anything Open Source. > > > > > > > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > -- > > This message is intended only for the named > > recipient. If you are not the > > intended recipient, you are notified that > > disclosing, copying, distributing, > > or taking any action in reliance on the contents of > > this information is > > strictly prohibited. > > > > ------------------------------------------------------------------------- > > Check out the new SourceForge.net Marketplace. > > It's the best place to buy or sell services for > > just about anything Open Source. > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Looking for last minute shopping deals? > Find them fast with Yahoo! Search. > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt B. <gud...@ya...> - 2008-01-10 17:14:56
|
You have a point, though I guess my aim in avoiding such a thing was that--usually--the path is simple enough to determine given source and dest classes. Secondly, you might use a different path depending on available source/dest combos, so the configuration might be a little more complex. :| As for where converters with awareness of "precision" might be useful, I can't say that I know of another context right now, but at the very least I would say it might be useful knowledge for both number and text types. -Matt --- Matt Sgarlata <mat...@sp...> wrote: > I agree, that does sound like it could end up being > somewhat arbitrary. I > know the original impetus for this was that > configuration of the > ChainedTransformer could be a real pain in the neck. > Are there other > situations where the information provided by > ImplicitTransformer or > PrecisionTransformer might be useful? I guess what > I'm getting at here is, > what is the requirement we are trying to solve? > Perhaps if we think about > it in a new way a different solution will present > itself. > > Perhaps an alternative could be to introduce a new > setTransformationPath(Class[] path) method to the > ChainedTransformer. That > would make configuration a snap, even if you were > trying to use dependency > injection for the configuration. > > Matt S > > On Jan 10, 2008 11:24 AM, Matt Benson > <gud...@ya...> wrote: > > > More on this: what do you think about the concept > of > > something like a PrecisionTransformer that returns > a > > float precision from 0.0 to 1.0 given a > > destinationClass and a sourceClass? These might > be > > somewhat arbitrary, or calculated (like with > numeric > > types), but they might allow a little more > > informedness on the part of the consumer. > > > > -Matt B > > > > --- Matt Benson <gud...@ya...> wrote: > > > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > wrote: > > > > > > > I have been thinking more about this approach, > and > > > > it's really starting to > > > > grow on me. I do have one concern though, can > > > this > > > > approach be extended to > > > > Copiers? For example, a Map -> Object copy > could > > > > probably be considered an > > > > imprecise transformation because the Map may > have > > > > more keys than the Object > > > > has properties. > > > > > > I thought about this as well. It could be done; > it > > > might be slightly complex calculating the > > > "precision" > > > of a PropertyNameMatchingCopier--I would think > an > > > explicitly specified PNMatchingC would be > precise; > > > an > > > imprecise one would be one using property name > > > discovery and where the properties of the source > are > > > not all available on the destination. > There--the > > > hard > > > part of that one is over. :) I will work on > > > ImpreciseConverter -> ImpreciseTransformer > extends > > > Transformer and other semantic changes as time > > > permits. Your ordering changes are, I expect, > fine > > > by > > > me as well. :) > > > > > > -Matt B > > > > > > > > > > > In addition to your approach, I also like the > idea > > > > of cleaning up the > > > > internal implementation in Morph so that > ordering > > > of > > > > source and destination > > > > classes is preserved for the following > reasons: > > > > 1) for at least some portion of users, setting > the > > > > order of source and > > > > destination classes will make sense as an > > > indication > > > > of the transformer's > > > > preferences for performing transformations (so > for > > > > this class of users, > > > > creating new transformers that play nicely > with > > > the > > > > ChainedTransformerTestCase will be simpler) > > > > 2) I think a general change from using > HashSets to > > > > ordered sets in Morph's > > > > implementation will mean transformations > happen > > > more > > > > consistently across > > > > JVMs and across time on the same JVM, leading > to a > > > > more stable platform > > > > > > > > So, what I did is I basically went through the > > > Morph > > > > codebase and replaced > > > > HashSets with ordered sets (preference order > is: > > > JDK > > > > 1.4 LinkedHashSet, > > > > Commons-collections ListOrderedSet, copy of > > > > ListOrderedSet in > > > > net.sf.morph.util). I was never able to > modify > > > the > > > > ChainedTransformerTestCase so that it > consistently > > > > threw an error. However, > > > > after working on the test case long enough, > > > > eventually something changed in > > > > my environment so that the test started to > fail. > > > I > > > > did my change of > > > > HashSets to ordered sets, and that was able to > fix > > > > the broken test. > > > > > > > > I checked in my changes for you to take a look > > > at... > > > > > > > > Matt S > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > Here's what I've got. > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > Be a better friend, newshound, and > > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with > the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -35,6 +35,7 @@ > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > import > net.sf.morph.transform.DecoratedCopier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import net.sf.morph.transform.NodeCopier; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > @@ -93,11 +94,11 @@ > > > > > * @since Dec 12, 2004 > > > > > */ > > > > > public class SimpleDelegatingTransformer > > > extends > > > > BaseCompositeTransformer > > > > > implements > > > > > - SpecializableComposite, > > > > ExplicitTransformer, Transformer, > > > > > DecoratedCopier, DecoratedConverter, > Cloneable { > > > > > + SpecializableComposite, > > > > ExplicitTransformer, Transformer, > > > > > DecoratedCopier, > > > > > + DecoratedConverter, > Cloneable, > > > > ImpreciseConverter { > > > > > > > > > > //TODO extract > BaseDelegatingTransformer > > > > with pluggable delegate > > > > > selection > > > > > > > > > > - > > > > > private static class MapThreadLocal > > > extends > > > > ThreadLocal { > > > > > protected Object > initialValue() { > > > > > return new HashMap(); > > > > > @@ -138,6 +139,7 @@ > > > > > } > > > > > > > > > > private Specializer specializer; > > > > > + private boolean > > > preferPreciseTransformers; > > > > > > > > > > private transient ThreadLocal > > > > > visitedSourceToDestinationMapThreadLocal = > new > > > > MapThreadLocal(); > > > > > private transient ThreadLocal > > > > stackDepthThreadLocal = new > > > > > StackDepthThreadLocal(); > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > /** > > > > > * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > TransformerUtils.isImpreciseConversion > > > > > (getTransformer(destinationClass, > > > > > + > sourceClass), > > > > destinationClass, > > > > > sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > * @see > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > */ > > > > > protected Class[] > getSourceClassesImpl() > > > > throws Exception { > > > > > @@ -477,6 +487,7 @@ > > > > > * if no suitable > transformer > > > > could be found > > > > > */ > > > > > private Transformer > getTransformer(Class > > > > transformerType, Class > > > > > destinationClass, Class sourceClass) throws > > > > TransformationException { > > > > > + Transformer candidate = > null; > > > > > for (int i = 0; i < > > > > components.length; i++) { > > > > > // if the transformer > is > > > > the correct type > > > > > Transformer > transformer = > > > > (Transformer) > > > > > components[i]; > > > > > @@ -484,6 +495,13 @@ > > > > > // if the > > > > transformer is capable of > > > > > performing the transformation > > > > > if > > > > (TransformerUtils.isTransformable( > > > > > > > > > transformer, > > > > > destinationClass, sourceClass)) { > > > > > + if > > > > (isPreferPreciseTransformers() > > > > > + > > > > > > > && candidate == > > > > > null > > > > > + > > > > > > > && > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > + > > > > > destinationClass, sourceClass)) { > > > > > + > > > > candidate = transformer; > > > > > + > > > > continue; > > > > > + } > > > > > if > > > > (getLog().isTraceEnabled()) { > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > > + > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > @@ -496,7 +514,9 @@ > > > > > > return > > > > transformer; > > > > > } > > > > > } > > > > > - > > > > > + if (candidate != > null) { > > > > > + return > > > candidate; > > > > > + } > > > > > } > > > > > throw new > > > TransformationException( > > > > > "Could not find a > > > > transformer that can transform > > > > > objects of " > > > > > @@ -612,4 +632,20 @@ > > > > > source); > > > > > } > > > > > > > > > > + /** > > > > > + * Get the > preferPreciseTransformers. > > > > > + * @return boolean > > > > > + */ > > > > > + public boolean > > > > isPreferPreciseTransformers() { > > > > > + return > > > preferPreciseTransformers; > > > > > + } > > > > > + > > > > > + /** > > > > > + * Set the > preferPreciseTransformers. > > > > Default false. > > > > > + * @param preferPreciseTransformers > the > > > > boolean to set > > > > > + */ > > > > > + public void > > > > setPreferPreciseTransformers(boolean > > > > > preferPreciseTransformers) { > > > > > + > this.preferPreciseTransformers = > > > > > preferPreciseTransformers; > > > > > + } > > > > > + > > > > > } > > > > > \ No newline at end of file > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > (revision 358) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > (working copy) > > > > > @@ -570,6 +570,35 @@ > > > > > } > > > > > } > > > > > > > > > > + /** > > > > > + * Implementation of > > > isImpreciseConversion > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return destinationClass == > null > > > && > > > > sourceClass != null; > > > > > + } > > > > > + > > > > > + /** > > > > > + * Learn whether the specified > > > conversion > > > > yields an imprecise > > > > > result. > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + */ > > > > > + public final boolean > > > > isImpreciseConversion(Class destinationClass, > > > > > Class sourceClass) { > > > > > + try { > > > > > + return > > > > isImpreciseConversionImpl(destinationClass, > > > > > sourceClass); > > > > > + } catch (Exception e) { > > > > > + if (e instanceof > > > > RuntimeException && > > > > > !isWrappingRuntimeExceptions()) { > > > > > + throw > > > > (RuntimeException) e; > > > > > + } > > > > > + throw new > > > > TransformationException("Could not > > > > > determine if conversion of " > > > > > + + > > > > sourceClass + " to " + > > > > > destinationClass > > > > > + + " > > > > results in a loss of > > > > > precision", e); > > > > > + } > > > > > + } > > > > > + > > > > > // property getters and setters > > > > > > > > > > /** > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with > the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -16,6 +16,7 @@ > > > > > package > net.sf.morph.transform.transformers; > > > > > > > > > > import java.util.ArrayList; > > > > > +import java.util.Iterator; > > > > > import java.util.List; > > > > > import java.util.Locale; > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > import > net.sf.morph.transform.DecoratedCopier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > import > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > @@ -40,7 +42,7 @@ > > > > > * @since Nov 24, 2004 > > > > > */ > > > > > public class ChainedTransformer extends > > > > BaseCompositeTransformer > > > > > implements > > > > > - DecoratedConverter, > > > > DecoratedCopier, ExplicitTransformer { > > > > > + DecoratedConverter, > > > > DecoratedCopier, ExplicitTransformer, > > > > > ImpreciseConverter { > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > } > > > > > > > > > > /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + List conversionPath = > > > > getConversionPath(destinationClass, > > > > > sourceClass); > > > > > + return > > > !isPrecise(conversionPath, > > > > sourceClass, 0); > > > > > + } > > > > > + > > > > > + /** > > > > > * Get the converter used when using > a > > > > ChainedTransformer as a > > > > > Copier. > > > > > * @return > > > > > */ > > > > > @@ -113,6 +123,7 @@ > > > > > throw new > > > > TransformationException(destinationClass, > > > > > sourceType, null, > > > > > > "Chained > > > > conversion path could not > > > > > be determined"); > > > > > } > > > > > + log.debug("Using chained > > > > conversion path " + > > > > > conversionPath); > > > > > Object o = source; > > > > > for (int i = 0; i < > > > > conversionPath.size(); i++) { > > > > > o = > > > > getConverter(chain[i]).convert((Class) > > > > > conversionPath.get(i), o, locale); > > > > > @@ -144,6 +155,7 @@ > > > > > throw new > > > > TransformationException(destinationClass, > > > > > source, null, > > > > > > "Chained > > > > conversion path could not > > > > > be determined"); > > > > > } > > > > > + log.debug("Using chained > > > > conversion path " + > > > > > conversionPath); > > > > > Object last = > > > > getCopyConverter().convert((Class) > > > > > conversionPath.get(chain.length - 2), > source, > > > > locale); > > > > > ((Copier) > > > copier).copy(destination, > > > > last, locale); > > > > > } > > > > > @@ -192,13 +204,7 @@ > > > > > * @return List > > > > > */ > > > > > protected List > getConversionPath(Class > > > > destinationType, Class > > > > > sourceType) { > > > > > - if (sourceType != null) { > > > > > - List withoutNull = > > > > > getConversionPath(destinationType, > sourceType, > > > 0, > > > > false); > > > > > - if (withoutNull != > null) > > > { > > > > > - return > > > > withoutNull; > > > > > - } > > > > > - } > > > > > - return > > > > getConversionPath(destinationType, sourceType, > 0, > > > > > true); > > > > > + return > > > > getConversionPath(destinationType, sourceType, > 0); > > > > > } > > > > > > > > > > /** > > > > > @@ -210,7 +216,7 @@ > > > > > * @param allowNull > > > > > * @return List > > > > > */ > > > > > - private List getConversionPath(Class > > > > destinationType, Class > > > > > sourceType, int index, boolean allowNull) { > > > > > + private List getConversionPath(Class > > > > destinationType, Class > > > > > sourceType, int index) { > > > > > Transformer[] chain = > getChain(); > > > > > Transformer c = chain[index]; > > > > > if (index + 1 == > chain.length) { > > > > > @@ -221,22 +227,38 @@ > > > > > } > > > > > return null; > > > > > } > > > > > + List possibleResult = null; > > > > > Class[] available = > > > > c.getDestinationClasses(); > > > > > for (int i = 0; i < > > > > available.length; i++) { > > > > > - if (available[i] == > null > > > > && !allowNull) { > > > > > - continue; > > > > > - } > > > > > if > > > > (TransformerUtils.isTransformable(c, > > > > > available[i], sourceType)) { > > > > > - List tail = > > > > > getConversionPath(destinationType, > available[i], > > > > index + 1, allowNull); > > > > > + List tail = > > > > > getConversionPath(destinationType, > available[i], > > > > index + 1); > > > > > if (tail != > null) > > > { > > > > > > > > tail.add(0, > > > > available[i]); > > > > > - > return > > > > tail; > > > > > + if > > > > (isPrecise(tail, sourceType, > > > > > index)) { > > > > > + > > > > return tail; > > > > > + } > > > > > + > > > > possibleResult = tail; > > > > > } > > > > > } > > > > > } > > > > > - return null; > > > > > + return possibleResult; > > > > > } > > > > > > > > > > + private boolean isPrecise(List > > > > conversionPath, Class sourceType, > > > > > int index) { > > > > > + Transformer[] chain = > > > getChain(); > > > > > + Class currentSource = > > > sourceType; > > > > > + int i = 0; > > > > > + for (Iterator iter = > > > > conversionPath.iterator(); > > > > > iter.hasNext(); i++) { > > > > > + Class currentDest = > > > > (Class) iter.next(); > > > > > + if > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > + i], currentDest, > > > > > + > > > > currentSource)) { > > > > > + return > false; > > > > > + } > > > > > + currentSource = > > > > currentDest; > > > > > + } > > > > > + return true; > > > > > + } > > > > > + > > > > > /** > > > > > * Get the components array narrowed > to a > > > > Transformer[]. > > > > > * @return Transformer[] > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > (revision > > > > > 0) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > (revision > > > > > 0) > > > > > @@ -0,0 +1,32 @@ > > > > > +/* > > > > > + * Copyright 2008 the original author or > > > authors. > > > > > + * > > > > > + * Licensed under the Apache License, > Version > > > 2.0 > > > > (the "License"); you > > > > > may not > > > > > + * use this file except in compliance with > the > > > > License. You may obtain a > > > > > copy of > > > > > + * the License at > > > > > + * > > > > > + * > http://www.apache.org/licenses/LICENSE-2.0 > > > > > + * > > > > > + * Unless required by applicable law or > agreed > > > to > > > > in writing, software > > > > > + * distributed under the License is > distributed > > > > on an "AS IS" BASIS, > > > > > WITHOUT > > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, > either > > > > express or implied. See > > > > > the > > > > > + * License for the specific language > governing > > > > permissions and > > > > > limitations under > > > > > + * the License. > > > > > + */ > > > > > +package net.sf.morph.transform; > > > > > + > > > > > +/** > > > > > + * Defines a converter whose operation may > > > result > > > > in a loss of data > > > > > precision. > > > > > + * > > > > > + * @author mbenson > > > > > + * @since Morph 1.0.2 > > > > > + */ > > > > > +public interface ImpreciseConverter extends > > > > Converter { > > > > > + /** > > > > > + * Learn whether the specified > > > conversion > > > > might yield an imprecise > > > > > result. > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + */ > > > > > + boolean isImpreciseConversion(Class > > > > destinationClass, Class > > > > > sourceClass); > > > > > +} > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > Name: svn:eol-style > > > > > + native > > > > > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > (working copy) > > > > > @@ -20,7 +20,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts an object to a textual > > > representation > > > > by calling the object's > > > > > @@ -32,7 +34,7 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 24, 2004 > > > > > */ > > > > > -public class ObjectToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class ObjectToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > private Converter textConverter; > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > (revision 361) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > (working copy) > > > > > @@ -32,7 +32,7 @@ > > > > > import > org.apache.commons.logging.LogFactory; > > > > > > > > > > /** > > > > > - * Converts basic text types into primtive > > > > numbers or {@link > > > > > java.lang.Number} > > > > > + * Converts basic text types into primitive > > > > numbers or {@link > > > > > java.lang.Number} > > > > > * objects. > > > > > * > > > > > * @author Matt Sgarlata > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > (revision 363) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > (working copy) > > > > > @@ -21,7 +21,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts {@link java.lang.Number}s into > basic > > > > text types ({@link > > > > > java.lang.String}, > > > > > @@ -30,7 +32,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Jan 26, 2006 > > > > > */ > > > > > -public class NumberToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class NumberToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > + ImpreciseConverter { > > > > > > > > > > private Converter textConverter; > > > > > private Converter numberConverter; > > > > > @@ -58,6 +61,13 @@ > > > > > } > > > > > > > > > > /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > * Get the number converter used by > this > > > > NumberToTextConverter. > > > > > * @return Converter > > > > > */ > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > (revision 360) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > (working copy) > > > > > @@ -22,7 +22,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts the basic time types ({@link > > > > java.util.Date} and > > > > > @@ -33,7 +35,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 31, 2004 > > > > > */ > > > > > -public class TimeToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class TimeToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > + ImpreciseConverter { > > > > > > > > > > private DateFormat dateFormat; > > > > > private Converter timeConverter; > > > > > @@ -55,6 +58,13 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > } > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > (working copy) > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > import net.sf.morph.util.ClassUtils; > > > > > @@ -43,7 +44,7 @@ > > > > > * @since Jan 2, 2005 > > > > > */ > > > > > public class TextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > - ExplicitTransformer { > > > > > + ExplicitTransformer, > > > > ImpreciseConverter { > > > > > > > > > > private static final Class > CHAR_SEQUENCE > > > = > > > > > ClassUtils.isJdk14OrHigherPresent() ? > ClassUtils > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > @@ -62,14 +63,7 @@ > > > > > s.add(Character.class); > > > > > s.add(char.class); > > > > > s.add(null); > > > > > - if (CHAR_SEQUENCE != null) { > > > > > - > s.add(CHAR_SEQUENCE); > > > > > - try { > > > > > - > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > StringBuffer.class.getConstructor(new > Class[] { > > > > String.class })); > > > > > - } catch (Exception > e) { > > > > > - //nope > > > > > - } > > > > > - } > > > > > + s.add(CHAR_SEQUENCE); > > > > > SOURCE_AND_DESTINATION_TYPES > = > > > > (Class[]) s.toArray(new > > > > > Class[s.size()]); > > > > > } > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > } > > > > > return new > > > > Character(string.charAt(0)); > > > > > } > > > > > - if (destinationClass == > > > > String.class) { > > > > > + if (destinationClass == > > > > String.class > > > > > + || > > > > (destinationClass == CHAR_SEQUENCE && > > > > > CHAR_SEQUENCE != null)) { > > > > > return string; > > > > > } > > > > > if (destinationClass == > > > > byte[].class) { > > > > > @@ -152,6 +147,16 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + if > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > sourceClass)) { > > > > > + return true; > > > > > + } > > > > > + return > isChar(destinationClass) > > > && > > > > !isChar(sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isAutomaticallyHandlingNulls() { > > > > > return !isEmptyNull(); > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > (working copy) > > > > > @@ -20,8 +20,10 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts boolean values to text values. > > > > Subclasses can build in > > > > > support for > > > > > @@ -32,10 +34,10 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Jan 9, 2005 > > > > > */ > > > > > -public class BooleanToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > - > > > > > +public class BooleanToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > + > > > > > private static final Class[] > SOURCE_TYPES > > > = > > > > { Boolean.class, > > > > > boolean.class }; > > > > > - > > > > > + > > > > > private Converter textConverter; > > > > > > > > > > /** > > > > > @@ -93,9 +95,16 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > - } > > > > > + } > > > > > > > > > > /** > > > > > * Get the text converter used by > this > > > > BaseToPrettyTextConverter. > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > (revision 363) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > (working copy) > > > > > @@ -19,6 +19,7 @@ > > > > > import java.util.Locale; > > > > > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > net.sf.morph.transform.support.NumberRounder; > > > > > import > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > @@ -31,8 +32,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 14, 2004 > > > > > */ > > > > > -public class NumberConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > - > > > > > +public class NumberConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > + > > > > > private static final Class[] > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > Number.class, byte.class, > > > > short.class, int.class, > > > > > long.class, > > > > > float.class, double.class, > null > > > > > @@ -116,9 +117,20 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > sourceClass) > > > > > + || > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > + > > > > sourceClass) < 0; > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected Object convertImpl(Class > > > > destinationClass, Object source, > > > > > Locale locale) throws > Exception { > > > > > - > > > > > + if (destinationClass == > null) { > > > > > + return null; > > > > > + } > > > > > if > > > (destinationClass.isPrimitive() > > > > && source == null) { > > > > > throw new > > > > TransformationException(destinationClass, > > > > > source); > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > (working copy) > > > > > @@ -18,7 +18,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Base class for converts that convert > objects > > > to > > > > a pretty > > > > > programmer-friendly > > > > > @@ -27,7 +29,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Feb 15, 2005 > > > > > */ > > > > > -public abstract class > BaseToPrettyTextConverter > > > > extends > > > > > BaseReflectorTransformer implements > > > > DecoratedConverter { > > > > > +public abstract class > BaseToPrettyTextConverter > > > > extends > > > > > BaseReflectorTransformer > > > > > + implements > DecoratedConverter, > > > > ImpreciseConverter { > > > > > > > > > > private String prefix; > > > > > private String suffix; > > > > > @@ -161,4 +164,19 @@ > > > > > public void setShowNullValues(boolean > > > > showNullValues) { > > > > > this.showNullValues = > > > > showNullValues; > > > > > } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * Get the intermediate class passed > to > > > > the text converter. > > > > > + * @return > > > > > + */ > > > > > + protected Class > getIntermediateClass() { > > > > > + return StringBuffer.class; > > > > > + } > > > > > } > > > > > Index: > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > src/core/net/sf/morph/util/NumberUtils.java > > > > (revision 365) > > > > > +++ > src/core/net/sf/morph/util/NumberUtils.java > > > > (working copy) > > > > > @@ -19,6 +19,7 @@ > > > > > import java.lang.reflect.Method; > > > > > import java.math.BigDecimal; > > > > > import java.math.BigInteger; > > > > > +import java.util.Comparator; > > > > > import java.util.HashMap; > > > > > import java.util.HashSet; > > > > > import java.util.Iterator; > > > > > @@ -69,6 +70,31 @@ > > > > > } > > > > > } > > > > > > > > > > + private static class > > > NarrownessComparator > > > > implements Comparator { > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + public int compare(Object > arg0, > > > > Object arg1) { > > > > > + if (arg0 == arg1) { > > > > > + return 0; > > > > > + } > > > > > + Class c0 = > > > getType(arg0); > > > > > + Class c1 = > > > getType(arg1); > > > > > + if (c0 == c1 || c0 > == > > > null > > > > || c1 == null) { > > > > > + return 0; > > > > > + } > > > > > + return > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > + } > > > > > + > > > > > + private Class getType(Object > o) > > > { > > > > > + if > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > + return > (Class) > > > o; > > > > > + } > > > > > + Class test = > > > > ClassUtils.getClass(o); > > > > > + return > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > > : null; > > > > > + } > > > > > + } > > > > > + > > > > > /** > > > > > * A Map of BigDecimals keyed by > Class > > > that > > > > indicate the maximum > > > > > value that > > > > > * the given (Number) Class may taken > on. > > > > > @@ -80,11 +106,16 @@ > > > > > * the given (Number) Class may taken > on. > > > > > */ > > > > > public static final Map > > > MINIMUMS_FOR_TYPES; > > > > > - > > > > > - public static final Map > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > - public static final Map > > > NUMBER_FACTORIES; > > > > > + /** > > > > > + * Comparator of class/object type > > > > narrowness. > > > > > + */ > > > > > + public static final Comparator > > > > NARROWNESS_COMPARATOR = new > > > > > NarrownessComparator(); > > > > > > > > > > + private static final Map > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > + > > > > > + private static final Map > > > NUMBER_FACTORIES; > > > > > + > > > > > /** > > > > > * Used by {@link > > > > NumberUtils#isNumber(Class)}. > > > > > */ > > > > > Index: > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > (revision 357) > > > > > +++ > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with > the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -26,6 +26,7 @@ > > > > > import net.sf.morph.transform.Converter; > > > > > import net.sf.morph.transform.Copier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > } > > > > > > > > > > /** > > > > > + * Learn whether > > > > <code>transformer</code>'s conversion > > > > > + * of <code>sourceClass</code> to > > > > <code>destinationClass</code> > > > > > might yield an imprecise result. > > > > > + * @param transformer > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + * @see ImpreciseConverter > > > > > + */ > > > > > + public static boolean > > > > isImpreciseConversion(Transformer > > > > > transformer, > > > > > + Class > destinationClass, > > > > Class sourceClass) { > > > > > + if (transformer instanceof > > > > ImpreciseConverter) { > > > > > + return > > > > ((ImpreciseConverter) > > > > > transformer).isImpreciseConversion( > > > > > + > > > > destinationClass, sourceClass); > > > > > + } > > > > > + return destinationClass == > null > > > && > > > > sourceClass != null; > > > > > + } > > > > > + > > > > > + /** > > > > > * Performs a transformation of one > > > object > > > > graph into another > > > > > object graph. > > > > > * > > > > > * @param destinationType > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > This SF.net email is sponsored by: Microsoft > > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > > 2005. > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > _______________________________________________ > > > > > morph-developer mailing list > > > > > mor...@li... > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > -- > > > > This message is intended only for the named > > > > recipient. If you are not the > > > > intended recipient, you are notified that > > > > disclosing, copying, distributing, > > > > or taking any action in reliance on the > contents > > > of > > > > this information is > > > > strictly prohibited. > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > Looking for last minute shopping deals? > > > Find them fast with Yahoo! Search. > > > > > > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2005. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Be a better friend, newshound, and > > know-it-all with Yahoo! Mobile. Try it now. > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > ------------------------------------------------------------------------- > > Check out the new SourceForge.net Marketplace. > > It's the best place to buy or sell services for > > just about anything Open Source. > > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Looking for last minute shopping deals? Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping |
From: Matt S. <mat...@sp...> - 2008-01-10 17:04:30
|
I agree, that does sound like it could end up being somewhat arbitrary. I know the original impetus for this was that configuration of the ChainedTransformer could be a real pain in the neck. Are there other situations where the information provided by ImplicitTransformer or PrecisionTransformer might be useful? I guess what I'm getting at here is, what is the requirement we are trying to solve? Perhaps if we think about it in a new way a different solution will present itself. Perhaps an alternative could be to introduce a new setTransformationPath(Class[] path) method to the ChainedTransformer. That would make configuration a snap, even if you were trying to use dependency injection for the configuration. Matt S On Jan 10, 2008 11:24 AM, Matt Benson <gud...@ya...> wrote: > More on this: what do you think about the concept of > something like a PrecisionTransformer that returns a > float precision from 0.0 to 1.0 given a > destinationClass and a sourceClass? These might be > somewhat arbitrary, or calculated (like with numeric > types), but they might allow a little more > informedness on the part of the consumer. > > -Matt B > > --- Matt Benson <gud...@ya...> wrote: > > > > > --- Matt Sgarlata > > <mat...@sp...> > > wrote: > > > > > I have been thinking more about this approach, and > > > it's really starting to > > > grow on me. I do have one concern though, can > > this > > > approach be extended to > > > Copiers? For example, a Map -> Object copy could > > > probably be considered an > > > imprecise transformation because the Map may have > > > more keys than the Object > > > has properties. > > > > I thought about this as well. It could be done; it > > might be slightly complex calculating the > > "precision" > > of a PropertyNameMatchingCopier--I would think an > > explicitly specified PNMatchingC would be precise; > > an > > imprecise one would be one using property name > > discovery and where the properties of the source are > > not all available on the destination. There--the > > hard > > part of that one is over. :) I will work on > > ImpreciseConverter -> ImpreciseTransformer extends > > Transformer and other semantic changes as time > > permits. Your ordering changes are, I expect, fine > > by > > me as well. :) > > > > -Matt B > > > > > > > > In addition to your approach, I also like the idea > > > of cleaning up the > > > internal implementation in Morph so that ordering > > of > > > source and destination > > > classes is preserved for the following reasons: > > > 1) for at least some portion of users, setting the > > > order of source and > > > destination classes will make sense as an > > indication > > > of the transformer's > > > preferences for performing transformations (so for > > > this class of users, > > > creating new transformers that play nicely with > > the > > > ChainedTransformerTestCase will be simpler) > > > 2) I think a general change from using HashSets to > > > ordered sets in Morph's > > > implementation will mean transformations happen > > more > > > consistently across > > > JVMs and across time on the same JVM, leading to a > > > more stable platform > > > > > > So, what I did is I basically went through the > > Morph > > > codebase and replaced > > > HashSets with ordered sets (preference order is: > > JDK > > > 1.4 LinkedHashSet, > > > Commons-collections ListOrderedSet, copy of > > > ListOrderedSet in > > > net.sf.morph.util). I was never able to modify > > the > > > ChainedTransformerTestCase so that it consistently > > > threw an error. However, > > > after working on the test case long enough, > > > eventually something changed in > > > my environment so that the test started to fail. > > I > > > did my change of > > > HashSets to ordered sets, and that was able to fix > > > the broken test. > > > > > > I checked in my changes for you to take a look > > at... > > > > > > Matt S > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > Here's what I've got. > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > Be a better friend, newshound, and > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > Index: > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > (revision 357) > > > > +++ > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -35,6 +35,7 @@ > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > import net.sf.morph.transform.DecoratedCopier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import net.sf.morph.transform.NodeCopier; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > @@ -93,11 +94,11 @@ > > > > * @since Dec 12, 2004 > > > > */ > > > > public class SimpleDelegatingTransformer > > extends > > > BaseCompositeTransformer > > > > implements > > > > - SpecializableComposite, > > > ExplicitTransformer, Transformer, > > > > DecoratedCopier, DecoratedConverter, Cloneable { > > > > + SpecializableComposite, > > > ExplicitTransformer, Transformer, > > > > DecoratedCopier, > > > > + DecoratedConverter, Cloneable, > > > ImpreciseConverter { > > > > > > > > //TODO extract BaseDelegatingTransformer > > > with pluggable delegate > > > > selection > > > > > > > > - > > > > private static class MapThreadLocal > > extends > > > ThreadLocal { > > > > protected Object initialValue() { > > > > return new HashMap(); > > > > @@ -138,6 +139,7 @@ > > > > } > > > > > > > > private Specializer specializer; > > > > + private boolean > > preferPreciseTransformers; > > > > > > > > private transient ThreadLocal > > > > visitedSourceToDestinationMapThreadLocal = new > > > MapThreadLocal(); > > > > private transient ThreadLocal > > > stackDepthThreadLocal = new > > > > StackDepthThreadLocal(); > > > > @@ -225,6 +227,14 @@ > > > > > > > > /** > > > > * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > TransformerUtils.isImpreciseConversion > > > > (getTransformer(destinationClass, > > > > + sourceClass), > > > destinationClass, > > > > sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > * @see > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > */ > > > > protected Class[] getSourceClassesImpl() > > > throws Exception { > > > > @@ -477,6 +487,7 @@ > > > > * if no suitable transformer > > > could be found > > > > */ > > > > private Transformer getTransformer(Class > > > transformerType, Class > > > > destinationClass, Class sourceClass) throws > > > TransformationException { > > > > + Transformer candidate = null; > > > > for (int i = 0; i < > > > components.length; i++) { > > > > // if the transformer is > > > the correct type > > > > Transformer transformer = > > > (Transformer) > > > > components[i]; > > > > @@ -484,6 +495,13 @@ > > > > // if the > > > transformer is capable of > > > > performing the transformation > > > > if > > > (TransformerUtils.isTransformable( > > > > > > > transformer, > > > > destinationClass, sourceClass)) { > > > > + if > > > (isPreferPreciseTransformers() > > > > + > > > > > && candidate == > > > > null > > > > + > > > > > && > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > + > > > > destinationClass, sourceClass)) { > > > > + > > > candidate = transformer; > > > > + > > > continue; > > > > + } > > > > if > > > (getLog().isTraceEnabled()) { > > > > > > > getLog().trace("Using " > > > > > > > > > + > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > @@ -496,7 +514,9 @@ > > > > return > > > transformer; > > > > } > > > > } > > > > - > > > > + if (candidate != null) { > > > > + return > > candidate; > > > > + } > > > > } > > > > throw new > > TransformationException( > > > > "Could not find a > > > transformer that can transform > > > > objects of " > > > > @@ -612,4 +632,20 @@ > > > > source); > > > > } > > > > > > > > + /** > > > > + * Get the preferPreciseTransformers. > > > > + * @return boolean > > > > + */ > > > > + public boolean > > > isPreferPreciseTransformers() { > > > > + return > > preferPreciseTransformers; > > > > + } > > > > + > > > > + /** > > > > + * Set the preferPreciseTransformers. > > > Default false. > > > > + * @param preferPreciseTransformers the > > > boolean to set > > > > + */ > > > > + public void > > > setPreferPreciseTransformers(boolean > > > > preferPreciseTransformers) { > > > > + this.preferPreciseTransformers = > > > > preferPreciseTransformers; > > > > + } > > > > + > > > > } > > > > \ No newline at end of file > > > > Index: > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > (revision 358) > > > > +++ > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > (working copy) > > > > @@ -570,6 +570,35 @@ > > > > } > > > > } > > > > > > > > + /** > > > > + * Implementation of > > isImpreciseConversion > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return destinationClass == null > > && > > > sourceClass != null; > > > > + } > > > > + > > > > + /** > > > > + * Learn whether the specified > > conversion > > > yields an imprecise > > > > result. > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + */ > > > > + public final boolean > > > isImpreciseConversion(Class destinationClass, > > > > Class sourceClass) { > > > > + try { > > > > + return > > > isImpreciseConversionImpl(destinationClass, > > > > sourceClass); > > > > + } catch (Exception e) { > > > > + if (e instanceof > > > RuntimeException && > > > > !isWrappingRuntimeExceptions()) { > > > > + throw > > > (RuntimeException) e; > > > > + } > > > > + throw new > > > TransformationException("Could not > > > > determine if conversion of " > > > > + + > > > sourceClass + " to " + > > > > destinationClass > > > > + + " > > > results in a loss of > > > > precision", e); > > > > + } > > > > + } > > > > + > > > > // property getters and setters > > > > > > > > /** > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > (revision 357) > > > > +++ > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -16,6 +16,7 @@ > > > > package net.sf.morph.transform.transformers; > > > > > > > > import java.util.ArrayList; > > > > +import java.util.Iterator; > > > > import java.util.List; > > > > import java.util.Locale; > > > > > > > > @@ -25,6 +26,7 @@ > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > import net.sf.morph.transform.DecoratedCopier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > import > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > @@ -40,7 +42,7 @@ > > > > * @since Nov 24, 2004 > > > > */ > > > > public class ChainedTransformer extends > > > BaseCompositeTransformer > > > > implements > > > > - DecoratedConverter, > > > DecoratedCopier, ExplicitTransformer { > > > > + DecoratedConverter, > > > DecoratedCopier, ExplicitTransformer, > > > > ImpreciseConverter { > > > > > > > > private Converter copyConverter; > > > > > > > > @@ -67,6 +69,14 @@ > > > > } > > > > > > > > /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + List conversionPath = > > > getConversionPath(destinationClass, > > > > sourceClass); > > > > + return > > !isPrecise(conversionPath, > > > sourceClass, 0); > > > > + } > > > > + > > > > + /** > > > > * Get the converter used when using a > > > ChainedTransformer as a > > > > Copier. > > > > * @return > > > > */ > > > > @@ -113,6 +123,7 @@ > > > > throw new > > > TransformationException(destinationClass, > > > > sourceType, null, > > > > "Chained > > > conversion path could not > > > > be determined"); > > > > } > > > > + log.debug("Using chained > > > conversion path " + > > > > conversionPath); > > > > Object o = source; > > > > for (int i = 0; i < > > > conversionPath.size(); i++) { > > > > o = > > > getConverter(chain[i]).convert((Class) > > > > conversionPath.get(i), o, locale); > > > > @@ -144,6 +155,7 @@ > > > > throw new > > > TransformationException(destinationClass, > > > > source, null, > > > > "Chained > > > conversion path could not > > > > be determined"); > > > > } > > > > + log.debug("Using chained > > > conversion path " + > > > > conversionPath); > > > > Object last = > > > getCopyConverter().convert((Class) > > > > conversionPath.get(chain.length - 2), source, > > > locale); > > > > ((Copier) > > copier).copy(destination, > > > last, locale); > > > > } > > > > @@ -192,13 +204,7 @@ > > > > * @return List > > > > */ > > > > protected List getConversionPath(Class > > > destinationType, Class > > > > sourceType) { > > > > - if (sourceType != null) { > > > > - List withoutNull = > > > > getConversionPath(destinationType, sourceType, > > 0, > > > false); > > > > - if (withoutNull != null) > > { > > > > - return > > > withoutNull; > > > > - } > > > > - } > > > > - return > > > getConversionPath(destinationType, sourceType, 0, > > > > true); > > > > + return > > > getConversionPath(destinationType, sourceType, 0); > > > > } > > > > > > > > /** > > > > @@ -210,7 +216,7 @@ > > > > * @param allowNull > > > > * @return List > > > > */ > > > > - private List getConversionPath(Class > > > destinationType, Class > > > > sourceType, int index, boolean allowNull) { > > > > + private List getConversionPath(Class > > > destinationType, Class > > > > sourceType, int index) { > > > > Transformer[] chain = getChain(); > > > > Transformer c = chain[index]; > > > > if (index + 1 == chain.length) { > > > > @@ -221,22 +227,38 @@ > > > > } > > > > return null; > > > > } > > > > + List possibleResult = null; > > > > Class[] available = > > > c.getDestinationClasses(); > > > > for (int i = 0; i < > > > available.length; i++) { > > > > - if (available[i] == null > > > && !allowNull) { > > > > - continue; > > > > - } > > > > if > > > (TransformerUtils.isTransformable(c, > > > > available[i], sourceType)) { > > > > - List tail = > > > > getConversionPath(destinationType, available[i], > > > index + 1, allowNull); > > > > + List tail = > > > > getConversionPath(destinationType, available[i], > > > index + 1); > > > > if (tail != null) > > { > > > > > > tail.add(0, > > > available[i]); > > > > - return > > > tail; > > > > + if > > > (isPrecise(tail, sourceType, > > > > index)) { > > > > + > > > return tail; > > > > + } > > > > + > > > possibleResult = tail; > > > > } > > > > } > > > > } > > > > - return null; > > > > + return possibleResult; > > > > } > > > > > > > > + private boolean isPrecise(List > > > conversionPath, Class sourceType, > > > > int index) { > > > > + Transformer[] chain = > > getChain(); > > > > + Class currentSource = > > sourceType; > > > > + int i = 0; > > > > + for (Iterator iter = > > > conversionPath.iterator(); > > > > iter.hasNext(); i++) { > > > > + Class currentDest = > > > (Class) iter.next(); > > > > + if > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > + i], currentDest, > > > > + > > > currentSource)) { > > > > + return false; > > > > + } > > > > + currentSource = > > > currentDest; > > > > + } > > > > + return true; > > > > + } > > > > + > > > > /** > > > > * Get the components array narrowed to a > > > Transformer[]. > > > > * @return Transformer[] > > > > Index: > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > (revision > > > > 0) > > > > +++ > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > (revision > > > > 0) > > > > @@ -0,0 +1,32 @@ > > > > +/* > > > > + * Copyright 2008 the original author or > > authors. > > > > + * > > > > + * Licensed under the Apache License, Version > > 2.0 > > > (the "License"); you > > > > may not > > > > + * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > + * the License at > > > > + * > > > > + * http://www.apache.org/licenses/LICENSE-2.0 > > > > + * > > > > + * Unless required by applicable law or agreed > > to > > > in writing, software > > > > + * distributed under the License is distributed > > > on an "AS IS" BASIS, > > > > WITHOUT > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, either > > > express or implied. See > > > > the > > > > + * License for the specific language governing > > > permissions and > > > > limitations under > > > > + * the License. > > > > + */ > > > > +package net.sf.morph.transform; > > > > + > > > > +/** > > > > + * Defines a converter whose operation may > > result > > > in a loss of data > > > > precision. > > > > + * > > > > + * @author mbenson > > > > + * @since Morph 1.0.2 > > > > + */ > > > > +public interface ImpreciseConverter extends > > > Converter { > > > > + /** > > > > + * Learn whether the specified > > conversion > > > might yield an imprecise > > > > result. > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + */ > > > > + boolean isImpreciseConversion(Class > > > destinationClass, Class > > > > sourceClass); > > > > +} > > > > > > > > Property changes on: > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > ___________________________________________________________________ > > > > Name: svn:eol-style > > > > + native > > > > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > (working copy) > > > > @@ -20,7 +20,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts an object to a textual > > representation > > > by calling the object's > > > > @@ -32,7 +34,7 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 24, 2004 > > > > */ > > > > -public class ObjectToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class ObjectToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > private Converter textConverter; > > > > > > > > @@ -52,6 +54,13 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > (revision 361) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > (working copy) > > > > @@ -32,7 +32,7 @@ > > > > import org.apache.commons.logging.LogFactory; > > > > > > > > /** > > > > - * Converts basic text types into primtive > > > numbers or {@link > > > > java.lang.Number} > > > > + * Converts basic text types into primitive > > > numbers or {@link > > > > java.lang.Number} > > > > * objects. > > > > * > > > > * @author Matt Sgarlata > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > (revision 363) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > (working copy) > > > > @@ -21,7 +21,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts {@link java.lang.Number}s into basic > > > text types ({@link > > > > java.lang.String}, > > > > @@ -30,7 +32,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Jan 26, 2006 > > > > */ > > > > -public class NumberToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class NumberToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > + ImpreciseConverter { > > > > > > > > private Converter textConverter; > > > > private Converter numberConverter; > > > > @@ -58,6 +61,13 @@ > > > > } > > > > > > > > /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > * Get the number converter used by this > > > NumberToTextConverter. > > > > * @return Converter > > > > */ > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > (revision 360) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > (working copy) > > > > @@ -22,7 +22,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts the basic time types ({@link > > > java.util.Date} and > > > > @@ -33,7 +35,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 31, 2004 > > > > */ > > > > -public class TimeToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class TimeToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > + ImpreciseConverter { > > > > > > > > private DateFormat dateFormat; > > > > private Converter timeConverter; > > > > @@ -55,6 +58,13 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > } > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > (revision 357) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > (working copy) > > > > @@ -22,6 +22,7 @@ > > > > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > import net.sf.morph.util.ClassUtils; > > > > @@ -43,7 +44,7 @@ > > > > * @since Jan 2, 2005 > > > > */ > > > > public class TextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > - ExplicitTransformer { > > > > + ExplicitTransformer, > > > ImpreciseConverter { > > > > > > > > private static final Class CHAR_SEQUENCE > > = > > > > ClassUtils.isJdk14OrHigherPresent() ? ClassUtils > > > > > > > .convertToClass("java.lang.CharSequence") > > > > @@ -62,14 +63,7 @@ > > > > s.add(Character.class); > > > > s.add(char.class); > > > > s.add(null); > > > > - if (CHAR_SEQUENCE != null) { > > > > - s.add(CHAR_SEQUENCE); > > > > - try { > > > > - > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > StringBuffer.class.getConstructor(new Class[] { > > > String.class })); > > > > - } catch (Exception e) { > > > > - //nope > > > > - } > > > > - } > > > > + s.add(CHAR_SEQUENCE); > > > > SOURCE_AND_DESTINATION_TYPES = > > > (Class[]) s.toArray(new > > > > Class[s.size()]); > > > > } > > > > > > > > @@ -106,7 +100,8 @@ > > > > } > > > > return new > > > Character(string.charAt(0)); > > > > } > > > > - if (destinationClass == > > > String.class) { > > > > + if (destinationClass == > > > String.class > > > > + || > > > (destinationClass == CHAR_SEQUENCE && > > > > CHAR_SEQUENCE != null)) { > > > > return string; > > > > } > > > > if (destinationClass == > > > byte[].class) { > > > > @@ -152,6 +147,16 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + if > > > (super.isImpreciseConversionImpl(destinationClass, > > > > sourceClass)) { > > > > + return true; > > > > + } > > > > + return isChar(destinationClass) > > && > > > !isChar(sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isAutomaticallyHandlingNulls() { > > > > return !isEmptyNull(); > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > (working copy) > > > > @@ -20,8 +20,10 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts boolean values to text values. > > > Subclasses can build in > > > > support for > > > > @@ -32,10 +34,10 @@ > > > > * @author Matt Sgarlata > > > > * @since Jan 9, 2005 > > > > */ > > > > -public class BooleanToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > - > > > > +public class BooleanToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > + > > > > private static final Class[] SOURCE_TYPES > > = > > > { Boolean.class, > > > > boolean.class }; > > > > - > > > > + > > > > private Converter textConverter; > > > > > > > > /** > > > > @@ -93,9 +95,16 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > - } > > > > + } > > > > > > > > /** > > > > * Get the text converter used by this > > > BaseToPrettyTextConverter. > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > (revision 363) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > (working copy) > > > > @@ -19,6 +19,7 @@ > > > > import java.util.Locale; > > > > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > net.sf.morph.transform.support.NumberRounder; > > > > import > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > @@ -31,8 +32,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 14, 2004 > > > > */ > > > > -public class NumberConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > - > > > > +public class NumberConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > + > > > > private static final Class[] > > > SOURCE_AND_DESTINATION_TYPES = { > > > > Number.class, byte.class, > > > short.class, int.class, > > > > long.class, > > > > float.class, double.class, null > > > > @@ -116,9 +117,20 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > super.isImpreciseConversionImpl(destinationClass, > > > > sourceClass) > > > > + || > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > + > > > sourceClass) < 0; > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected Object convertImpl(Class > > > destinationClass, Object source, > > > > Locale locale) throws Exception { > > > > - > > > > + if (destinationClass == null) { > > > > + return null; > > > > + } > > > > if > > (destinationClass.isPrimitive() > > > && source == null) { > > > > throw new > > > TransformationException(destinationClass, > > > > source); > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > (working copy) > > > > @@ -18,7 +18,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Base class for converts that convert objects > > to > > > a pretty > > > > programmer-friendly > > > > @@ -27,7 +29,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Feb 15, 2005 > > > > */ > > > > -public abstract class BaseToPrettyTextConverter > > > extends > > > > BaseReflectorTransformer implements > > > DecoratedConverter { > > > > +public abstract class BaseToPrettyTextConverter > > > extends > > > > BaseReflectorTransformer > > > > + implements DecoratedConverter, > > > ImpreciseConverter { > > > > > > > > private String prefix; > > > > private String suffix; > > > > @@ -161,4 +164,19 @@ > > > > public void setShowNullValues(boolean > > > showNullValues) { > > > > this.showNullValues = > > > showNullValues; > > > > } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * Get the intermediate class passed to > > > the text converter. > > > > + * @return > > > > + */ > > > > + protected Class getIntermediateClass() { > > > > + return StringBuffer.class; > > > > + } > > > > } > > > > Index: > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > =================================================================== > > > > --- src/core/net/sf/morph/util/NumberUtils.java > > > (revision 365) > > > > +++ src/core/net/sf/morph/util/NumberUtils.java > > > (working copy) > > > > @@ -19,6 +19,7 @@ > > > > import java.lang.reflect.Method; > > > > import java.math.BigDecimal; > > > > import java.math.BigInteger; > > > > +import java.util.Comparator; > > > > import java.util.HashMap; > > > > import java.util.HashSet; > > > > import java.util.Iterator; > > > > @@ -69,6 +70,31 @@ > > > > } > > > > } > > > > > > > > + private static class > > NarrownessComparator > > > implements Comparator { > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > + public int compare(Object arg0, > > > Object arg1) { > > > > + if (arg0 == arg1) { > > > > + return 0; > > > > + } > > > > + Class c0 = > > getType(arg0); > > > > + Class c1 = > > getType(arg1); > > > > + if (c0 == c1 || c0 == > > null > > > || c1 == null) { > > > > + return 0; > > > > + } > > > > + return > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > + } > > > > + > > > > + private Class getType(Object o) > > { > > > > + if > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > + return (Class) > > o; > > > > + } > > > > + Class test = > > > ClassUtils.getClass(o); > > > > + return > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > : null; > > > > + } > > > > + } > > > > + > > > > /** > > > > * A Map of BigDecimals keyed by Class > > that > > > indicate the maximum > > > > value that > > > > * the given (Number) Class may taken on. > > > > @@ -80,11 +106,16 @@ > > > > * the given (Number) Class may taken on. > > > > */ > > > > public static final Map > > MINIMUMS_FOR_TYPES; > > > > - > > > > - public static final Map > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > - public static final Map > > NUMBER_FACTORIES; > > > > + /** > > > > + * Comparator of class/object type > > > narrowness. > > > > + */ > > > > + public static final Comparator > > > NARROWNESS_COMPARATOR = new > > > > NarrownessComparator(); > > > > > > > > + private static final Map > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > + > > > > + private static final Map > > NUMBER_FACTORIES; > > > > + > > > > /** > > > > * Used by {@link > > > NumberUtils#isNumber(Class)}. > > > > */ > > > > Index: > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > =================================================================== > > > > --- > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > (revision 357) > > > > +++ > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -26,6 +26,7 @@ > > > > import net.sf.morph.transform.Converter; > > > > import net.sf.morph.transform.Copier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > > > > > @@ -90,6 +91,24 @@ > > > > } > > > > > > > > /** > > > > + * Learn whether > > > <code>transformer</code>'s conversion > > > > + * of <code>sourceClass</code> to > > > <code>destinationClass</code> > > > > might yield an imprecise result. > > > > + * @param transformer > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + * @see ImpreciseConverter > > > > + */ > > > > + public static boolean > > > isImpreciseConversion(Transformer > > > > transformer, > > > > + Class destinationClass, > > > Class sourceClass) { > > > > + if (transformer instanceof > > > ImpreciseConverter) { > > > > + return > > > ((ImpreciseConverter) > > > > transformer).isImpreciseConversion( > > > > + > > > destinationClass, sourceClass); > > > > + } > > > > + return destinationClass == null > > && > > > sourceClass != null; > > > > + } > > > > + > > > > + /** > > > > * Performs a transformation of one > > object > > > graph into another > > > > object graph. > > > > * > > > > * @param destinationType > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > -- > > > This message is intended only for the named > > > recipient. If you are not the > > > intended recipient, you are notified that > > > disclosing, copying, distributing, > > > or taking any action in reliance on the contents > > of > > > this information is > > > strictly prohibited. > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2005. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Looking for last minute shopping deals? > > Find them fast with Yahoo! Search. > > > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > > 2005. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Be a better friend, newshound, and > know-it-all with Yahoo! Mobile. Try it now. > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt B. <gud...@ya...> - 2008-01-10 16:24:13
|
More on this: what do you think about the concept of something like a PrecisionTransformer that returns a float precision from 0.0 to 1.0 given a destinationClass and a sourceClass? These might be somewhat arbitrary, or calculated (like with numeric types), but they might allow a little more informedness on the part of the consumer. -Matt B --- Matt Benson <gud...@ya...> wrote: > > --- Matt Sgarlata > <mat...@sp...> > wrote: > > > I have been thinking more about this approach, and > > it's really starting to > > grow on me. I do have one concern though, can > this > > approach be extended to > > Copiers? For example, a Map -> Object copy could > > probably be considered an > > imprecise transformation because the Map may have > > more keys than the Object > > has properties. > > I thought about this as well. It could be done; it > might be slightly complex calculating the > "precision" > of a PropertyNameMatchingCopier--I would think an > explicitly specified PNMatchingC would be precise; > an > imprecise one would be one using property name > discovery and where the properties of the source are > not all available on the destination. There--the > hard > part of that one is over. :) I will work on > ImpreciseConverter -> ImpreciseTransformer extends > Transformer and other semantic changes as time > permits. Your ordering changes are, I expect, fine > by > me as well. :) > > -Matt B > > > > > In addition to your approach, I also like the idea > > of cleaning up the > > internal implementation in Morph so that ordering > of > > source and destination > > classes is preserved for the following reasons: > > 1) for at least some portion of users, setting the > > order of source and > > destination classes will make sense as an > indication > > of the transformer's > > preferences for performing transformations (so for > > this class of users, > > creating new transformers that play nicely with > the > > ChainedTransformerTestCase will be simpler) > > 2) I think a general change from using HashSets to > > ordered sets in Morph's > > implementation will mean transformations happen > more > > consistently across > > JVMs and across time on the same JVM, leading to a > > more stable platform > > > > So, what I did is I basically went through the > Morph > > codebase and replaced > > HashSets with ordered sets (preference order is: > JDK > > 1.4 LinkedHashSet, > > Commons-collections ListOrderedSet, copy of > > ListOrderedSet in > > net.sf.morph.util). I was never able to modify > the > > ChainedTransformerTestCase so that it consistently > > threw an error. However, > > after working on the test case long enough, > > eventually something changed in > > my environment so that the test started to fail. > I > > did my change of > > HashSets to ordered sets, and that was able to fix > > the broken test. > > > > I checked in my changes for you to take a look > at... > > > > Matt S > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > <gud...@ya...> wrote: > > > > > Here's what I've got. > > > > > > -Matt B > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > Be a better friend, newshound, and > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > Index: > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > =================================================================== > > > --- > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > (revision 357) > > > +++ > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > (working copy) > > > @@ -1,5 +1,5 @@ > > > /* > > > - * Copyright 2004-2005, 2007 the original > author > > or authors. > > > + * Copyright 2004-2005, 2007-2008 the original > > author or authors. > > > * > > > * Licensed under the Apache License, Version > 2.0 > > (the "License"); you may > > > not > > > * use this file except in compliance with the > > License. You may obtain a > > > copy of > > > @@ -35,6 +35,7 @@ > > > import > net.sf.morph.transform.DecoratedConverter; > > > import net.sf.morph.transform.DecoratedCopier; > > > import > > net.sf.morph.transform.ExplicitTransformer; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import net.sf.morph.transform.NodeCopier; > > > import > > net.sf.morph.transform.TransformationException; > > > import net.sf.morph.transform.Transformer; > > > @@ -93,11 +94,11 @@ > > > * @since Dec 12, 2004 > > > */ > > > public class SimpleDelegatingTransformer > extends > > BaseCompositeTransformer > > > implements > > > - SpecializableComposite, > > ExplicitTransformer, Transformer, > > > DecoratedCopier, DecoratedConverter, Cloneable { > > > + SpecializableComposite, > > ExplicitTransformer, Transformer, > > > DecoratedCopier, > > > + DecoratedConverter, Cloneable, > > ImpreciseConverter { > > > > > > //TODO extract BaseDelegatingTransformer > > with pluggable delegate > > > selection > > > > > > - > > > private static class MapThreadLocal > extends > > ThreadLocal { > > > protected Object initialValue() { > > > return new HashMap(); > > > @@ -138,6 +139,7 @@ > > > } > > > > > > private Specializer specializer; > > > + private boolean > preferPreciseTransformers; > > > > > > private transient ThreadLocal > > > visitedSourceToDestinationMapThreadLocal = new > > MapThreadLocal(); > > > private transient ThreadLocal > > stackDepthThreadLocal = new > > > StackDepthThreadLocal(); > > > @@ -225,6 +227,14 @@ > > > > > > /** > > > * {@inheritDoc} > > > + */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > TransformerUtils.isImpreciseConversion > > > (getTransformer(destinationClass, > > > + sourceClass), > > destinationClass, > > > sourceClass); > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > * @see > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > */ > > > protected Class[] getSourceClassesImpl() > > throws Exception { > > > @@ -477,6 +487,7 @@ > > > * if no suitable transformer > > could be found > > > */ > > > private Transformer getTransformer(Class > > transformerType, Class > > > destinationClass, Class sourceClass) throws > > TransformationException { > > > + Transformer candidate = null; > > > for (int i = 0; i < > > components.length; i++) { > > > // if the transformer is > > the correct type > > > Transformer transformer = > > (Transformer) > > > components[i]; > > > @@ -484,6 +495,13 @@ > > > // if the > > transformer is capable of > > > performing the transformation > > > if > > (TransformerUtils.isTransformable( > > > > > transformer, > > > destinationClass, sourceClass)) { > > > + if > > (isPreferPreciseTransformers() > > > + > > > && candidate == > > > null > > > + > > > && > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > + > > > destinationClass, sourceClass)) { > > > + > > candidate = transformer; > > > + > > continue; > > > + } > > > if > > (getLog().isTraceEnabled()) { > > > > > getLog().trace("Using " > > > > > > + > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > @@ -496,7 +514,9 @@ > > > return > > transformer; > > > } > > > } > > > - > > > + if (candidate != null) { > > > + return > candidate; > > > + } > > > } > > > throw new > TransformationException( > > > "Could not find a > > transformer that can transform > > > objects of " > > > @@ -612,4 +632,20 @@ > > > source); > > > } > > > > > > + /** > > > + * Get the preferPreciseTransformers. > > > + * @return boolean > > > + */ > > > + public boolean > > isPreferPreciseTransformers() { > > > + return > preferPreciseTransformers; > > > + } > > > + > > > + /** > > > + * Set the preferPreciseTransformers. > > Default false. > > > + * @param preferPreciseTransformers the > > boolean to set > > > + */ > > > + public void > > setPreferPreciseTransformers(boolean > > > preferPreciseTransformers) { > > > + this.preferPreciseTransformers = > > > preferPreciseTransformers; > > > + } > > > + > > > } > > > \ No newline at end of file > > > Index: > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > (revision 358) > > > +++ > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > (working copy) > > > @@ -570,6 +570,35 @@ > > > } > > > } > > > > > > + /** > > > + * Implementation of > isImpreciseConversion > > > + * @param destinationClass > > > + * @param sourceClass > > > + * @return > > > + */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return destinationClass == null > && > > sourceClass != null; > > > + } > > > + > > > + /** > > > + * Learn whether the specified > conversion > > yields an imprecise > > > result. > > > + * @param destinationClass > > > + * @param sourceClass > > > + * @return boolean > > > + */ > > > + public final boolean > > isImpreciseConversion(Class destinationClass, > > > Class sourceClass) { > > > + try { > > > + return > > isImpreciseConversionImpl(destinationClass, > > > sourceClass); > > > + } catch (Exception e) { > > > + if (e instanceof > > RuntimeException && > > > !isWrappingRuntimeExceptions()) { > > > + throw > > (RuntimeException) e; > > > + } > > > + throw new > > TransformationException("Could not > > > determine if conversion of " > > > + + > > sourceClass + " to " + > > > destinationClass > > > + + " > > results in a loss of > > > precision", e); > > > + } > > > + } > > > + > > > // property getters and setters > > > > > > /** > > > Index: > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > (revision 357) > > > +++ > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > (working copy) > > > @@ -1,5 +1,5 @@ > > > /* > > > - * Copyright 2004-2005, 2007 the original > author > > or authors. > > > + * Copyright 2004-2005, 2007-2008 the original > > author or authors. > > > * > > > * Licensed under the Apache License, Version > 2.0 > > (the "License"); you may > > > not > > > * use this file except in compliance with the > > License. You may obtain a > > > copy of > > > @@ -16,6 +16,7 @@ > > > package net.sf.morph.transform.transformers; > > > > > > import java.util.ArrayList; > > > +import java.util.Iterator; > > > import java.util.List; > > > import java.util.Locale; > > > > > > @@ -25,6 +26,7 @@ > > > import > net.sf.morph.transform.DecoratedConverter; > > > import net.sf.morph.transform.DecoratedCopier; > > > import > > net.sf.morph.transform.ExplicitTransformer; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > net.sf.morph.transform.TransformationException; > > > import net.sf.morph.transform.Transformer; > > > import > > net.sf.morph.transform.copiers.CopierDecorator; > > > @@ -40,7 +42,7 @@ > > > * @since Nov 24, 2004 > > > */ > > > public class ChainedTransformer extends > > BaseCompositeTransformer > > > implements > > > - DecoratedConverter, > > DecoratedCopier, ExplicitTransformer { > > > + DecoratedConverter, > > DecoratedCopier, ExplicitTransformer, > > > ImpreciseConverter { > > > > > > private Converter copyConverter; > > > > > > @@ -67,6 +69,14 @@ > > > } > > > > > > /** > > > + * {@inheritDoc} > > > + */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + List conversionPath = > > getConversionPath(destinationClass, > > > sourceClass); > > > + return > !isPrecise(conversionPath, > > sourceClass, 0); > > > + } > > > + > > > + /** > > > * Get the converter used when using a > > ChainedTransformer as a > > > Copier. > > > * @return > > > */ > > > @@ -113,6 +123,7 @@ > > > throw new > > TransformationException(destinationClass, > > > sourceType, null, > > > "Chained > > conversion path could not > > > be determined"); > > > } > > > + log.debug("Using chained > > conversion path " + > > > conversionPath); > > > Object o = source; > > > for (int i = 0; i < > > conversionPath.size(); i++) { > > > o = > > getConverter(chain[i]).convert((Class) > > > conversionPath.get(i), o, locale); > > > @@ -144,6 +155,7 @@ > > > throw new > > TransformationException(destinationClass, > > > source, null, > > > "Chained > > conversion path could not > > > be determined"); > > > } > > > + log.debug("Using chained > > conversion path " + > > > conversionPath); > > > Object last = > > getCopyConverter().convert((Class) > > > conversionPath.get(chain.length - 2), source, > > locale); > > > ((Copier) > copier).copy(destination, > > last, locale); > > > } > > > @@ -192,13 +204,7 @@ > > > * @return List > > > */ > > > protected List getConversionPath(Class > > destinationType, Class > > > sourceType) { > > > - if (sourceType != null) { > > > - List withoutNull = > > > getConversionPath(destinationType, sourceType, > 0, > > false); > > > - if (withoutNull != null) > { > > > - return > > withoutNull; > > > - } > > > - } > > > - return > > getConversionPath(destinationType, sourceType, 0, > > > true); > > > + return > > getConversionPath(destinationType, sourceType, 0); > > > } > > > > > > /** > > > @@ -210,7 +216,7 @@ > > > * @param allowNull > > > * @return List > > > */ > > > - private List getConversionPath(Class > > destinationType, Class > > > sourceType, int index, boolean allowNull) { > > > + private List getConversionPath(Class > > destinationType, Class > > > sourceType, int index) { > > > Transformer[] chain = getChain(); > > > Transformer c = chain[index]; > > > if (index + 1 == chain.length) { > > > @@ -221,22 +227,38 @@ > > > } > > > return null; > > > } > > > + List possibleResult = null; > > > Class[] available = > > c.getDestinationClasses(); > > > for (int i = 0; i < > > available.length; i++) { > > > - if (available[i] == null > > && !allowNull) { > > > - continue; > > > - } > > > if > > (TransformerUtils.isTransformable(c, > > > available[i], sourceType)) { > > > - List tail = > > > getConversionPath(destinationType, available[i], > > index + 1, allowNull); > > > + List tail = > > > getConversionPath(destinationType, available[i], > > index + 1); > > > if (tail != null) > { > > > > tail.add(0, > > available[i]); > > > - return > > tail; > > > + if > > (isPrecise(tail, sourceType, > > > index)) { > > > + > > return tail; > > > + } > > > + > > possibleResult = tail; > > > } > > > } > > > } > > > - return null; > > > + return possibleResult; > > > } > > > > > > + private boolean isPrecise(List > > conversionPath, Class sourceType, > > > int index) { > > > + Transformer[] chain = > getChain(); > > > + Class currentSource = > sourceType; > > > + int i = 0; > > > + for (Iterator iter = > > conversionPath.iterator(); > > > iter.hasNext(); i++) { > > > + Class currentDest = > > (Class) iter.next(); > > > + if > > > (TransformerUtils.isImpreciseConversion(chain[index > > > + i], currentDest, > > > + > > currentSource)) { > > > + return false; > > > + } > > > + currentSource = > > currentDest; > > > + } > > > + return true; > > > + } > > > + > > > /** > > > * Get the components array narrowed to a > > Transformer[]. > > > * @return Transformer[] > > > Index: > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > (revision > > > 0) > > > +++ > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > (revision > > > 0) > > > @@ -0,0 +1,32 @@ > > > +/* > > > + * Copyright 2008 the original author or > authors. > > > + * > > > + * Licensed under the Apache License, Version > 2.0 > > (the "License"); you > > > may not > > > + * use this file except in compliance with the > > License. You may obtain a > > > copy of > > > + * the License at > > > + * > > > + * http://www.apache.org/licenses/LICENSE-2.0 > > > + * > > > + * Unless required by applicable law or agreed > to > > in writing, software > > > + * distributed under the License is distributed > > on an "AS IS" BASIS, > > > WITHOUT > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, either > > express or implied. See > > > the > > > + * License for the specific language governing > > permissions and > > > limitations under > > > + * the License. > > > + */ > > > +package net.sf.morph.transform; > > > + > > > +/** > > > + * Defines a converter whose operation may > result > > in a loss of data > > > precision. > > > + * > > > + * @author mbenson > > > + * @since Morph 1.0.2 > > > + */ > > > +public interface ImpreciseConverter extends > > Converter { > > > + /** > > > + * Learn whether the specified > conversion > > might yield an imprecise > > > result. > > > + * @param destinationClass > > > + * @param sourceClass > > > + * @return boolean > > > + */ > > > + boolean isImpreciseConversion(Class > > destinationClass, Class > > > sourceClass); > > > +} > > > > > > Property changes on: > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > ___________________________________________________________________ > > > Name: svn:eol-style > > > + native > > > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > (revision 362) > > > +++ > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > (working copy) > > > @@ -20,7 +20,9 @@ > > > import net.sf.morph.Defaults; > > > import net.sf.morph.transform.Converter; > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > +import net.sf.morph.util.TransformerUtils; > > > > > > /** > > > * Converts an object to a textual > representation > > by calling the object's > > > @@ -32,7 +34,7 @@ > > > * @author Matt Sgarlata > > > * @since Dec 24, 2004 > > > */ > > > -public class ObjectToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter { > > > +public class ObjectToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter, ImpreciseConverter { > > > > > > private Converter textConverter; > > > > > > @@ -52,6 +54,13 @@ > > > /** > > > * {@inheritDoc} > > > */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > destinationClass, String.class); > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > protected boolean > > isWrappingRuntimeExceptions() { > > > return true; > > > } > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > (revision 361) > > > +++ > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > (working copy) > > > @@ -32,7 +32,7 @@ > > > import org.apache.commons.logging.LogFactory; > > > > > > /** > > > - * Converts basic text types into primtive > > numbers or {@link > > > java.lang.Number} > > > + * Converts basic text types into primitive > > numbers or {@link > > > java.lang.Number} > > > * objects. > > > * > > > * @author Matt Sgarlata > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > (revision 363) > > > +++ > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > (working copy) > > > @@ -21,7 +21,9 @@ > > > import net.sf.morph.Defaults; > > > import net.sf.morph.transform.Converter; > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > +import net.sf.morph.util.TransformerUtils; > > > > > > /** > > > * Converts {@link java.lang.Number}s into basic > > text types ({@link > > > java.lang.String}, > > > @@ -30,7 +32,8 @@ > > > * @author Matt Sgarlata > > > * @since Jan 26, 2006 > > > */ > > > -public class NumberToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter { > > > +public class NumberToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter, > > > + ImpreciseConverter { > > > > > > private Converter textConverter; > > > private Converter numberConverter; > > > @@ -58,6 +61,13 @@ > > > } > > > > > > /** > > > + * {@inheritDoc} > > > + */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > destinationClass, String.class); > > > + } > > > + > > > + /** > > > * Get the number converter used by this > > NumberToTextConverter. > > > * @return Converter > > > */ > > > Index: > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > (revision 360) > > > +++ > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > (working copy) > > > @@ -22,7 +22,9 @@ > > > import net.sf.morph.Defaults; > > > import net.sf.morph.transform.Converter; > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > +import net.sf.morph.util.TransformerUtils; > > > > > > /** > > > * Converts the basic time types ({@link > > java.util.Date} and > > > @@ -33,7 +35,8 @@ > > > * @author Matt Sgarlata > > > * @since Dec 31, 2004 > > > */ > > > -public class TimeToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter { > > > +public class TimeToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter, > > > + ImpreciseConverter { > > > > > > private DateFormat dateFormat; > > > private Converter timeConverter; > > > @@ -55,6 +58,13 @@ > > > /** > > > * {@inheritDoc} > > > */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > destinationClass, String.class); > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > protected boolean > > isWrappingRuntimeExceptions() { > > > return true; > > > } > > > Index: > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > (revision 357) > > > +++ > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > (working copy) > > > @@ -22,6 +22,7 @@ > > > > > > import > net.sf.morph.transform.DecoratedConverter; > > > import > > net.sf.morph.transform.ExplicitTransformer; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > net.sf.morph.transform.TransformationException; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > import net.sf.morph.util.ClassUtils; > > > @@ -43,7 +44,7 @@ > > > * @since Jan 2, 2005 > > > */ > > > public class TextConverter extends > > BaseTransformer implements > > > DecoratedConverter, > > > - ExplicitTransformer { > > > + ExplicitTransformer, > > ImpreciseConverter { > > > > > > private static final Class CHAR_SEQUENCE > = > > > ClassUtils.isJdk14OrHigherPresent() ? ClassUtils > > > > > .convertToClass("java.lang.CharSequence") > > > @@ -62,14 +63,7 @@ > > > s.add(Character.class); > > > s.add(char.class); > > > s.add(null); > > > - if (CHAR_SEQUENCE != null) { > > > - s.add(CHAR_SEQUENCE); > > > - try { > > > - > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > StringBuffer.class.getConstructor(new Class[] { > > String.class })); > > > - } catch (Exception e) { > > > - //nope > > > - } > > > - } > > > + s.add(CHAR_SEQUENCE); > > > SOURCE_AND_DESTINATION_TYPES = > > (Class[]) s.toArray(new > > > Class[s.size()]); > > > } > > > > > > @@ -106,7 +100,8 @@ > > > } > > > return new > > Character(string.charAt(0)); > > > } > > > - if (destinationClass == > > String.class) { > > > + if (destinationClass == > > String.class > > > + || > > (destinationClass == CHAR_SEQUENCE && > > > CHAR_SEQUENCE != null)) { > > > return string; > > > } > > > if (destinationClass == > > byte[].class) { > > > @@ -152,6 +147,16 @@ > > > /** > > > * {@inheritDoc} > > > */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + if > > (super.isImpreciseConversionImpl(destinationClass, > > > sourceClass)) { > > > + return true; > > > + } > > > + return isChar(destinationClass) > && > > !isChar(sourceClass); > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > protected boolean > > isAutomaticallyHandlingNulls() { > > > return !isEmptyNull(); > > > } > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > (revision 362) > > > +++ > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > (working copy) > > > @@ -20,8 +20,10 @@ > > > import net.sf.morph.Defaults; > > > import net.sf.morph.transform.Converter; > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > net.sf.morph.transform.TransformationException; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > +import net.sf.morph.util.TransformerUtils; > > > > > > /** > > > * Converts boolean values to text values. > > Subclasses can build in > > > support for > > > @@ -32,10 +34,10 @@ > > > * @author Matt Sgarlata > > > * @since Jan 9, 2005 > > > */ > > > -public class BooleanToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter { > > > - > > > +public class BooleanToTextConverter extends > > BaseTransformer implements > > > DecoratedConverter, ImpreciseConverter { > > > + > > > private static final Class[] SOURCE_TYPES > = > > { Boolean.class, > > > boolean.class }; > > > - > > > + > > > private Converter textConverter; > > > > > > /** > > > @@ -93,9 +95,16 @@ > > > /** > > > * {@inheritDoc} > > > */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > destinationClass, String.class); > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > protected boolean > > isWrappingRuntimeExceptions() { > > > return true; > > > - } > > > + } > > > > > > /** > > > * Get the text converter used by this > > BaseToPrettyTextConverter. > > > Index: > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > =================================================================== > > > --- > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > (revision 363) > > > +++ > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > (working copy) > > > @@ -19,6 +19,7 @@ > > > import java.util.Locale; > > > > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > net.sf.morph.transform.TransformationException; > > > import > > net.sf.morph.transform.support.NumberRounder; > > > import > > > net.sf.morph.transform.transformers.BaseTransformer; > > > @@ -31,8 +32,8 @@ > > > * @author Matt Sgarlata > > > * @since Dec 14, 2004 > > > */ > > > -public class NumberConverter extends > > BaseTransformer implements > > > DecoratedConverter { > > > - > > > +public class NumberConverter extends > > BaseTransformer implements > > > DecoratedConverter, ImpreciseConverter { > > > + > > > private static final Class[] > > SOURCE_AND_DESTINATION_TYPES = { > > > Number.class, byte.class, > > short.class, int.class, > > > long.class, > > > float.class, double.class, null > > > @@ -116,9 +117,20 @@ > > > /** > > > * {@inheritDoc} > > > */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > super.isImpreciseConversionImpl(destinationClass, > > > sourceClass) > > > + || > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > + > > sourceClass) < 0; > > > + } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > protected Object convertImpl(Class > > destinationClass, Object source, > > > Locale locale) throws Exception { > > > - > > > + if (destinationClass == null) { > > > + return null; > > > + } > > > if > (destinationClass.isPrimitive() > > && source == null) { > > > throw new > > TransformationException(destinationClass, > > > source); > > > } > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > =================================================================== > > > --- > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > (revision 362) > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > (working copy) > > > @@ -18,7 +18,9 @@ > > > import net.sf.morph.Defaults; > > > import net.sf.morph.transform.Converter; > > > import > net.sf.morph.transform.DecoratedConverter; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > +import net.sf.morph.util.TransformerUtils; > > > > > > /** > > > * Base class for converts that convert objects > to > > a pretty > > > programmer-friendly > > > @@ -27,7 +29,8 @@ > > > * @author Matt Sgarlata > > > * @since Feb 15, 2005 > > > */ > > > -public abstract class BaseToPrettyTextConverter > > extends > > > BaseReflectorTransformer implements > > DecoratedConverter { > > > +public abstract class BaseToPrettyTextConverter > > extends > > > BaseReflectorTransformer > > > + implements DecoratedConverter, > > ImpreciseConverter { > > > > > > private String prefix; > > > private String suffix; > > > @@ -161,4 +164,19 @@ > > > public void setShowNullValues(boolean > > showNullValues) { > > > this.showNullValues = > > showNullValues; > > > } > > > + > > > + /** > > > + * {@inheritDoc} > > > + */ > > > + protected boolean > > isImpreciseConversionImpl(Class > > > destinationClass, Class sourceClass) { > > > + return > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > destinationClass, sourceClass); > > > + } > > > + > > > + /** > > > + * Get the intermediate class passed to > > the text converter. > > > + * @return > > > + */ > > > + protected Class getIntermediateClass() { > > > + return StringBuffer.class; > > > + } > > > } > > > Index: > src/core/net/sf/morph/util/NumberUtils.java > > > > > > =================================================================== > > > --- src/core/net/sf/morph/util/NumberUtils.java > > (revision 365) > > > +++ src/core/net/sf/morph/util/NumberUtils.java > > (working copy) > > > @@ -19,6 +19,7 @@ > > > import java.lang.reflect.Method; > > > import java.math.BigDecimal; > > > import java.math.BigInteger; > > > +import java.util.Comparator; > > > import java.util.HashMap; > > > import java.util.HashSet; > > > import java.util.Iterator; > > > @@ -69,6 +70,31 @@ > > > } > > > } > > > > > > + private static class > NarrownessComparator > > implements Comparator { > > > + /** > > > + * {@inheritDoc} > > > + */ > > > + public int compare(Object arg0, > > Object arg1) { > > > + if (arg0 == arg1) { > > > + return 0; > > > + } > > > + Class c0 = > getType(arg0); > > > + Class c1 = > getType(arg1); > > > + if (c0 == c1 || c0 == > null > > || c1 == null) { > > > + return 0; > > > + } > > > + return > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > + } > > > + > > > + private Class getType(Object o) > { > > > + if > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > + return (Class) > o; > > > + } > > > + Class test = > > ClassUtils.getClass(o); > > > + return > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > : null; > > > + } > > > + } > > > + > > > /** > > > * A Map of BigDecimals keyed by Class > that > > indicate the maximum > > > value that > > > * the given (Number) Class may taken on. > > > @@ -80,11 +106,16 @@ > > > * the given (Number) Class may taken on. > > > */ > > > public static final Map > MINIMUMS_FOR_TYPES; > > > - > > > - public static final Map > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > - public static final Map > NUMBER_FACTORIES; > > > + /** > > > + * Comparator of class/object type > > narrowness. > > > + */ > > > + public static final Comparator > > NARROWNESS_COMPARATOR = new > > > NarrownessComparator(); > > > > > > + private static final Map > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > + > > > + private static final Map > NUMBER_FACTORIES; > > > + > > > /** > > > * Used by {@link > > NumberUtils#isNumber(Class)}. > > > */ > > > Index: > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > =================================================================== > > > --- > > src/core/net/sf/morph/util/TransformerUtils.java > > > (revision 357) > > > +++ > > src/core/net/sf/morph/util/TransformerUtils.java > > > (working copy) > > > @@ -1,5 +1,5 @@ > > > /* > > > - * Copyright 2004-2005, 2007 the original > author > > or authors. > > > + * Copyright 2004-2005, 2007-2008 the original > > author or authors. > > > * > > > * Licensed under the Apache License, Version > 2.0 > > (the "License"); you may > > > not > > > * use this file except in compliance with the > > License. You may obtain a > > > copy of > > > @@ -26,6 +26,7 @@ > > > import net.sf.morph.transform.Converter; > > > import net.sf.morph.transform.Copier; > > > import > > net.sf.morph.transform.ExplicitTransformer; > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > import > > net.sf.morph.transform.TransformationException; > > > import net.sf.morph.transform.Transformer; > > > > > > @@ -90,6 +91,24 @@ > > > } > > > > > > /** > > > + * Learn whether > > <code>transformer</code>'s conversion > > > + * of <code>sourceClass</code> to > > <code>destinationClass</code> > > > might yield an imprecise result. > > > + * @param transformer > > > + * @param destinationClass > > > + * @param sourceClass > > > + * @return boolean > > > + * @see ImpreciseConverter > > > + */ > > > + public static boolean > > isImpreciseConversion(Transformer > > > transformer, > > > + Class destinationClass, > > Class sourceClass) { > > > + if (transformer instanceof > > ImpreciseConverter) { > > > + return > > ((ImpreciseConverter) > > > transformer).isImpreciseConversion( > > > + > > destinationClass, sourceClass); > > > + } > > > + return destinationClass == null > && > > sourceClass != null; > > > + } > > > + > > > + /** > > > * Performs a transformation of one > object > > graph into another > > > object graph. > > > * > > > * @param destinationType > > > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > 2005. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > -- > > This message is intended only for the named > > recipient. If you are not the > > intended recipient, you are notified that > > disclosing, copying, distributing, > > or taking any action in reliance on the contents > of > > this information is > > strictly prohibited. > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > > 2005. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Looking for last minute shopping deals? > Find them fast with Yahoo! Search. > http://tools.search.yahoo.com/newsearch/category.php?category=shopping > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio > 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ |
From: Matt B. <gud...@ya...> - 2008-01-08 15:24:23
|
Ahhh... ;) --- Matt Sgarlata <mat...@sp...> wrote: > I actually put it in the Composite package because > that's where a lot of > similar calls are.... > > Matt > > On Jan 7, 2008 12:39 PM, Matt Benson > <gud...@ya...> wrote: > > > I got the renamed call, but the method still seems > to > > be missing on ClassUtils. ;) > > > > --- Matt Sgarlata > <mat...@sp...> > > wrote: > > > > > Sorry about that! I renamed the method > > > isCommonsCollections3Present because > > > the class referenced is new in 3.x (I meant to > do > > > this before, but I > > > forgot). > > > > > > Matt S > > > > > > On Jan 7, 2008 11:32 AM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > > > > > --- Matt Sgarlata > > > <mat...@sp...> > > > > wrote: > > > > > > > > > I have been thinking more about this > approach, > > > and > > > > > it's really starting to > > > > > grow on me. I do have one concern though, > can > > > this > > > > > approach be extended to > > > > > Copiers? For example, a Map -> Object copy > > > could > > > > > probably be considered an > > > > > imprecise transformation because the Map may > > > have > > > > > more keys than the Object > > > > > has properties. > > > > > > > > > > In addition to your approach, I also like > the > > > idea > > > > > of cleaning up the > > > > > internal implementation in Morph so that > > > ordering of > > > > > source and destination > > > > > classes is preserved for the following > reasons: > > > > > 1) for at least some portion of users, > setting > > > the > > > > > order of source and > > > > > destination classes will make sense as an > > > indication > > > > > of the transformer's > > > > > preferences for performing transformations > (so > > > for > > > > > this class of users, > > > > > creating new transformers that play nicely > with > > > the > > > > > ChainedTransformerTestCase will be simpler) > > > > > 2) I think a general change from using > HashSets > > > to > > > > > ordered sets in Morph's > > > > > implementation will mean transformations > happen > > > more > > > > > consistently across > > > > > JVMs and across time on the same JVM, > leading to > > > a > > > > > more stable platform > > > > > > > > > > So, what I did is I basically went through > the > > > Morph > > > > > codebase and replaced > > > > > HashSets with ordered sets (preference order > is: > > > JDK > > > > > 1.4 LinkedHashSet, > > > > > Commons-collections ListOrderedSet, copy of > > > > > ListOrderedSet in > > > > > net.sf.morph.util). I was never able to > modify > > > the > > > > > ChainedTransformerTestCase so that it > > > consistently > > > > > threw an error. However, > > > > > after working on the test case long enough, > > > > > eventually something changed in > > > > > my environment so that the test started to > fail. > > > I > > > > > did my change of > > > > > HashSets to ordered sets, and that was able > to > > > fix > > > > > the broken test. > > > > > > > > I seem to be missing a > > > > ClassUtils.isCommonsCollectionsPresent() > method > > > after > > > > syncing. I'll create my own for now, but it > does > > > seem > > > > to be missing. Thanks! > > > > > > > > -Matt B > > > > > > > > > > > > > > I checked in my changes for you to take a > look > > > at... > > > > > > > > > > Matt S > > > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > > <gud...@ya...> wrote: > > > > > > > > > > > Here's what I've got. > > > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > > Be a better friend, newshound, and > > > > > > know-it-all with Yahoo! Mobile. Try it > now. > > > > > > > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -35,6 +35,7 @@ > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > > net.sf.morph.transform.DecoratedCopier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import net.sf.morph.transform.NodeCopier; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > @@ -93,11 +94,11 @@ > > > > > > * @since Dec 12, 2004 > > > > > > */ > > > > > > public class SimpleDelegatingTransformer > > > extends > > > > > BaseCompositeTransformer > > > > > > implements > > > > > > - SpecializableComposite, > > > > > ExplicitTransformer, Transformer, > > > > > > DecoratedCopier, DecoratedConverter, > Cloneable > > > { > > > > > > + SpecializableComposite, > > > > > ExplicitTransformer, Transformer, > > > > > > DecoratedCopier, > > > > > > + DecoratedConverter, > Cloneable, > > > > > ImpreciseConverter { > > > > > > > > > > > > //TODO extract > > > BaseDelegatingTransformer > > > > > with pluggable delegate > > > > > > selection > > > > > > > > > > > > - > > > > > > private static class MapThreadLocal > > > extends > > > > > ThreadLocal { > > > > > > protected Object > initialValue() > > > { > > > > > > return new > HashMap(); > > > > > > @@ -138,6 +139,7 @@ > > > > > > } > > > > > > > > > > > > private Specializer specializer; > > > > > > + private boolean > > > preferPreciseTransformers; > > > > > > > > > > > > private transient ThreadLocal > > > > > > visitedSourceToDestinationMapThreadLocal = > new > > > > > MapThreadLocal(); > > > > > > private transient ThreadLocal > > > > > stackDepthThreadLocal = new > > > > > > StackDepthThreadLocal(); > > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > TransformerUtils.isImpreciseConversion > > > > > > (getTransformer(destinationClass, > > > > > > + > sourceClass), > > > > > destinationClass, > > > > > > sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > * @see > > > > > > > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > > */ > > > > > > protected Class[] > > > getSourceClassesImpl() > > > > > throws Exception { > > > > > > @@ -477,6 +487,7 @@ > > > > > > * if no suitable > > > transformer > > > > > could be found > > > > > > */ > > > > > > private Transformer > > > getTransformer(Class > > > > > transformerType, Class > > > > > > destinationClass, Class sourceClass) > throws > > > > > TransformationException { > > > > > > + Transformer candidate = > null; > > > > > > for (int i = 0; i < > > > > > components.length; i++) { > > > > > > // if the > transformer > > > is > > > > > the correct type > > > > > > Transformer > transformer > > > = > > > > > (Transformer) > > > > > > components[i]; > > > > > > @@ -484,6 +495,13 @@ > > > > > > // if the > > > > > transformer is capable of > > > > > > performing the transformation > > > > > > if > > > > > (TransformerUtils.isTransformable( > > > > > > > > > > > transformer, > > > > > > destinationClass, sourceClass)) { > > > > > > + if > > > > > (isPreferPreciseTransformers() > > > > > > + > > > > > && candidate == > > > > > > null > > > > > > + > > > > > && > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > > + > > > > > > destinationClass, sourceClass)) { > > > > > > + > > > > > candidate = transformer; > > > > > > + > > > > > continue; > > > > > > + } > > > > > > if > > > > > (getLog().isTraceEnabled()) { > > > > > > > > > > > getLog().trace("Using " > > > > > > > > > > > + > > > > > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > > @@ -496,7 +514,9 @@ > > > > > > > return > > > > > transformer; > > > > > > } > > > > > > } > > > > > > - > > > > > > + if (candidate != > null) > > > { > > > > > > + return > > > candidate; > > > > > > + } > > > > > > } > > > > > > throw new > > > TransformationException( > > > > > > "Could not find a > > > > > transformer that can transform > > > > > > objects of " > > > > > > @@ -612,4 +632,20 @@ > > > > > > source); > > > > > > } > > > > > > > > > > > > + /** > > > > > > + * Get the > preferPreciseTransformers. > > > > > > + * @return boolean > > > > > > + */ > > > > > > + public boolean > > > > > isPreferPreciseTransformers() { > > > > > > + return > > > preferPreciseTransformers; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Set the > preferPreciseTransformers. > > > > > Default false. > > > > > > + * @param > preferPreciseTransformers > > > the > > > > > boolean to set > > > > > > + */ > > > > > > + public void > > > > > setPreferPreciseTransformers(boolean > > > > > > preferPreciseTransformers) { > > > > > > + > this.preferPreciseTransformers > > > = > > > > > > preferPreciseTransformers; > > > > > > + } > > > > > > + > > > > > > } > > > > > > \ No newline at end of file > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > (revision 358) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > (working copy) > > > > > > @@ -570,6 +570,35 @@ > > > > > > } > > > > > > } > > > > > > > > > > > > + /** > > > > > > + * Implementation of > > > isImpreciseConversion > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return destinationClass == > > > null && > > > > > sourceClass != null; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Learn whether the specified > > > conversion > > > > > yields an imprecise > > > > > > result. > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + */ > > > > > > + public final boolean > > > > > isImpreciseConversion(Class > destinationClass, > > > > > > Class sourceClass) { > > > > > > + try { > > > > > > + return > > > > > isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass); > > > > > > + } catch (Exception e) { > > > > > > + if (e instanceof > > > > > RuntimeException && > > > > > > !isWrappingRuntimeExceptions()) { > > > > > > + throw > > > > > (RuntimeException) e; > > > > > > + } > > > > > > + throw new > > > > > TransformationException("Could not > > > > > > determine if conversion of " > > > > > > + + > > > > > sourceClass + " to " + > > > > > > destinationClass > > > > > > + + > " > > > > > results in a loss of > > > > > > precision", e); > > > > > > + } > > > > > > + } > > > > > > + > > > > > > // property getters and setters > > > > > > > > > > > > /** > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -16,6 +16,7 @@ > > > > > > package > net.sf.morph.transform.transformers; > > > > > > > > > > > > import java.util.ArrayList; > > > > > > +import java.util.Iterator; > > > > > > import java.util.List; > > > > > > import java.util.Locale; > > > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > > net.sf.morph.transform.DecoratedCopier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > import > > > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > > @@ -40,7 +42,7 @@ > > > > > > * @since Nov 24, 2004 > > > > > > */ > > > > > > public class ChainedTransformer extends > > > > > BaseCompositeTransformer > > > > > > implements > > > > > > - DecoratedConverter, > > > > > DecoratedCopier, ExplicitTransformer { > > > > > > + DecoratedConverter, > > > > > DecoratedCopier, ExplicitTransformer, > > > > > > ImpreciseConverter { > > > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + List conversionPath = > > > > > getConversionPath(destinationClass, > > > > > > sourceClass); > > > > > > + return > > > !isPrecise(conversionPath, > > > > > sourceClass, 0); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Get the converter used when > using a > > > > > ChainedTransformer as a > > > > > > Copier. > > > > > > * @return > > > > > > */ > > > > > > @@ -113,6 +123,7 @@ > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > sourceType, null, > > > > > > > > > "Chained > > > > > conversion path could not > > > > > > be determined"); > > > > > > } > > > > > > + log.debug("Using chained > > > > > conversion path " + > > > > > > conversionPath); > > > > > > Object o = source; > > > > > > for (int i = 0; i < > > > > > conversionPath.size(); i++) { > > > > > > o = > > > > > getConverter(chain[i]).convert((Class) > > > > > > conversionPath.get(i), o, locale); > > > > > > @@ -144,6 +155,7 @@ > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > source, null, > > > > > > > > > "Chained > > > > > conversion path could not > > > > > > be determined"); > > > > > > } > > > > > > + log.debug("Using chained > > > > > conversion path " + > > > > > > conversionPath); > > > > > > Object last = > > > > > getCopyConverter().convert((Class) > > > > > > conversionPath.get(chain.length - 2), > source, > > > > > locale); > > > > > > ((Copier) > > > copier).copy(destination, > > > > > last, locale); > > > > > > } > > > > > > @@ -192,13 +204,7 @@ > > > > > > * @return List > > > > > > */ > > > > > > protected List > getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType) { > > > > > > - if (sourceType != null) { > > > > > > - List withoutNull = > > > > > > getConversionPath(destinationType, > sourceType, > > > 0, > > > > > false); > > > > > > - if (withoutNull != > > > null) { > > > > > > - return > > > > > withoutNull; > > > > > > - } > > > > > > - } > > > > > > - return > > > > > getConversionPath(destinationType, > sourceType, > > > 0, > > > > > > true); > > > > > > + return > > > > > getConversionPath(destinationType, > sourceType, > > > 0); > > > > > > } > > > > > > > > > > > > /** > > > > > > @@ -210,7 +216,7 @@ > > > > > > * @param allowNull > > > > > > * @return List > > > > > > */ > > > > > > - private List > getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType, int index, boolean allowNull) > { > > > > > > + private List > getConversionPath(Class > > > > > destinationType, Class > > > > > > sourceType, int index) { > > > > > > Transformer[] chain = > > > getChain(); > > > > > > Transformer c = > chain[index]; > > > > > > if (index + 1 == > chain.length) > > > { > > > > > > @@ -221,22 +227,38 @@ > > > > > > } > > > > > > return null; > > > > > > } > > > > > > + List possibleResult = > null; > > > > > > Class[] available = > > > > > c.getDestinationClasses(); > > > > > > for (int i = 0; i < > > > > > available.length; i++) { > > > > > > - if (available[i] > == > > > null > > > > > && !allowNull) { > > > > > > - continue; > > > > > > - } > > > > > > if > > > > > (TransformerUtils.isTransformable(c, > > > > > > available[i], sourceType)) { > > > > > > - List tail > = > > > > > > getConversionPath(destinationType, > > > available[i], > > > > > index + 1, allowNull); > > > > > > + List tail > = > > > > > > getConversionPath(destinationType, > > > available[i], > > > > > index + 1); > > > > > > if (tail != > > > null) { > > > > > > > > > tail.add(0, > > > > > available[i]); > > > > > > - > return > > > > > tail; > > > > > > + if > > > > > (isPrecise(tail, sourceType, > > > > > > index)) { > > > > > > + > > > > > return tail; > > > > > > + } > > > > > > + > > > > > possibleResult = tail; > > > > > > } > > > > > > } > > > > > > } > > > > > > - return null; > > > > > > + return possibleResult; > > > > > > } > > > > > > > > > > > > + private boolean isPrecise(List > > > > > conversionPath, Class sourceType, > > > > > > int index) { > > > > > > + Transformer[] chain = > > > getChain(); > > > > > > + Class currentSource = > > > sourceType; > > > > > > + int i = 0; > > > > > > + for (Iterator iter = > > > > > conversionPath.iterator(); > > > > > > iter.hasNext(); i++) { > > > > > > + Class currentDest > = > > > > > (Class) iter.next(); > > > > > > + if > > > > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > > + i], currentDest, > > > > > > + > > > > > currentSource)) { > > > > > > + return > false; > > > > > > + } > > > > > > + currentSource = > > > > > currentDest; > > > > > > + } > > > > > > + return true; > > > > > > + } > > > > > > + > > > > > > /** > > > > > > * Get the components array > narrowed to > > > a > > > > > Transformer[]. > > > > > > * @return Transformer[] > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > (revision > > > > > > 0) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > (revision > > > > > > 0) > > > > > > @@ -0,0 +1,32 @@ > > > > > > +/* > > > > > > + * Copyright 2008 the original author or > > > authors. > > > > > > + * > > > > > > + * Licensed under the Apache License, > Version > > > 2.0 > > > > > (the "License"); you > > > > > > may not > > > > > > + * use this file except in compliance > with > > > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > + * the License at > > > > > > + * > > > > > > + * > http://www.apache.org/licenses/LICENSE-2.0 > > > > > > + * > > > > > > + * Unless required by applicable law or > > > agreed to > > > > > in writing, software > > > > > > + * distributed under the License is > > > distributed > > > > > on an "AS IS" BASIS, > > > > > > WITHOUT > > > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, > > > either > > > > > express or implied. See > > > > > > the > > > > > > + * License for the specific language > > > governing > > > > > permissions and > > > > > > limitations under > > > > > > + * the License. > > > > > > + */ > > > > > > +package net.sf.morph.transform; > > > > > > + > > > > > > +/** > > > > > > + * Defines a converter whose operation > may > > > result > > > > > in a loss of data > > > > > > precision. > > > > > > + * > > > > > > + * @author mbenson > > > > > > + * @since Morph 1.0.2 > > > > > > + */ > > > > > > +public interface ImpreciseConverter > extends > > > > > Converter { > > > > > > + /** > > > > > > + * Learn whether the specified > > > conversion > > > > > might yield an imprecise > > > > > > result. > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + */ > > > > > > + boolean > isImpreciseConversion(Class > > > > > destinationClass, Class > > > > > > sourceClass); > > > > > > +} > > > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > > Name: svn:eol-style > > > > > > + native > > > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > (working copy) > > > > > > @@ -20,7 +20,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts an object to a textual > > > representation > > > > > by calling the object's > > > > > > @@ -32,7 +34,7 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 24, 2004 > > > > > > */ > > > > > > -public class ObjectToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class ObjectToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > > > private Converter textConverter; > > > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > (revision 361) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > (working copy) > > > > > > @@ -32,7 +32,7 @@ > > > > > > import > org.apache.commons.logging.LogFactory; > > > > > > > > > > > > /** > > > > > > - * Converts basic text types into > primtive > > > > > numbers or {@link > > > > > > java.lang.Number} > > > > > > + * Converts basic text types into > primitive > > > > > numbers or {@link > > > > > > java.lang.Number} > > > > > > * objects. > > > > > > * > > > > > > * @author Matt Sgarlata > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > (revision 363) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > (working copy) > > > > > > @@ -21,7 +21,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts {@link java.lang.Number}s into > > > basic > > > > > text types ({@link > > > > > > java.lang.String}, > > > > > > @@ -30,7 +32,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Jan 26, 2006 > > > > > > */ > > > > > > -public class NumberToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class NumberToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > + ImpreciseConverter { > > > > > > > > > > > > private Converter textConverter; > > > > > > private Converter numberConverter; > > > > > > @@ -58,6 +61,13 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Get the number converter used by > > > this > > > > > NumberToTextConverter. > > > > > > * @return Converter > > > > > > */ > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > (revision 360) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > (working copy) > > > > > > @@ -22,7 +22,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts the basic time types ({@link > > > > > java.util.Date} and > > > > > > @@ -33,7 +35,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 31, 2004 > > > > > > */ > > > > > > -public class TimeToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > +public class TimeToTextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > + ImpreciseConverter { > > > > > > > > > > > > private DateFormat dateFormat; > > > > > > private Converter timeConverter; > > > > > > @@ -55,6 +58,13 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > (revision 357) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > (working copy) > > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > import net.sf.morph.util.ClassUtils; > > > > > > @@ -43,7 +44,7 @@ > > > > > > * @since Jan 2, 2005 > > > > > > */ > > > > > > public class TextConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, > > > > > > - ExplicitTransformer { > > > > > > + ExplicitTransformer, > > > > > ImpreciseConverter { > > > > > > > > > > > > private static final Class > > > CHAR_SEQUENCE = > > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > > ClassUtils > > > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > > @@ -62,14 +63,7 @@ > > > > > > s.add(Character.class); > > > > > > s.add(char.class); > > > > > > s.add(null); > > > > > > - if (CHAR_SEQUENCE != null) > { > > > > > > - > s.add(CHAR_SEQUENCE); > > > > > > - try { > > > > > > - > > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > > StringBuffer.class.getConstructor(new > Class[] > > > { > > > > > String.class })); > > > > > > - } catch (Exception > e) > > > { > > > > > > - //nope > > > > > > - } > > > > > > - } > > > > > > + s.add(CHAR_SEQUENCE); > > > > > > > SOURCE_AND_DESTINATION_TYPES = > > > > > (Class[]) s.toArray(new > > > > > > Class[s.size()]); > > > > > > } > > > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > > } > > > > > > return new > > > > > Character(string.charAt(0)); > > > > > > } > > > > > > - if (destinationClass == > > > > > String.class) { > > > > > > + if (destinationClass == > > > > > String.class > > > > > > + || > > > > > (destinationClass == CHAR_SEQUENCE && > > > > > > CHAR_SEQUENCE != null)) { > > > > > > return string; > > > > > > } > > > > > > if (destinationClass == > > > > > byte[].class) { > > > > > > @@ -152,6 +147,16 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + if > > > > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass)) { > > > > > > + return true; > > > > > > + } > > > > > > + return > > > isChar(destinationClass) && > > > > > !isChar(sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isAutomaticallyHandlingNulls() { > > > > > > return !isEmptyNull(); > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > (working copy) > > > > > > @@ -20,8 +20,10 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Converts boolean values to text values. > > > > > Subclasses can build in > > > > > > support for > > > > > > @@ -32,10 +34,10 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Jan 9, 2005 > > > > > > */ > > > > > > -public class BooleanToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > - > > > > > > +public class BooleanToTextConverter > extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > + > > > > > > private static final Class[] > > > SOURCE_TYPES = > > > > > { Boolean.class, > > > > > > boolean.class }; > > > > > > - > > > > > > + > > > > > > private Converter textConverter; > > > > > > > > > > > > /** > > > > > > @@ -93,9 +95,16 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, String.class); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected boolean > > > > > isWrappingRuntimeExceptions() { > > > > > > return true; > > > > > > - } > > > > > > + } > > > > > > > > > > > > /** > > > > > > * Get the text converter used by > this > > > > > BaseToPrettyTextConverter. > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > (revision 363) > > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > (working copy) > > > > > > @@ -19,6 +19,7 @@ > > > > > > import java.util.Locale; > > > > > > > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > > > > > > net.sf.morph.transform.support.NumberRounder; > > > > > > import > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > > @@ -31,8 +32,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Dec 14, 2004 > > > > > > */ > > > > > > -public class NumberConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter { > > > > > > - > > > > > > +public class NumberConverter extends > > > > > BaseTransformer implements > > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > + > > > > > > private static final Class[] > > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > > Number.class, byte.class, > > > > > short.class, int.class, > > > > > > long.class, > > > > > > float.class, double.class, > null > > > > > > @@ -116,9 +117,20 @@ > > > > > > /** > > > > > > * {@inheritDoc} > > > > > > */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > > sourceClass) > > > > > > + || > > > > > > > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > > + > > > > > sourceClass) < 0; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > protected Object convertImpl(Class > > > > > destinationClass, Object source, > > > > > > Locale locale) throws > Exception > > > { > > > > > > - > > > > > > + if (destinationClass == > null) > > > { > > > > > > + return null; > > > > > > + } > > > > > > if > > > (destinationClass.isPrimitive() > > > > > && source == null) { > > > > > > throw new > > > > > TransformationException(destinationClass, > > > > > > source); > > > > > > } > > > > > > Index: > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > (revision 362) > > > > > > +++ > > > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > (working copy) > > > > > > @@ -18,7 +18,9 @@ > > > > > > import net.sf.morph.Defaults; > > > > > > import net.sf.morph.transform.Converter; > > > > > > import > > > net.sf.morph.transform.DecoratedConverter; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > > +import > net.sf.morph.util.TransformerUtils; > > > > > > > > > > > > /** > > > > > > * Base class for converts that convert > > > objects to > > > > > a pretty > > > > > > programmer-friendly > > > > > > @@ -27,7 +29,8 @@ > > > > > > * @author Matt Sgarlata > > > > > > * @since Feb 15, 2005 > > > > > > */ > > > > > > -public abstract class > > > BaseToPrettyTextConverter > > > > > extends > > > > > > BaseReflectorTransformer implements > > > > > DecoratedConverter { > > > > > > +public abstract class > > > BaseToPrettyTextConverter > > > > > extends > > > > > > BaseReflectorTransformer > > > > > > + implements > DecoratedConverter, > > > > > ImpreciseConverter { > > > > > > > > > > > > private String prefix; > > > > > > private String suffix; > > > > > > @@ -161,4 +164,19 @@ > > > > > > public void > setShowNullValues(boolean > > > > > showNullValues) { > > > > > > this.showNullValues = > > > > > showNullValues; > > > > > > } > > > > > > + > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + protected boolean > > > > > isImpreciseConversionImpl(Class > > > > > > destinationClass, Class sourceClass) { > > > > > > + return > > > > > > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > > destinationClass, sourceClass); > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > + * Get the intermediate class > passed > > > to > > > > > the text converter. > > > > > > + * @return > > > > > > + */ > > > > > > + protected Class > getIntermediateClass() > > > { > > > > > > + return StringBuffer.class; > > > > > > + } > > > > > > } > > > > > > Index: > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > (revision 365) > > > > > > +++ > > > src/core/net/sf/morph/util/NumberUtils.java > > > > > (working copy) > > > > > > @@ -19,6 +19,7 @@ > > > > > > import java.lang.reflect.Method; > > > > > > import java.math.BigDecimal; > > > > > > import java.math.BigInteger; > > > > > > +import java.util.Comparator; > > > > > > import java.util.HashMap; > > > > > > import java.util.HashSet; > > > > > > import java.util.Iterator; > > > > > > @@ -69,6 +70,31 @@ > > > > > > } > > > > > > } > > > > > > > > > > > > + private static class > > > NarrownessComparator > > > > > implements Comparator { > > > > > > + /** > > > > > > + * {@inheritDoc} > > > > > > + */ > > > > > > + public int compare(Object > > > arg0, > > > > > Object arg1) { > > > > > > + if (arg0 == arg1) > { > > > > > > + return 0; > > > > > > + } > > > > > > + Class c0 = > > > getType(arg0); > > > > > > + Class c1 = > > > getType(arg1); > > > > > > + if (c0 == c1 || c0 > == > > > null > > > > > || c1 == null) { > > > > > > + return 0; > > > > > > + } > > > > > > + return > > > > > > > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > > + } > > > > > > + > > > > > > + private Class > getType(Object > > > o) { > > > > > > + if > > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > > + return > (Class) > > > o; > > > > > > + } > > > > > > + Class test = > > > > > ClassUtils.getClass(o); > > > > > > + return > > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > > > : null; > > > > > > + } > > > > > > + } > > > > > > + > > > > > > /** > > > > > > * A Map of BigDecimals keyed by > Class > > > that > > > > > indicate the maximum > > > > > > value that > > > > > > * the given (Number) Class may > taken > > > on. > > > > > > @@ -80,11 +106,16 @@ > > > > > > * the given (Number) Class may > taken > > > on. > > > > > > */ > > > > > > public static final Map > > > MINIMUMS_FOR_TYPES; > > > > > > - > > > > > > - public static final Map > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > > > - public static final Map > > > NUMBER_FACTORIES; > > > > > > + /** > > > > > > + * Comparator of class/object type > > > > > narrowness. > > > > > > + */ > > > > > > + public static final Comparator > > > > > NARROWNESS_COMPARATOR = new > > > > > > NarrownessComparator(); > > > > > > > > > > > > + private static final Map > > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > + > > > > > > + private static final Map > > > NUMBER_FACTORIES; > > > > > > + > > > > > > /** > > > > > > * Used by {@link > > > > > NumberUtils#isNumber(Class)}. > > > > > > */ > > > > > > Index: > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > > > > > > > =================================================================== > > > > > > --- > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > (revision 357) > > > > > > +++ > > > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > (working copy) > > > > > > @@ -1,5 +1,5 @@ > > > > > > /* > > > > > > - * Copyright 2004-2005, 2007 the original > > > author > > > > > or authors. > > > > > > + * Copyright 2004-2005, 2007-2008 the > > > original > > > > > author or authors. > > > > > > * > > > > > > * Licensed under the Apache License, > Version > > > 2.0 > > > > > (the "License"); you may > > > > > > not > > > > > > * use this file except in compliance with > the > > > > > License. You may obtain a > > > > > > copy of > > > > > > @@ -26,6 +26,7 @@ > > > > > > import net.sf.morph.transform.Converter; > > > > > > import net.sf.morph.transform.Copier; > > > > > > import > > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > > +import > > > net.sf.morph.transform.ImpreciseConverter; > > > > > > import > > > > > > net.sf.morph.transform.TransformationException; > > > > > > import > net.sf.morph.transform.Transformer; > > > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > > } > > > > > > > > > > > > /** > > > > > > + * Learn whether > > > > > <code>transformer</code>'s conversion > > > > > > + * of <code>sourceClass</code> to > > > > > <code>destinationClass</code> > > > > > > might yield an imprecise result. > > > > > > + * @param transformer > > > > > > + * @param destinationClass > > > > > > + * @param sourceClass > > > > > > + * @return boolean > > > > > > + * @see ImpreciseConverter > > > > > > + */ > > > > > > + public static boolean > > > > > isImpreciseConversion(Transformer > > > > > > transformer, > > > > > > + Class > > > destinationClass, > > > > > Class sourceClass) { > > > > > > + if (transformer instanceof > > > > > ImpreciseConverter) { > > > > > > + return > > > > > ((ImpreciseConverter) > > > > > > transformer).isImpreciseConversion( > > > > > > + > > > > > destinationClass, sourceClass); > > > > > > + } > > > > > > + return destinationClass == > > > null && > > > > > sourceClass != null; > > > > > > + } > > > > > > + > > > > > > + /** > > > > > > * Performs a transformation of one > > > object > > > > > graph into another > > > > > > object graph. > > > > > > * > > > > > > * @param destinationType > > > > > > > > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > > This SF.net email is sponsored by: > Microsoft > > > > > > Defy all challenges. Microsoft(R) Visual > > > Studio > > > > > 2005. > > > > > > > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > > > > _______________________________________________ > > > > > > morph-developer mailing list > > > > > > mor...@li... > > > > > > > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > This message is intended only for the named > > > > > recipient. If you are not the > > > > > intended recipient, you are notified that > > > > > disclosing, copying, distributing, > > > > > or taking any action in reliance on the > contents > > > of > > > > > this information is > > > > > strictly prohibited. > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > This SF.net email is sponsored by: Microsoft > > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > > > 2005. > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > > > _______________________________________________ > > > > > morph-developer mailing list > > > > > mor...@li... > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > Never miss a thing. Make Yahoo your home > page. > > > > http://www.yahoo.com/r/hs > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > -- > > > This message is intended only for the named > > > recipient. If you are not the > > > intended recipient, you are notified that > > > disclosing, copying, distributing, > > > or taking any action in reliance on the contents > of > > > this information is > > > strictly prohibited. > > > > > > > ------------------------------------------------------------------------- > > > Check out the new SourceForge.net Marketplace. > > > It's the best place to buy or sell services for > > > just about anything Open Source. > > > > > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Never miss a thing. Make Yahoo your home page. > > http://www.yahoo.com/r/hs > > > > > ------------------------------------------------------------------------- > > Check out the new SourceForge.net Marketplace. > > It's the best place to buy or sell services for > > just about anything Open Source. > > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Looking for last minute shopping deals? Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping |
From: Matt S. <mat...@sp...> - 2008-01-08 13:54:35
|
I actually put it in the Composite package because that's where a lot of similar calls are.... Matt On Jan 7, 2008 12:39 PM, Matt Benson <gud...@ya...> wrote: > I got the renamed call, but the method still seems to > be missing on ClassUtils. ;) > > --- Matt Sgarlata <mat...@sp...> > wrote: > > > Sorry about that! I renamed the method > > isCommonsCollections3Present because > > the class referenced is new in 3.x (I meant to do > > this before, but I > > forgot). > > > > Matt S > > > > On Jan 7, 2008 11:32 AM, Matt Benson > > <gud...@ya...> wrote: > > > > > > > > --- Matt Sgarlata > > <mat...@sp...> > > > wrote: > > > > > > > I have been thinking more about this approach, > > and > > > > it's really starting to > > > > grow on me. I do have one concern though, can > > this > > > > approach be extended to > > > > Copiers? For example, a Map -> Object copy > > could > > > > probably be considered an > > > > imprecise transformation because the Map may > > have > > > > more keys than the Object > > > > has properties. > > > > > > > > In addition to your approach, I also like the > > idea > > > > of cleaning up the > > > > internal implementation in Morph so that > > ordering of > > > > source and destination > > > > classes is preserved for the following reasons: > > > > 1) for at least some portion of users, setting > > the > > > > order of source and > > > > destination classes will make sense as an > > indication > > > > of the transformer's > > > > preferences for performing transformations (so > > for > > > > this class of users, > > > > creating new transformers that play nicely with > > the > > > > ChainedTransformerTestCase will be simpler) > > > > 2) I think a general change from using HashSets > > to > > > > ordered sets in Morph's > > > > implementation will mean transformations happen > > more > > > > consistently across > > > > JVMs and across time on the same JVM, leading to > > a > > > > more stable platform > > > > > > > > So, what I did is I basically went through the > > Morph > > > > codebase and replaced > > > > HashSets with ordered sets (preference order is: > > JDK > > > > 1.4 LinkedHashSet, > > > > Commons-collections ListOrderedSet, copy of > > > > ListOrderedSet in > > > > net.sf.morph.util). I was never able to modify > > the > > > > ChainedTransformerTestCase so that it > > consistently > > > > threw an error. However, > > > > after working on the test case long enough, > > > > eventually something changed in > > > > my environment so that the test started to fail. > > I > > > > did my change of > > > > HashSets to ordered sets, and that was able to > > fix > > > > the broken test. > > > > > > I seem to be missing a > > > ClassUtils.isCommonsCollectionsPresent() method > > after > > > syncing. I'll create my own for now, but it does > > seem > > > to be missing. Thanks! > > > > > > -Matt B > > > > > > > > > > > I checked in my changes for you to take a look > > at... > > > > > > > > Matt S > > > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > > <gud...@ya...> wrote: > > > > > > > > > Here's what I've got. > > > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > > Be a better friend, newshound, and > > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > > > Index: > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, Version > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -35,6 +35,7 @@ > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > import > > net.sf.morph.transform.DecoratedCopier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import net.sf.morph.transform.NodeCopier; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > @@ -93,11 +94,11 @@ > > > > > * @since Dec 12, 2004 > > > > > */ > > > > > public class SimpleDelegatingTransformer > > extends > > > > BaseCompositeTransformer > > > > > implements > > > > > - SpecializableComposite, > > > > ExplicitTransformer, Transformer, > > > > > DecoratedCopier, DecoratedConverter, Cloneable > > { > > > > > + SpecializableComposite, > > > > ExplicitTransformer, Transformer, > > > > > DecoratedCopier, > > > > > + DecoratedConverter, Cloneable, > > > > ImpreciseConverter { > > > > > > > > > > //TODO extract > > BaseDelegatingTransformer > > > > with pluggable delegate > > > > > selection > > > > > > > > > > - > > > > > private static class MapThreadLocal > > extends > > > > ThreadLocal { > > > > > protected Object initialValue() > > { > > > > > return new HashMap(); > > > > > @@ -138,6 +139,7 @@ > > > > > } > > > > > > > > > > private Specializer specializer; > > > > > + private boolean > > preferPreciseTransformers; > > > > > > > > > > private transient ThreadLocal > > > > > visitedSourceToDestinationMapThreadLocal = new > > > > MapThreadLocal(); > > > > > private transient ThreadLocal > > > > stackDepthThreadLocal = new > > > > > StackDepthThreadLocal(); > > > > > @@ -225,6 +227,14 @@ > > > > > > > > > > /** > > > > > * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > TransformerUtils.isImpreciseConversion > > > > > (getTransformer(destinationClass, > > > > > + sourceClass), > > > > destinationClass, > > > > > sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > * @see > > > > > > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > > */ > > > > > protected Class[] > > getSourceClassesImpl() > > > > throws Exception { > > > > > @@ -477,6 +487,7 @@ > > > > > * if no suitable > > transformer > > > > could be found > > > > > */ > > > > > private Transformer > > getTransformer(Class > > > > transformerType, Class > > > > > destinationClass, Class sourceClass) throws > > > > TransformationException { > > > > > + Transformer candidate = null; > > > > > for (int i = 0; i < > > > > components.length; i++) { > > > > > // if the transformer > > is > > > > the correct type > > > > > Transformer transformer > > = > > > > (Transformer) > > > > > components[i]; > > > > > @@ -484,6 +495,13 @@ > > > > > // if the > > > > transformer is capable of > > > > > performing the transformation > > > > > if > > > > (TransformerUtils.isTransformable( > > > > > > > > > transformer, > > > > > destinationClass, sourceClass)) { > > > > > + if > > > > (isPreferPreciseTransformers() > > > > > + > > > > && candidate == > > > > > null > > > > > + > > > > && > > > > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > > + > > > > > destinationClass, sourceClass)) { > > > > > + > > > > candidate = transformer; > > > > > + > > > > continue; > > > > > + } > > > > > if > > > > (getLog().isTraceEnabled()) { > > > > > > > > > getLog().trace("Using " > > > > > > > > > + > > > > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > > @@ -496,7 +514,9 @@ > > > > > return > > > > transformer; > > > > > } > > > > > } > > > > > - > > > > > + if (candidate != null) > > { > > > > > + return > > candidate; > > > > > + } > > > > > } > > > > > throw new > > TransformationException( > > > > > "Could not find a > > > > transformer that can transform > > > > > objects of " > > > > > @@ -612,4 +632,20 @@ > > > > > source); > > > > > } > > > > > > > > > > + /** > > > > > + * Get the preferPreciseTransformers. > > > > > + * @return boolean > > > > > + */ > > > > > + public boolean > > > > isPreferPreciseTransformers() { > > > > > + return > > preferPreciseTransformers; > > > > > + } > > > > > + > > > > > + /** > > > > > + * Set the preferPreciseTransformers. > > > > Default false. > > > > > + * @param preferPreciseTransformers > > the > > > > boolean to set > > > > > + */ > > > > > + public void > > > > setPreferPreciseTransformers(boolean > > > > > preferPreciseTransformers) { > > > > > + this.preferPreciseTransformers > > = > > > > > preferPreciseTransformers; > > > > > + } > > > > > + > > > > > } > > > > > \ No newline at end of file > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > (revision 358) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > (working copy) > > > > > @@ -570,6 +570,35 @@ > > > > > } > > > > > } > > > > > > > > > > + /** > > > > > + * Implementation of > > isImpreciseConversion > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return destinationClass == > > null && > > > > sourceClass != null; > > > > > + } > > > > > + > > > > > + /** > > > > > + * Learn whether the specified > > conversion > > > > yields an imprecise > > > > > result. > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + */ > > > > > + public final boolean > > > > isImpreciseConversion(Class destinationClass, > > > > > Class sourceClass) { > > > > > + try { > > > > > + return > > > > isImpreciseConversionImpl(destinationClass, > > > > > sourceClass); > > > > > + } catch (Exception e) { > > > > > + if (e instanceof > > > > RuntimeException && > > > > > !isWrappingRuntimeExceptions()) { > > > > > + throw > > > > (RuntimeException) e; > > > > > + } > > > > > + throw new > > > > TransformationException("Could not > > > > > determine if conversion of " > > > > > + + > > > > sourceClass + " to " + > > > > > destinationClass > > > > > + + " > > > > results in a loss of > > > > > precision", e); > > > > > + } > > > > > + } > > > > > + > > > > > // property getters and setters > > > > > > > > > > /** > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, Version > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -16,6 +16,7 @@ > > > > > package net.sf.morph.transform.transformers; > > > > > > > > > > import java.util.ArrayList; > > > > > +import java.util.Iterator; > > > > > import java.util.List; > > > > > import java.util.Locale; > > > > > > > > > > @@ -25,6 +26,7 @@ > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > import > > net.sf.morph.transform.DecoratedCopier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > import > > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > > @@ -40,7 +42,7 @@ > > > > > * @since Nov 24, 2004 > > > > > */ > > > > > public class ChainedTransformer extends > > > > BaseCompositeTransformer > > > > > implements > > > > > - DecoratedConverter, > > > > DecoratedCopier, ExplicitTransformer { > > > > > + DecoratedConverter, > > > > DecoratedCopier, ExplicitTransformer, > > > > > ImpreciseConverter { > > > > > > > > > > private Converter copyConverter; > > > > > > > > > > @@ -67,6 +69,14 @@ > > > > > } > > > > > > > > > > /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + List conversionPath = > > > > getConversionPath(destinationClass, > > > > > sourceClass); > > > > > + return > > !isPrecise(conversionPath, > > > > sourceClass, 0); > > > > > + } > > > > > + > > > > > + /** > > > > > * Get the converter used when using a > > > > ChainedTransformer as a > > > > > Copier. > > > > > * @return > > > > > */ > > > > > @@ -113,6 +123,7 @@ > > > > > throw new > > > > TransformationException(destinationClass, > > > > > sourceType, null, > > > > > > > "Chained > > > > conversion path could not > > > > > be determined"); > > > > > } > > > > > + log.debug("Using chained > > > > conversion path " + > > > > > conversionPath); > > > > > Object o = source; > > > > > for (int i = 0; i < > > > > conversionPath.size(); i++) { > > > > > o = > > > > getConverter(chain[i]).convert((Class) > > > > > conversionPath.get(i), o, locale); > > > > > @@ -144,6 +155,7 @@ > > > > > throw new > > > > TransformationException(destinationClass, > > > > > source, null, > > > > > > > "Chained > > > > conversion path could not > > > > > be determined"); > > > > > } > > > > > + log.debug("Using chained > > > > conversion path " + > > > > > conversionPath); > > > > > Object last = > > > > getCopyConverter().convert((Class) > > > > > conversionPath.get(chain.length - 2), source, > > > > locale); > > > > > ((Copier) > > copier).copy(destination, > > > > last, locale); > > > > > } > > > > > @@ -192,13 +204,7 @@ > > > > > * @return List > > > > > */ > > > > > protected List getConversionPath(Class > > > > destinationType, Class > > > > > sourceType) { > > > > > - if (sourceType != null) { > > > > > - List withoutNull = > > > > > getConversionPath(destinationType, sourceType, > > 0, > > > > false); > > > > > - if (withoutNull != > > null) { > > > > > - return > > > > withoutNull; > > > > > - } > > > > > - } > > > > > - return > > > > getConversionPath(destinationType, sourceType, > > 0, > > > > > true); > > > > > + return > > > > getConversionPath(destinationType, sourceType, > > 0); > > > > > } > > > > > > > > > > /** > > > > > @@ -210,7 +216,7 @@ > > > > > * @param allowNull > > > > > * @return List > > > > > */ > > > > > - private List getConversionPath(Class > > > > destinationType, Class > > > > > sourceType, int index, boolean allowNull) { > > > > > + private List getConversionPath(Class > > > > destinationType, Class > > > > > sourceType, int index) { > > > > > Transformer[] chain = > > getChain(); > > > > > Transformer c = chain[index]; > > > > > if (index + 1 == chain.length) > > { > > > > > @@ -221,22 +227,38 @@ > > > > > } > > > > > return null; > > > > > } > > > > > + List possibleResult = null; > > > > > Class[] available = > > > > c.getDestinationClasses(); > > > > > for (int i = 0; i < > > > > available.length; i++) { > > > > > - if (available[i] == > > null > > > > && !allowNull) { > > > > > - continue; > > > > > - } > > > > > if > > > > (TransformerUtils.isTransformable(c, > > > > > available[i], sourceType)) { > > > > > - List tail = > > > > > getConversionPath(destinationType, > > available[i], > > > > index + 1, allowNull); > > > > > + List tail = > > > > > getConversionPath(destinationType, > > available[i], > > > > index + 1); > > > > > if (tail != > > null) { > > > > > > > tail.add(0, > > > > available[i]); > > > > > - return > > > > tail; > > > > > + if > > > > (isPrecise(tail, sourceType, > > > > > index)) { > > > > > + > > > > return tail; > > > > > + } > > > > > + > > > > possibleResult = tail; > > > > > } > > > > > } > > > > > } > > > > > - return null; > > > > > + return possibleResult; > > > > > } > > > > > > > > > > + private boolean isPrecise(List > > > > conversionPath, Class sourceType, > > > > > int index) { > > > > > + Transformer[] chain = > > getChain(); > > > > > + Class currentSource = > > sourceType; > > > > > + int i = 0; > > > > > + for (Iterator iter = > > > > conversionPath.iterator(); > > > > > iter.hasNext(); i++) { > > > > > + Class currentDest = > > > > (Class) iter.next(); > > > > > + if > > > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > > + i], currentDest, > > > > > + > > > > currentSource)) { > > > > > + return false; > > > > > + } > > > > > + currentSource = > > > > currentDest; > > > > > + } > > > > > + return true; > > > > > + } > > > > > + > > > > > /** > > > > > * Get the components array narrowed to > > a > > > > Transformer[]. > > > > > * @return Transformer[] > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > (revision > > > > > 0) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > (revision > > > > > 0) > > > > > @@ -0,0 +1,32 @@ > > > > > +/* > > > > > + * Copyright 2008 the original author or > > authors. > > > > > + * > > > > > + * Licensed under the Apache License, Version > > 2.0 > > > > (the "License"); you > > > > > may not > > > > > + * use this file except in compliance with > > the > > > > License. You may obtain a > > > > > copy of > > > > > + * the License at > > > > > + * > > > > > + * http://www.apache.org/licenses/LICENSE-2.0 > > > > > + * > > > > > + * Unless required by applicable law or > > agreed to > > > > in writing, software > > > > > + * distributed under the License is > > distributed > > > > on an "AS IS" BASIS, > > > > > WITHOUT > > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, > > either > > > > express or implied. See > > > > > the > > > > > + * License for the specific language > > governing > > > > permissions and > > > > > limitations under > > > > > + * the License. > > > > > + */ > > > > > +package net.sf.morph.transform; > > > > > + > > > > > +/** > > > > > + * Defines a converter whose operation may > > result > > > > in a loss of data > > > > > precision. > > > > > + * > > > > > + * @author mbenson > > > > > + * @since Morph 1.0.2 > > > > > + */ > > > > > +public interface ImpreciseConverter extends > > > > Converter { > > > > > + /** > > > > > + * Learn whether the specified > > conversion > > > > might yield an imprecise > > > > > result. > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + */ > > > > > + boolean isImpreciseConversion(Class > > > > destinationClass, Class > > > > > sourceClass); > > > > > +} > > > > > > > > > > Property changes on: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > > > > > > ___________________________________________________________________ > > > > > Name: svn:eol-style > > > > > + native > > > > > > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > (working copy) > > > > > @@ -20,7 +20,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts an object to a textual > > representation > > > > by calling the object's > > > > > @@ -32,7 +34,7 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 24, 2004 > > > > > */ > > > > > -public class ObjectToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class ObjectToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > > > private Converter textConverter; > > > > > > > > > > @@ -52,6 +54,13 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > (revision 361) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > (working copy) > > > > > @@ -32,7 +32,7 @@ > > > > > import org.apache.commons.logging.LogFactory; > > > > > > > > > > /** > > > > > - * Converts basic text types into primtive > > > > numbers or {@link > > > > > java.lang.Number} > > > > > + * Converts basic text types into primitive > > > > numbers or {@link > > > > > java.lang.Number} > > > > > * objects. > > > > > * > > > > > * @author Matt Sgarlata > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > (revision 363) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > (working copy) > > > > > @@ -21,7 +21,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts {@link java.lang.Number}s into > > basic > > > > text types ({@link > > > > > java.lang.String}, > > > > > @@ -30,7 +32,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Jan 26, 2006 > > > > > */ > > > > > -public class NumberToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class NumberToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > + ImpreciseConverter { > > > > > > > > > > private Converter textConverter; > > > > > private Converter numberConverter; > > > > > @@ -58,6 +61,13 @@ > > > > > } > > > > > > > > > > /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > * Get the number converter used by > > this > > > > NumberToTextConverter. > > > > > * @return Converter > > > > > */ > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > (revision 360) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > (working copy) > > > > > @@ -22,7 +22,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts the basic time types ({@link > > > > java.util.Date} and > > > > > @@ -33,7 +35,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 31, 2004 > > > > > */ > > > > > -public class TimeToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > +public class TimeToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > + ImpreciseConverter { > > > > > > > > > > private DateFormat dateFormat; > > > > > private Converter timeConverter; > > > > > @@ -55,6 +58,13 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > } > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > (revision 357) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > (working copy) > > > > > @@ -22,6 +22,7 @@ > > > > > > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > import net.sf.morph.util.ClassUtils; > > > > > @@ -43,7 +44,7 @@ > > > > > * @since Jan 2, 2005 > > > > > */ > > > > > public class TextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, > > > > > - ExplicitTransformer { > > > > > + ExplicitTransformer, > > > > ImpreciseConverter { > > > > > > > > > > private static final Class > > CHAR_SEQUENCE = > > > > > ClassUtils.isJdk14OrHigherPresent() ? > > ClassUtils > > > > > > > > > .convertToClass("java.lang.CharSequence") > > > > > @@ -62,14 +63,7 @@ > > > > > s.add(Character.class); > > > > > s.add(char.class); > > > > > s.add(null); > > > > > - if (CHAR_SEQUENCE != null) { > > > > > - s.add(CHAR_SEQUENCE); > > > > > - try { > > > > > - > > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > > StringBuffer.class.getConstructor(new Class[] > > { > > > > String.class })); > > > > > - } catch (Exception e) > > { > > > > > - //nope > > > > > - } > > > > > - } > > > > > + s.add(CHAR_SEQUENCE); > > > > > SOURCE_AND_DESTINATION_TYPES = > > > > (Class[]) s.toArray(new > > > > > Class[s.size()]); > > > > > } > > > > > > > > > > @@ -106,7 +100,8 @@ > > > > > } > > > > > return new > > > > Character(string.charAt(0)); > > > > > } > > > > > - if (destinationClass == > > > > String.class) { > > > > > + if (destinationClass == > > > > String.class > > > > > + || > > > > (destinationClass == CHAR_SEQUENCE && > > > > > CHAR_SEQUENCE != null)) { > > > > > return string; > > > > > } > > > > > if (destinationClass == > > > > byte[].class) { > > > > > @@ -152,6 +147,16 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + if > > > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > > sourceClass)) { > > > > > + return true; > > > > > + } > > > > > + return > > isChar(destinationClass) && > > > > !isChar(sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isAutomaticallyHandlingNulls() { > > > > > return !isEmptyNull(); > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > (working copy) > > > > > @@ -20,8 +20,10 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Converts boolean values to text values. > > > > Subclasses can build in > > > > > support for > > > > > @@ -32,10 +34,10 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Jan 9, 2005 > > > > > */ > > > > > -public class BooleanToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > - > > > > > +public class BooleanToTextConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > + > > > > > private static final Class[] > > SOURCE_TYPES = > > > > { Boolean.class, > > > > > boolean.class }; > > > > > - > > > > > + > > > > > private Converter textConverter; > > > > > > > > > > /** > > > > > @@ -93,9 +95,16 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, String.class); > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected boolean > > > > isWrappingRuntimeExceptions() { > > > > > return true; > > > > > - } > > > > > + } > > > > > > > > > > /** > > > > > * Get the text converter used by this > > > > BaseToPrettyTextConverter. > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > (revision 363) > > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > (working copy) > > > > > @@ -19,6 +19,7 @@ > > > > > import java.util.Locale; > > > > > > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import > > > > net.sf.morph.transform.support.NumberRounder; > > > > > import > > > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > > @@ -31,8 +32,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Dec 14, 2004 > > > > > */ > > > > > -public class NumberConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter { > > > > > - > > > > > +public class NumberConverter extends > > > > BaseTransformer implements > > > > > DecoratedConverter, ImpreciseConverter { > > > > > + > > > > > private static final Class[] > > > > SOURCE_AND_DESTINATION_TYPES = { > > > > > Number.class, byte.class, > > > > short.class, int.class, > > > > > long.class, > > > > > float.class, double.class, null > > > > > @@ -116,9 +117,20 @@ > > > > > /** > > > > > * {@inheritDoc} > > > > > */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > super.isImpreciseConversionImpl(destinationClass, > > > > > sourceClass) > > > > > + || > > > > > > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > > + > > > > sourceClass) < 0; > > > > > + } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > protected Object convertImpl(Class > > > > destinationClass, Object source, > > > > > Locale locale) throws Exception > > { > > > > > - > > > > > + if (destinationClass == null) > > { > > > > > + return null; > > > > > + } > > > > > if > > (destinationClass.isPrimitive() > > > > && source == null) { > > > > > throw new > > > > TransformationException(destinationClass, > > > > > source); > > > > > } > > > > > Index: > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > (revision 362) > > > > > +++ > > > > > > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > (working copy) > > > > > @@ -18,7 +18,9 @@ > > > > > import net.sf.morph.Defaults; > > > > > import net.sf.morph.transform.Converter; > > > > > import > > net.sf.morph.transform.DecoratedConverter; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > > > /** > > > > > * Base class for converts that convert > > objects to > > > > a pretty > > > > > programmer-friendly > > > > > @@ -27,7 +29,8 @@ > > > > > * @author Matt Sgarlata > > > > > * @since Feb 15, 2005 > > > > > */ > > > > > -public abstract class > > BaseToPrettyTextConverter > > > > extends > > > > > BaseReflectorTransformer implements > > > > DecoratedConverter { > > > > > +public abstract class > > BaseToPrettyTextConverter > > > > extends > > > > > BaseReflectorTransformer > > > > > + implements DecoratedConverter, > > > > ImpreciseConverter { > > > > > > > > > > private String prefix; > > > > > private String suffix; > > > > > @@ -161,4 +164,19 @@ > > > > > public void setShowNullValues(boolean > > > > showNullValues) { > > > > > this.showNullValues = > > > > showNullValues; > > > > > } > > > > > + > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + protected boolean > > > > isImpreciseConversionImpl(Class > > > > > destinationClass, Class sourceClass) { > > > > > + return > > > > > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > > destinationClass, sourceClass); > > > > > + } > > > > > + > > > > > + /** > > > > > + * Get the intermediate class passed > > to > > > > the text converter. > > > > > + * @return > > > > > + */ > > > > > + protected Class getIntermediateClass() > > { > > > > > + return StringBuffer.class; > > > > > + } > > > > > } > > > > > Index: > > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > src/core/net/sf/morph/util/NumberUtils.java > > > > (revision 365) > > > > > +++ > > src/core/net/sf/morph/util/NumberUtils.java > > > > (working copy) > > > > > @@ -19,6 +19,7 @@ > > > > > import java.lang.reflect.Method; > > > > > import java.math.BigDecimal; > > > > > import java.math.BigInteger; > > > > > +import java.util.Comparator; > > > > > import java.util.HashMap; > > > > > import java.util.HashSet; > > > > > import java.util.Iterator; > > > > > @@ -69,6 +70,31 @@ > > > > > } > > > > > } > > > > > > > > > > + private static class > > NarrownessComparator > > > > implements Comparator { > > > > > + /** > > > > > + * {@inheritDoc} > > > > > + */ > > > > > + public int compare(Object > > arg0, > > > > Object arg1) { > > > > > + if (arg0 == arg1) { > > > > > + return 0; > > > > > + } > > > > > + Class c0 = > > getType(arg0); > > > > > + Class c1 = > > getType(arg1); > > > > > + if (c0 == c1 || c0 == > > null > > > > || c1 == null) { > > > > > + return 0; > > > > > + } > > > > > + return > > > > > > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > > + } > > > > > + > > > > > + private Class getType(Object > > o) { > > > > > + if > > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > > + return (Class) > > o; > > > > > + } > > > > > + Class test = > > > > ClassUtils.getClass(o); > > > > > + return > > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > > : null; > > > > > + } > > > > > + } > > > > > + > > > > > /** > > > > > * A Map of BigDecimals keyed by Class > > that > > > > indicate the maximum > > > > > value that > > > > > * the given (Number) Class may taken > > on. > > > > > @@ -80,11 +106,16 @@ > > > > > * the given (Number) Class may taken > > on. > > > > > */ > > > > > public static final Map > > MINIMUMS_FOR_TYPES; > > > > > - > > > > > - public static final Map > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > > > - public static final Map > > NUMBER_FACTORIES; > > > > > + /** > > > > > + * Comparator of class/object type > > > > narrowness. > > > > > + */ > > > > > + public static final Comparator > > > > NARROWNESS_COMPARATOR = new > > > > > NarrownessComparator(); > > > > > > > > > > + private static final Map > > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > + > > > > > + private static final Map > > NUMBER_FACTORIES; > > > > > + > > > > > /** > > > > > * Used by {@link > > > > NumberUtils#isNumber(Class)}. > > > > > */ > > > > > Index: > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > > > > > > =================================================================== > > > > > --- > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > (revision 357) > > > > > +++ > > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > (working copy) > > > > > @@ -1,5 +1,5 @@ > > > > > /* > > > > > - * Copyright 2004-2005, 2007 the original > > author > > > > or authors. > > > > > + * Copyright 2004-2005, 2007-2008 the > > original > > > > author or authors. > > > > > * > > > > > * Licensed under the Apache License, Version > > 2.0 > > > > (the "License"); you may > > > > > not > > > > > * use this file except in compliance with the > > > > License. You may obtain a > > > > > copy of > > > > > @@ -26,6 +26,7 @@ > > > > > import net.sf.morph.transform.Converter; > > > > > import net.sf.morph.transform.Copier; > > > > > import > > > > net.sf.morph.transform.ExplicitTransformer; > > > > > +import > > net.sf.morph.transform.ImpreciseConverter; > > > > > import > > > > net.sf.morph.transform.TransformationException; > > > > > import net.sf.morph.transform.Transformer; > > > > > > > > > > @@ -90,6 +91,24 @@ > > > > > } > > > > > > > > > > /** > > > > > + * Learn whether > > > > <code>transformer</code>'s conversion > > > > > + * of <code>sourceClass</code> to > > > > <code>destinationClass</code> > > > > > might yield an imprecise result. > > > > > + * @param transformer > > > > > + * @param destinationClass > > > > > + * @param sourceClass > > > > > + * @return boolean > > > > > + * @see ImpreciseConverter > > > > > + */ > > > > > + public static boolean > > > > isImpreciseConversion(Transformer > > > > > transformer, > > > > > + Class > > destinationClass, > > > > Class sourceClass) { > > > > > + if (transformer instanceof > > > > ImpreciseConverter) { > > > > > + return > > > > ((ImpreciseConverter) > > > > > transformer).isImpreciseConversion( > > > > > + > > > > destinationClass, sourceClass); > > > > > + } > > > > > + return destinationClass == > > null && > > > > sourceClass != null; > > > > > + } > > > > > + > > > > > + /** > > > > > * Performs a transformation of one > > object > > > > graph into another > > > > > object graph. > > > > > * > > > > > * @param destinationType > > > > > > > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > > This SF.net email is sponsored by: Microsoft > > > > > Defy all challenges. Microsoft(R) Visual > > Studio > > > > 2005. > > > > > > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > > > _______________________________________________ > > > > > morph-developer mailing list > > > > > mor...@li... > > > > > > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > -- > > > > This message is intended only for the named > > > > recipient. If you are not the > > > > intended recipient, you are notified that > > > > disclosing, copying, distributing, > > > > or taking any action in reliance on the contents > > of > > > > this information is > > > > strictly prohibited. > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual Studio > > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > Never miss a thing. Make Yahoo your home page. > > > http://www.yahoo.com/r/hs > > > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > 2005. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > -- > > This message is intended only for the named > > recipient. If you are not the > > intended recipient, you are notified that > > disclosing, copying, distributing, > > or taking any action in reliance on the contents of > > this information is > > strictly prohibited. > > > > ------------------------------------------------------------------------- > > Check out the new SourceForge.net Marketplace. > > It's the best place to buy or sell services for > > just about anything Open Source. > > > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > ____________________________________________________________________________________ > Never miss a thing. Make Yahoo your home page. > http://www.yahoo.com/r/hs > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > -- This message is intended only for the named recipient. If you are not the intended recipient, you are notified that disclosing, copying, distributing, or taking any action in reliance on the contents of this information is strictly prohibited. |
From: Matt B. <gud...@ya...> - 2008-01-07 17:39:12
|
I got the renamed call, but the method still seems to be missing on ClassUtils. ;) --- Matt Sgarlata <mat...@sp...> wrote: > Sorry about that! I renamed the method > isCommonsCollections3Present because > the class referenced is new in 3.x (I meant to do > this before, but I > forgot). > > Matt S > > On Jan 7, 2008 11:32 AM, Matt Benson > <gud...@ya...> wrote: > > > > > --- Matt Sgarlata > <mat...@sp...> > > wrote: > > > > > I have been thinking more about this approach, > and > > > it's really starting to > > > grow on me. I do have one concern though, can > this > > > approach be extended to > > > Copiers? For example, a Map -> Object copy > could > > > probably be considered an > > > imprecise transformation because the Map may > have > > > more keys than the Object > > > has properties. > > > > > > In addition to your approach, I also like the > idea > > > of cleaning up the > > > internal implementation in Morph so that > ordering of > > > source and destination > > > classes is preserved for the following reasons: > > > 1) for at least some portion of users, setting > the > > > order of source and > > > destination classes will make sense as an > indication > > > of the transformer's > > > preferences for performing transformations (so > for > > > this class of users, > > > creating new transformers that play nicely with > the > > > ChainedTransformerTestCase will be simpler) > > > 2) I think a general change from using HashSets > to > > > ordered sets in Morph's > > > implementation will mean transformations happen > more > > > consistently across > > > JVMs and across time on the same JVM, leading to > a > > > more stable platform > > > > > > So, what I did is I basically went through the > Morph > > > codebase and replaced > > > HashSets with ordered sets (preference order is: > JDK > > > 1.4 LinkedHashSet, > > > Commons-collections ListOrderedSet, copy of > > > ListOrderedSet in > > > net.sf.morph.util). I was never able to modify > the > > > ChainedTransformerTestCase so that it > consistently > > > threw an error. However, > > > after working on the test case long enough, > > > eventually something changed in > > > my environment so that the test started to fail. > I > > > did my change of > > > HashSets to ordered sets, and that was able to > fix > > > the broken test. > > > > I seem to be missing a > > ClassUtils.isCommonsCollectionsPresent() method > after > > syncing. I'll create my own for now, but it does > seem > > to be missing. Thanks! > > > > -Matt B > > > > > > > > I checked in my changes for you to take a look > at... > > > > > > Matt S > > > > > > On Jan 6, 2008 12:59 PM, Matt Benson > > > <gud...@ya...> wrote: > > > > > > > Here's what I've got. > > > > > > > > -Matt B > > > > > > > > > > > > > > > > > > > > > > > > ____________________________________________________________________________________ > > > > Be a better friend, newshound, and > > > > know-it-all with Yahoo! Mobile. Try it now. > > > > > > > > > > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > > > > > > > Index: > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > (revision 357) > > > > +++ > > > > > > > > > > > > src/core/net/sf/morph/transform/transformers/SimpleDelegatingTransformer.java > > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -35,6 +35,7 @@ > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > import > net.sf.morph.transform.DecoratedCopier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import net.sf.morph.transform.NodeCopier; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > @@ -93,11 +94,11 @@ > > > > * @since Dec 12, 2004 > > > > */ > > > > public class SimpleDelegatingTransformer > extends > > > BaseCompositeTransformer > > > > implements > > > > - SpecializableComposite, > > > ExplicitTransformer, Transformer, > > > > DecoratedCopier, DecoratedConverter, Cloneable > { > > > > + SpecializableComposite, > > > ExplicitTransformer, Transformer, > > > > DecoratedCopier, > > > > + DecoratedConverter, Cloneable, > > > ImpreciseConverter { > > > > > > > > //TODO extract > BaseDelegatingTransformer > > > with pluggable delegate > > > > selection > > > > > > > > - > > > > private static class MapThreadLocal > extends > > > ThreadLocal { > > > > protected Object initialValue() > { > > > > return new HashMap(); > > > > @@ -138,6 +139,7 @@ > > > > } > > > > > > > > private Specializer specializer; > > > > + private boolean > preferPreciseTransformers; > > > > > > > > private transient ThreadLocal > > > > visitedSourceToDestinationMapThreadLocal = new > > > MapThreadLocal(); > > > > private transient ThreadLocal > > > stackDepthThreadLocal = new > > > > StackDepthThreadLocal(); > > > > @@ -225,6 +227,14 @@ > > > > > > > > /** > > > > * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > TransformerUtils.isImpreciseConversion > > > > (getTransformer(destinationClass, > > > > + sourceClass), > > > destinationClass, > > > > sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > * @see > > > > > > > > > > net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl() > > > > */ > > > > protected Class[] > getSourceClassesImpl() > > > throws Exception { > > > > @@ -477,6 +487,7 @@ > > > > * if no suitable > transformer > > > could be found > > > > */ > > > > private Transformer > getTransformer(Class > > > transformerType, Class > > > > destinationClass, Class sourceClass) throws > > > TransformationException { > > > > + Transformer candidate = null; > > > > for (int i = 0; i < > > > components.length; i++) { > > > > // if the transformer > is > > > the correct type > > > > Transformer transformer > = > > > (Transformer) > > > > components[i]; > > > > @@ -484,6 +495,13 @@ > > > > // if the > > > transformer is capable of > > > > performing the transformation > > > > if > > > (TransformerUtils.isTransformable( > > > > > > > transformer, > > > > destinationClass, sourceClass)) { > > > > + if > > > (isPreferPreciseTransformers() > > > > + > > > && candidate == > > > > null > > > > + > > > && > > > > > > > > TransformerUtils.isImpreciseConversion(transformer, > > > > + > > > > destinationClass, sourceClass)) { > > > > + > > > candidate = transformer; > > > > + > > > continue; > > > > + } > > > > if > > > (getLog().isTraceEnabled()) { > > > > > > > getLog().trace("Using " > > > > > > > + > > > > > > > > ClassUtils.getUnqualifiedClassName(transformerType) > > > > @@ -496,7 +514,9 @@ > > > > return > > > transformer; > > > > } > > > > } > > > > - > > > > + if (candidate != null) > { > > > > + return > candidate; > > > > + } > > > > } > > > > throw new > TransformationException( > > > > "Could not find a > > > transformer that can transform > > > > objects of " > > > > @@ -612,4 +632,20 @@ > > > > source); > > > > } > > > > > > > > + /** > > > > + * Get the preferPreciseTransformers. > > > > + * @return boolean > > > > + */ > > > > + public boolean > > > isPreferPreciseTransformers() { > > > > + return > preferPreciseTransformers; > > > > + } > > > > + > > > > + /** > > > > + * Set the preferPreciseTransformers. > > > Default false. > > > > + * @param preferPreciseTransformers > the > > > boolean to set > > > > + */ > > > > + public void > > > setPreferPreciseTransformers(boolean > > > > preferPreciseTransformers) { > > > > + this.preferPreciseTransformers > = > > > > preferPreciseTransformers; > > > > + } > > > > + > > > > } > > > > \ No newline at end of file > > > > Index: > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > (revision 358) > > > > +++ > > > > > > src/core/net/sf/morph/transform/transformers/BaseTransformer.java > > > > (working copy) > > > > @@ -570,6 +570,35 @@ > > > > } > > > > } > > > > > > > > + /** > > > > + * Implementation of > isImpreciseConversion > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return destinationClass == > null && > > > sourceClass != null; > > > > + } > > > > + > > > > + /** > > > > + * Learn whether the specified > conversion > > > yields an imprecise > > > > result. > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + */ > > > > + public final boolean > > > isImpreciseConversion(Class destinationClass, > > > > Class sourceClass) { > > > > + try { > > > > + return > > > isImpreciseConversionImpl(destinationClass, > > > > sourceClass); > > > > + } catch (Exception e) { > > > > + if (e instanceof > > > RuntimeException && > > > > !isWrappingRuntimeExceptions()) { > > > > + throw > > > (RuntimeException) e; > > > > + } > > > > + throw new > > > TransformationException("Could not > > > > determine if conversion of " > > > > + + > > > sourceClass + " to " + > > > > destinationClass > > > > + + " > > > results in a loss of > > > > precision", e); > > > > + } > > > > + } > > > > + > > > > // property getters and setters > > > > > > > > /** > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > (revision 357) > > > > +++ > > > > > > src/core/net/sf/morph/transform/transformers/ChainedTransformer.java > > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -16,6 +16,7 @@ > > > > package net.sf.morph.transform.transformers; > > > > > > > > import java.util.ArrayList; > > > > +import java.util.Iterator; > > > > import java.util.List; > > > > import java.util.Locale; > > > > > > > > @@ -25,6 +26,7 @@ > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > import > net.sf.morph.transform.DecoratedCopier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > import > > > net.sf.morph.transform.copiers.CopierDecorator; > > > > @@ -40,7 +42,7 @@ > > > > * @since Nov 24, 2004 > > > > */ > > > > public class ChainedTransformer extends > > > BaseCompositeTransformer > > > > implements > > > > - DecoratedConverter, > > > DecoratedCopier, ExplicitTransformer { > > > > + DecoratedConverter, > > > DecoratedCopier, ExplicitTransformer, > > > > ImpreciseConverter { > > > > > > > > private Converter copyConverter; > > > > > > > > @@ -67,6 +69,14 @@ > > > > } > > > > > > > > /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + List conversionPath = > > > getConversionPath(destinationClass, > > > > sourceClass); > > > > + return > !isPrecise(conversionPath, > > > sourceClass, 0); > > > > + } > > > > + > > > > + /** > > > > * Get the converter used when using a > > > ChainedTransformer as a > > > > Copier. > > > > * @return > > > > */ > > > > @@ -113,6 +123,7 @@ > > > > throw new > > > TransformationException(destinationClass, > > > > sourceType, null, > > > > > "Chained > > > conversion path could not > > > > be determined"); > > > > } > > > > + log.debug("Using chained > > > conversion path " + > > > > conversionPath); > > > > Object o = source; > > > > for (int i = 0; i < > > > conversionPath.size(); i++) { > > > > o = > > > getConverter(chain[i]).convert((Class) > > > > conversionPath.get(i), o, locale); > > > > @@ -144,6 +155,7 @@ > > > > throw new > > > TransformationException(destinationClass, > > > > source, null, > > > > > "Chained > > > conversion path could not > > > > be determined"); > > > > } > > > > + log.debug("Using chained > > > conversion path " + > > > > conversionPath); > > > > Object last = > > > getCopyConverter().convert((Class) > > > > conversionPath.get(chain.length - 2), source, > > > locale); > > > > ((Copier) > copier).copy(destination, > > > last, locale); > > > > } > > > > @@ -192,13 +204,7 @@ > > > > * @return List > > > > */ > > > > protected List getConversionPath(Class > > > destinationType, Class > > > > sourceType) { > > > > - if (sourceType != null) { > > > > - List withoutNull = > > > > getConversionPath(destinationType, sourceType, > 0, > > > false); > > > > - if (withoutNull != > null) { > > > > - return > > > withoutNull; > > > > - } > > > > - } > > > > - return > > > getConversionPath(destinationType, sourceType, > 0, > > > > true); > > > > + return > > > getConversionPath(destinationType, sourceType, > 0); > > > > } > > > > > > > > /** > > > > @@ -210,7 +216,7 @@ > > > > * @param allowNull > > > > * @return List > > > > */ > > > > - private List getConversionPath(Class > > > destinationType, Class > > > > sourceType, int index, boolean allowNull) { > > > > + private List getConversionPath(Class > > > destinationType, Class > > > > sourceType, int index) { > > > > Transformer[] chain = > getChain(); > > > > Transformer c = chain[index]; > > > > if (index + 1 == chain.length) > { > > > > @@ -221,22 +227,38 @@ > > > > } > > > > return null; > > > > } > > > > + List possibleResult = null; > > > > Class[] available = > > > c.getDestinationClasses(); > > > > for (int i = 0; i < > > > available.length; i++) { > > > > - if (available[i] == > null > > > && !allowNull) { > > > > - continue; > > > > - } > > > > if > > > (TransformerUtils.isTransformable(c, > > > > available[i], sourceType)) { > > > > - List tail = > > > > getConversionPath(destinationType, > available[i], > > > index + 1, allowNull); > > > > + List tail = > > > > getConversionPath(destinationType, > available[i], > > > index + 1); > > > > if (tail != > null) { > > > > > tail.add(0, > > > available[i]); > > > > - return > > > tail; > > > > + if > > > (isPrecise(tail, sourceType, > > > > index)) { > > > > + > > > return tail; > > > > + } > > > > + > > > possibleResult = tail; > > > > } > > > > } > > > > } > > > > - return null; > > > > + return possibleResult; > > > > } > > > > > > > > + private boolean isPrecise(List > > > conversionPath, Class sourceType, > > > > int index) { > > > > + Transformer[] chain = > getChain(); > > > > + Class currentSource = > sourceType; > > > > + int i = 0; > > > > + for (Iterator iter = > > > conversionPath.iterator(); > > > > iter.hasNext(); i++) { > > > > + Class currentDest = > > > (Class) iter.next(); > > > > + if > > > > (TransformerUtils.isImpreciseConversion(chain[index > > > > + i], currentDest, > > > > + > > > currentSource)) { > > > > + return false; > > > > + } > > > > + currentSource = > > > currentDest; > > > > + } > > > > + return true; > > > > + } > > > > + > > > > /** > > > > * Get the components array narrowed to > a > > > Transformer[]. > > > > * @return Transformer[] > > > > Index: > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > (revision > > > > 0) > > > > +++ > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > (revision > > > > 0) > > > > @@ -0,0 +1,32 @@ > > > > +/* > > > > + * Copyright 2008 the original author or > authors. > > > > + * > > > > + * Licensed under the Apache License, Version > 2.0 > > > (the "License"); you > > > > may not > > > > + * use this file except in compliance with > the > > > License. You may obtain a > > > > copy of > > > > + * the License at > > > > + * > > > > + * http://www.apache.org/licenses/LICENSE-2.0 > > > > + * > > > > + * Unless required by applicable law or > agreed to > > > in writing, software > > > > + * distributed under the License is > distributed > > > on an "AS IS" BASIS, > > > > WITHOUT > > > > + * WARRANTIES OR CONDITIONS OF ANY KIND, > either > > > express or implied. See > > > > the > > > > + * License for the specific language > governing > > > permissions and > > > > limitations under > > > > + * the License. > > > > + */ > > > > +package net.sf.morph.transform; > > > > + > > > > +/** > > > > + * Defines a converter whose operation may > result > > > in a loss of data > > > > precision. > > > > + * > > > > + * @author mbenson > > > > + * @since Morph 1.0.2 > > > > + */ > > > > +public interface ImpreciseConverter extends > > > Converter { > > > > + /** > > > > + * Learn whether the specified > conversion > > > might yield an imprecise > > > > result. > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + */ > > > > + boolean isImpreciseConversion(Class > > > destinationClass, Class > > > > sourceClass); > > > > +} > > > > > > > > Property changes on: > > > > > > > > > > src/core/net/sf/morph/transform/ImpreciseConverter.java > > > > > > > > > > ___________________________________________________________________ > > > > Name: svn:eol-style > > > > + native > > > > > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/ObjectToTextConverter.java > > > > (working copy) > > > > @@ -20,7 +20,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts an object to a textual > representation > > > by calling the object's > > > > @@ -32,7 +34,7 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 24, 2004 > > > > */ > > > > -public class ObjectToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class ObjectToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > > > > > private Converter textConverter; > > > > > > > > @@ -52,6 +54,13 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > (revision 361) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TextToNumberConverter.java > > > > (working copy) > > > > @@ -32,7 +32,7 @@ > > > > import org.apache.commons.logging.LogFactory; > > > > > > > > /** > > > > - * Converts basic text types into primtive > > > numbers or {@link > > > > java.lang.Number} > > > > + * Converts basic text types into primitive > > > numbers or {@link > > > > java.lang.Number} > > > > * objects. > > > > * > > > > * @author Matt Sgarlata > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > (revision 363) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/NumberToTextConverter.java > > > > (working copy) > > > > @@ -21,7 +21,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts {@link java.lang.Number}s into > basic > > > text types ({@link > > > > java.lang.String}, > > > > @@ -30,7 +32,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Jan 26, 2006 > > > > */ > > > > -public class NumberToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class NumberToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > + ImpreciseConverter { > > > > > > > > private Converter textConverter; > > > > private Converter numberConverter; > > > > @@ -58,6 +61,13 @@ > > > > } > > > > > > > > /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > * Get the number converter used by > this > > > NumberToTextConverter. > > > > * @return Converter > > > > */ > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > (revision 360) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TimeToTextConverter.java > > > > (working copy) > > > > @@ -22,7 +22,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts the basic time types ({@link > > > java.util.Date} and > > > > @@ -33,7 +35,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 31, 2004 > > > > */ > > > > -public class TimeToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > +public class TimeToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > + ImpreciseConverter { > > > > > > > > private DateFormat dateFormat; > > > > private Converter timeConverter; > > > > @@ -55,6 +58,13 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > } > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > (revision 357) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/TextConverter.java > > > > (working copy) > > > > @@ -22,6 +22,7 @@ > > > > > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > import net.sf.morph.util.ClassUtils; > > > > @@ -43,7 +44,7 @@ > > > > * @since Jan 2, 2005 > > > > */ > > > > public class TextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, > > > > - ExplicitTransformer { > > > > + ExplicitTransformer, > > > ImpreciseConverter { > > > > > > > > private static final Class > CHAR_SEQUENCE = > > > > ClassUtils.isJdk14OrHigherPresent() ? > ClassUtils > > > > > > > .convertToClass("java.lang.CharSequence") > > > > @@ -62,14 +63,7 @@ > > > > s.add(Character.class); > > > > s.add(char.class); > > > > s.add(null); > > > > - if (CHAR_SEQUENCE != null) { > > > > - s.add(CHAR_SEQUENCE); > > > > - try { > > > > - > > > CONSTRUCTOR_CACHE.put(CHAR_SEQUENCE, > > > > StringBuffer.class.getConstructor(new Class[] > { > > > String.class })); > > > > - } catch (Exception e) > { > > > > - //nope > > > > - } > > > > - } > > > > + s.add(CHAR_SEQUENCE); > > > > SOURCE_AND_DESTINATION_TYPES = > > > (Class[]) s.toArray(new > > > > Class[s.size()]); > > > > } > > > > > > > > @@ -106,7 +100,8 @@ > > > > } > > > > return new > > > Character(string.charAt(0)); > > > > } > > > > - if (destinationClass == > > > String.class) { > > > > + if (destinationClass == > > > String.class > > > > + || > > > (destinationClass == CHAR_SEQUENCE && > > > > CHAR_SEQUENCE != null)) { > > > > return string; > > > > } > > > > if (destinationClass == > > > byte[].class) { > > > > @@ -152,6 +147,16 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + if > > > > (super.isImpreciseConversionImpl(destinationClass, > > > > sourceClass)) { > > > > + return true; > > > > + } > > > > + return > isChar(destinationClass) && > > > !isChar(sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isAutomaticallyHandlingNulls() { > > > > return !isEmptyNull(); > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/BooleanToTextConverter.java > > > > (working copy) > > > > @@ -20,8 +20,10 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Converts boolean values to text values. > > > Subclasses can build in > > > > support for > > > > @@ -32,10 +34,10 @@ > > > > * @author Matt Sgarlata > > > > * @since Jan 9, 2005 > > > > */ > > > > -public class BooleanToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > - > > > > +public class BooleanToTextConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > + > > > > private static final Class[] > SOURCE_TYPES = > > > { Boolean.class, > > > > boolean.class }; > > > > - > > > > + > > > > private Converter textConverter; > > > > > > > > /** > > > > @@ -93,9 +95,16 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, String.class); > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected boolean > > > isWrappingRuntimeExceptions() { > > > > return true; > > > > - } > > > > + } > > > > > > > > /** > > > > * Get the text converter used by this > > > BaseToPrettyTextConverter. > > > > Index: > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > (revision 363) > > > > +++ > > > > > > src/core/net/sf/morph/transform/converters/NumberConverter.java > > > > (working copy) > > > > @@ -19,6 +19,7 @@ > > > > import java.util.Locale; > > > > > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import > > > net.sf.morph.transform.support.NumberRounder; > > > > import > > > > net.sf.morph.transform.transformers.BaseTransformer; > > > > @@ -31,8 +32,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Dec 14, 2004 > > > > */ > > > > -public class NumberConverter extends > > > BaseTransformer implements > > > > DecoratedConverter { > > > > - > > > > +public class NumberConverter extends > > > BaseTransformer implements > > > > DecoratedConverter, ImpreciseConverter { > > > > + > > > > private static final Class[] > > > SOURCE_AND_DESTINATION_TYPES = { > > > > Number.class, byte.class, > > > short.class, int.class, > > > > long.class, > > > > float.class, double.class, null > > > > @@ -116,9 +117,20 @@ > > > > /** > > > > * {@inheritDoc} > > > > */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > super.isImpreciseConversionImpl(destinationClass, > > > > sourceClass) > > > > + || > > > > > > > > > > NumberUtils.NARROWNESS_COMPARATOR.compare(destinationClass, > > > > + > > > sourceClass) < 0; > > > > + } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > protected Object convertImpl(Class > > > destinationClass, Object source, > > > > Locale locale) throws Exception > { > > > > - > > > > + if (destinationClass == null) > { > > > > + return null; > > > > + } > > > > if > (destinationClass.isPrimitive() > > > && source == null) { > > > > throw new > > > TransformationException(destinationClass, > > > > source); > > > > } > > > > Index: > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > > > > > > > =================================================================== > > > > --- > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > (revision 362) > > > > +++ > > > > > > > > > > src/core/net/sf/morph/transform/converters/BaseToPrettyTextConverter.java > > > > (working copy) > > > > @@ -18,7 +18,9 @@ > > > > import net.sf.morph.Defaults; > > > > import net.sf.morph.transform.Converter; > > > > import > net.sf.morph.transform.DecoratedConverter; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > > > > net.sf.morph.transform.transformers.BaseReflectorTransformer; > > > > +import net.sf.morph.util.TransformerUtils; > > > > > > > > /** > > > > * Base class for converts that convert > objects to > > > a pretty > > > > programmer-friendly > > > > @@ -27,7 +29,8 @@ > > > > * @author Matt Sgarlata > > > > * @since Feb 15, 2005 > > > > */ > > > > -public abstract class > BaseToPrettyTextConverter > > > extends > > > > BaseReflectorTransformer implements > > > DecoratedConverter { > > > > +public abstract class > BaseToPrettyTextConverter > > > extends > > > > BaseReflectorTransformer > > > > + implements DecoratedConverter, > > > ImpreciseConverter { > > > > > > > > private String prefix; > > > > private String suffix; > > > > @@ -161,4 +164,19 @@ > > > > public void setShowNullValues(boolean > > > showNullValues) { > > > > this.showNullValues = > > > showNullValues; > > > > } > > > > + > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > + protected boolean > > > isImpreciseConversionImpl(Class > > > > destinationClass, Class sourceClass) { > > > > + return > > > > > > TransformerUtils.isImpreciseConversion(getTextConverter(), > > > > destinationClass, sourceClass); > > > > + } > > > > + > > > > + /** > > > > + * Get the intermediate class passed > to > > > the text converter. > > > > + * @return > > > > + */ > > > > + protected Class getIntermediateClass() > { > > > > + return StringBuffer.class; > > > > + } > > > > } > > > > Index: > src/core/net/sf/morph/util/NumberUtils.java > > > > > > > > > > =================================================================== > > > > --- > src/core/net/sf/morph/util/NumberUtils.java > > > (revision 365) > > > > +++ > src/core/net/sf/morph/util/NumberUtils.java > > > (working copy) > > > > @@ -19,6 +19,7 @@ > > > > import java.lang.reflect.Method; > > > > import java.math.BigDecimal; > > > > import java.math.BigInteger; > > > > +import java.util.Comparator; > > > > import java.util.HashMap; > > > > import java.util.HashSet; > > > > import java.util.Iterator; > > > > @@ -69,6 +70,31 @@ > > > > } > > > > } > > > > > > > > + private static class > NarrownessComparator > > > implements Comparator { > > > > + /** > > > > + * {@inheritDoc} > > > > + */ > > > > + public int compare(Object > arg0, > > > Object arg1) { > > > > + if (arg0 == arg1) { > > > > + return 0; > > > > + } > > > > + Class c0 = > getType(arg0); > > > > + Class c1 = > getType(arg1); > > > > + if (c0 == c1 || c0 == > null > > > || c1 == null) { > > > > + return 0; > > > > + } > > > > + return > > > > > > > > > > getMaximumForType(c0).compareTo(getMaximumForType(c1)); > > > > + } > > > > + > > > > + private Class getType(Object > o) { > > > > + if > > > (MAXIMUMS_FOR_TYPES.containsKey(o)) { > > > > + return (Class) > o; > > > > + } > > > > + Class test = > > > ClassUtils.getClass(o); > > > > + return > > > MAXIMUMS_FOR_TYPES.containsKey(test) ? test > > > > : null; > > > > + } > > > > + } > > > > + > > > > /** > > > > * A Map of BigDecimals keyed by Class > that > > > indicate the maximum > > > > value that > > > > * the given (Number) Class may taken > on. > > > > @@ -80,11 +106,16 @@ > > > > * the given (Number) Class may taken > on. > > > > */ > > > > public static final Map > MINIMUMS_FOR_TYPES; > > > > - > > > > - public static final Map > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > > > > > - public static final Map > NUMBER_FACTORIES; > > > > + /** > > > > + * Comparator of class/object type > > > narrowness. > > > > + */ > > > > + public static final Comparator > > > NARROWNESS_COMPARATOR = new > > > > NarrownessComparator(); > > > > > > > > + private static final Map > > > WRAPPERS_FOR_PRIMITIVE_TYPES; > > > > + > > > > + private static final Map > NUMBER_FACTORIES; > > > > + > > > > /** > > > > * Used by {@link > > > NumberUtils#isNumber(Class)}. > > > > */ > > > > Index: > > > src/core/net/sf/morph/util/TransformerUtils.java > > > > > > > > > > =================================================================== > > > > --- > > > src/core/net/sf/morph/util/TransformerUtils.java > > > (revision 357) > > > > +++ > > > src/core/net/sf/morph/util/TransformerUtils.java > > > (working copy) > > > > @@ -1,5 +1,5 @@ > > > > /* > > > > - * Copyright 2004-2005, 2007 the original > author > > > or authors. > > > > + * Copyright 2004-2005, 2007-2008 the > original > > > author or authors. > > > > * > > > > * Licensed under the Apache License, Version > 2.0 > > > (the "License"); you may > > > > not > > > > * use this file except in compliance with the > > > License. You may obtain a > > > > copy of > > > > @@ -26,6 +26,7 @@ > > > > import net.sf.morph.transform.Converter; > > > > import net.sf.morph.transform.Copier; > > > > import > > > net.sf.morph.transform.ExplicitTransformer; > > > > +import > net.sf.morph.transform.ImpreciseConverter; > > > > import > > > net.sf.morph.transform.TransformationException; > > > > import net.sf.morph.transform.Transformer; > > > > > > > > @@ -90,6 +91,24 @@ > > > > } > > > > > > > > /** > > > > + * Learn whether > > > <code>transformer</code>'s conversion > > > > + * of <code>sourceClass</code> to > > > <code>destinationClass</code> > > > > might yield an imprecise result. > > > > + * @param transformer > > > > + * @param destinationClass > > > > + * @param sourceClass > > > > + * @return boolean > > > > + * @see ImpreciseConverter > > > > + */ > > > > + public static boolean > > > isImpreciseConversion(Transformer > > > > transformer, > > > > + Class > destinationClass, > > > Class sourceClass) { > > > > + if (transformer instanceof > > > ImpreciseConverter) { > > > > + return > > > ((ImpreciseConverter) > > > > transformer).isImpreciseConversion( > > > > + > > > destinationClass, sourceClass); > > > > + } > > > > + return destinationClass == > null && > > > sourceClass != null; > > > > + } > > > > + > > > > + /** > > > > * Performs a transformation of one > object > > > graph into another > > > > object graph. > > > > * > > > > * @param destinationType > > > > > > > > > > > > > > ------------------------------------------------------------------------- > > > > This SF.net email is sponsored by: Microsoft > > > > Defy all challenges. Microsoft(R) Visual > Studio > > > 2005. > > > > > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > > > > _______________________________________________ > > > > morph-developer mailing list > > > > mor...@li... > > > > > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > > > > -- > > > This message is intended only for the named > > > recipient. If you are not the > > > intended recipient, you are notified that > > > disclosing, copying, distributing, > > > or taking any action in reliance on the contents > of > > > this information is > > > strictly prohibited. > > > > > > > ------------------------------------------------------------------------- > > > This SF.net email is sponsored by: Microsoft > > > Defy all challenges. Microsoft(R) Visual Studio > > > 2005. > > > > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/> > > _______________________________________________ > > > morph-developer mailing list > > > mor...@li... > > > > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > > > > > > > > > ____________________________________________________________________________________ > > Never miss a thing. Make Yahoo your home page. > > http://www.yahoo.com/r/hs > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio > 2005. > > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > morph-developer mailing list > > mor...@li... > > > https://lists.sourceforge.net/lists/listinfo/morph-developer > > > > > > -- > This message is intended only for the named > recipient. If you are not the > intended recipient, you are notified that > disclosing, copying, distributing, > or taking any action in reliance on the contents of > this information is > strictly prohibited. > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace> _______________________________________________ > morph-developer mailing list > mor...@li... > https://lists.sourceforge.net/lists/listinfo/morph-developer > ____________________________________________________________________________________ Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs |