Skip to content

Commit

Permalink
TAP5-2650: Change TypeCoercer configuration to be a mapped one
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagohp committed Dec 1, 2020
1 parent b2d454d commit 5d1513b
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
// limitations under the License.
package org.apache.tapestry5.beanmodel;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.apache.tapestry5.beanmodel.internal.services.BeanModelSourceImpl;
import org.apache.tapestry5.beanmodel.internal.services.PropertyAccessImpl;
import org.apache.tapestry5.beanmodel.internal.services.PropertyConduitSourceImpl;
import org.apache.tapestry5.beanmodel.services.BeanModelSource;
import org.apache.tapestry5.beanmodel.services.PlasticProxyFactoryImpl;
import org.apache.tapestry5.beanmodel.services.PropertyConduitSource;
import org.apache.tapestry5.commons.AnnotationProvider;
import org.apache.tapestry5.commons.Configuration;
import org.apache.tapestry5.commons.MappedConfiguration;
import org.apache.tapestry5.commons.ObjectLocator;
import org.apache.tapestry5.commons.internal.BasicDataTypeAnalyzers;
import org.apache.tapestry5.commons.internal.BasicTypeCoercions;
Expand All @@ -27,16 +31,13 @@
import org.apache.tapestry5.commons.internal.services.TypeCoercerImpl;
import org.apache.tapestry5.commons.internal.util.TapestryException;
import org.apache.tapestry5.commons.services.CoercionTuple;
import org.apache.tapestry5.commons.services.CoercionTuple.Key;
import org.apache.tapestry5.commons.services.DataTypeAnalyzer;
import org.apache.tapestry5.commons.services.PlasticProxyFactory;
import org.apache.tapestry5.commons.services.PropertyAccess;
import org.apache.tapestry5.commons.services.TypeCoercer;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;

/**
* Utility class for creating {@link BeanModelSource} instances without
* Tapestry-IoC. Usage of Tapestry-IoC is still recommended.
Expand Down Expand Up @@ -172,28 +173,39 @@ private void createTypeCoercer()
typeCoercer = new TypeCoercerImpl(configuration.getTuples());
}

final private static class CoercionTupleConfiguration implements Configuration<CoercionTuple>
final private static class CoercionTupleConfiguration implements MappedConfiguration<CoercionTuple.Key, CoercionTuple>
{

final private Collection<CoercionTuple> tuples = new ArrayList<CoercionTuple>();
final private Map<CoercionTuple.Key, CoercionTuple> tuples = new HashMap<>();

@Override
public void add(CoercionTuple tuble)
public void add(CoercionTuple.Key key, CoercionTuple tuple)
{
tuples.add(tuble);
tuples.put(key, tuple);
}

@Override
public void addInstance(Class<? extends CoercionTuple> clazz)
public void addInstance(CoercionTuple.Key key, Class<? extends CoercionTuple> clazz)
{
throw new RuntimeException("Not implemented");
}

public Collection<CoercionTuple> getTuples()
public Map<CoercionTuple.Key, CoercionTuple> getTuples()
{
return tuples;
}

@Override
public void override(Key key, CoercionTuple value)
{
throw new RuntimeException("Not implemented");
}

@Override
public void overrideInstance(Key key, Class<? extends CoercionTuple> clazz) {
throw new RuntimeException("Not implemented");
}

}

final private static class AutobuildOnlyObjectLocator implements ObjectLocator {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.util.Collections;
import java.util.List;

import org.apache.tapestry5.commons.Configuration;
import org.apache.tapestry5.commons.MappedConfiguration;
import org.apache.tapestry5.commons.services.Coercion;
import org.apache.tapestry5.commons.services.CoercionTuple;
import org.apache.tapestry5.commons.services.TypeCoercer;
Expand All @@ -39,7 +39,8 @@ public class BasicTypeCoercions
/**
* Provides the basic type coercions to a {@link Configuration} instance.
*/
public static void provideBasicTypeCoercions(Configuration<CoercionTuple> configuration)
public static void provideBasicTypeCoercions(
MappedConfiguration<CoercionTuple.Key, CoercionTuple> configuration)
{
add(configuration, Object.class, String.class, new Coercion<Object, String>()
{
Expand Down Expand Up @@ -310,31 +311,20 @@ public Object[] coerce(Collection input)
}
});

configuration.add(CoercionTuple.create(Flow.class, List.class, new Coercion<Flow, List>()
{
@Override
public List coerce(Flow input)
{
return input.toList();
}
}));
CoercionTuple<Flow, List> flowToListCoercion = CoercionTuple.create(Flow.class, List.class, Flow::toList);
configuration.add(flowToListCoercion.getKey(), flowToListCoercion);

