From: Matt S. <mat...@sp...> - 2008-01-07 16:58:28
|
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. |