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 |