configuration.add(CoercionTuple.create(Flow.class, Boolean.class, new Coercion<Flow, Boolean>()
{
@Override
public Boolean coerce(Flow input)
{
return !input.isEmpty();
}
}));
CoercionTuple<Flow, Boolean> flowToBooleanCoercion = CoercionTuple.create(Flow.class, Boolean.class, (i) -> !i.isEmpty());
configuration.add(flowToBooleanCoercion.getKey(), flowToBooleanCoercion);


}

private static <S, T> void add(Configuration<CoercionTuple> configuration, Class<S> sourceType,
private static <S, T> void add(MappedConfiguration<CoercionTuple.Key, CoercionTuple> configuration, Class<S> sourceType,
Class<T> targetType, Coercion<S, T> coercion)
{
configuration.add(CoercionTuple.create(sourceType, targetType, coercion));
CoercionTuple<S, T> tuple = CoercionTuple.create(sourceType, targetType, coercion);
configuration.add(tuple.getKey(), tuple);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ public String toString()
}
};

public TypeCoercerImpl(Collection<CoercionTuple> tuples)
public TypeCoercerImpl(Map<CoercionTuple.Key, CoercionTuple> tuples)
{
for (CoercionTuple tuple : tuples)
for (CoercionTuple tuple : tuples.values())
{
Class key = tuple.getSourceType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public final class CoercionTuple<S, T>
private final Class<T> targetType;

private final Coercion<S, T> coercion;

private final Key key;

/**
* Wraps an arbitrary coercion with an implementation of toString() that identifies the source and target types.
Expand Down Expand Up @@ -119,6 +121,7 @@ public CoercionTuple(Class<S> sourceType, Class<T> targetType, Coercion<S, T> co
this.sourceType = PlasticUtils.toWrapperType(sourceType);
this.targetType = PlasticUtils.toWrapperType(targetType);
this.coercion = wrap ? new CoercionWrapper<S, T>(coercion) : coercion;
this.key = new Key();
}

@Override
Expand All @@ -141,5 +144,59 @@ public Class<T> getTargetType()
{
return targetType;
}

public Key getKey()
{
return key;
}

/**
* Class that represents the key to be used to the mapped configuration of the
* {@link TypeCoercer} service.
*/
public final class Key
{

@Override
public String toString() {
return String.format("%s -> %s", sourceType.getName(), targetType.getName());
}

@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((sourceType == null) ? 0 : sourceType.hashCode());
result = prime * result + ((targetType == null) ? 0 : targetType.hashCode());
return result;
}

@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CoercionTuple other = (CoercionTuple) obj;
if (sourceType == null)
{
if (other.sourceType != null)
return false;
} else if (!sourceType.equals(other.sourceType))
return false;
if (targetType == null)
{
if (other.targetType != null)
return false;
} else if (!targetType.equals(other.targetType))
return false;
return true;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

package org.apache.tapestry5.commons.services;

import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
import org.apache.tapestry5.ioc.annotations.UsesMappedConfiguration;

/**
* Makes use of {@link org.apache.tapestry5.commons.services.Coercion}s to convert between an input value (of some specific
* type) and a desired output type. Smart about coercing, even if it requires multiple coercion steps (i.e., via an
* intermediate type, such as String).
*/
@UsesConfiguration(CoercionTuple.class)
@UsesMappedConfiguration(key = CoercionTuple.Key.class, value = CoercionTuple.class)
public interface TypeCoercer
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@

package org.apache.tapestry5.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.tapestry5.commons.internal.services.TypeCoercerImpl;
import org.apache.tapestry5.commons.services.Coercion;
import org.apache.tapestry5.commons.services.CoercionTuple;
import org.apache.tapestry5.commons.services.TypeCoercer;
import org.apache.tapestry5.commons.util.CollectionFactory;
import org.apache.tapestry5.commons.util.UnknownValueException;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.testng.annotations.Test;
Expand Down Expand Up @@ -74,7 +75,10 @@ public Stooge coerce(String input) {

});

TypeCoercer typeCoercer = new TypeCoercerImpl(CollectionFactory.<CoercionTuple, CoercionTuple>newList(stoogeToString, stringToStooge));
Map<CoercionTuple.Key, CoercionTuple> map = new HashMap<>();
map.put(stoogeToString.getKey(), stoogeToString);
map.put(stringToStooge.getKey(), stringToStooge);
TypeCoercer typeCoercer = new TypeCoercerImpl(map);


EnumValueEncoder<Stooge> encoder = new EnumValueEncoder<Stooge>(typeCoercer, Stooge.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
* </ul>
*/
@Contribute(TypeCoercer.class)
public static void provideBasicTypeCoercions(Configuration<CoercionTuple> configuration)
public static void provideBasicTypeCoercions(MappedConfiguration<CoercionTuple.Key, CoercionTuple> configuration)
{
BasicTypeCoercions.provideBasicTypeCoercions(configuration);
}
Expand Down

0 comments on commit 5d1513b

Please sign in to comment.