Re: [morph-developer] [PATCH] ImpreciseConverter as suggested
Brought to you by:
orangeherbert,
sgarlatm
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. |