You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/03/01 21:28:49 UTC
svn commit: r917694 - in /tapestry/tapestry5/trunk/tapestry-ioc/src:
main/java/org/apache/tapestry5/ioc/internal/services/
main/java/org/apache/tapestry5/ioc/internal/util/
main/resources/org/apache/tapestry5/ioc/internal/services/
test/java/org/apache...
Author: hlship
Date: Mon Mar 1 20:28:48 2010
New Revision: 917694
URL: http://svn.apache.org/viewvc?rev=917694&view=rev
Log:
TAP5-1035: Use UnknownValueException when no coercion can be found by TypeCoercer
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java (with props)
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java?rev=917694&r1=917693&r2=917694&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImpl.java Mon Mar 1 20:28:48 2010
@@ -14,18 +14,24 @@
package org.apache.tapestry5.ioc.internal.services;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newList;
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.InheritanceSearch;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.PossibleValues;
+import org.apache.tapestry5.ioc.internal.util.UnknownValueException;
import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.Coercion;
import org.apache.tapestry5.ioc.services.CoercionTuple;
import org.apache.tapestry5.ioc.services.TypeCoercer;
-import java.util.*;
-
public class TypeCoercerImpl implements TypeCoercer
{
// Constructed from the service's configuration.
@@ -182,22 +188,20 @@
* coercions, that accomplish
* the desired coercion.
* <p/>
- * There's <strong>TREMENDOUS</strong> room to improve this algorithm. For example, inheritance
- * lists could be cached. Further, there's probably more ways to early prune the search.
- * However, even with dozens or perhaps hundreds of tuples, I suspect the search will still
- * grind to a conclusion quickly.
+ * There's <strong>TREMENDOUS</strong> room to improve this algorithm. For example, inheritance lists could be
+ * cached. Further, there's probably more ways to early prune the search. However, even with dozens or perhaps
+ * hundreds of tuples, I suspect the search will still grind to a conclusion quickly.
* <p/>
- * The order of operations should help ensure that the most efficient tuple chain is located. If
- * you think about how tuples are added to the queue, there are two factors: size (the number of
- * steps in the coercion) and "class distance" (that is, number of steps up the inheritance
- * hiearchy). All the appropriate 1 step coercions will be considered first, in class distance
- * order. Along the way, we'll queue up all the 2 step coercions, again in class distance order.
- * By the time we reach some of those, we'll have begun queing up the 3 step coercions, and so
- * forth, until we run out of input tuples we can use to fabricate multi-step compound
- * coercions, or reach a final response.
+ * The order of operations should help ensure that the most efficient tuple chain is located. If you think about how
+ * tuples are added to the queue, there are two factors: size (the number of steps in the coercion) and
+ * "class distance" (that is, number of steps up the inheritance hiearchy). All the appropriate 1 step coercions
+ * will be considered first, in class distance order. Along the way, we'll queue up all the 2 step coercions, again
+ * in class distance order. By the time we reach some of those, we'll have begun queing up the 3 step coercions, and
+ * so forth, until we run out of input tuples we can use to fabricate multi-step compound coercions, or reach a
+ * final response.
* <p/>
- * This does create a good number of short lived temporary objects (the compound tuples), but
- * that's what the GC is really good at.
+ * This does create a good number of short lived temporary objects (the compound tuples), but that's what the GC is
+ * really good at.
*
* @param sourceType
* @param targetType
@@ -246,8 +250,8 @@
// Not found anywhere. Identify the source and target type and a (sorted) list of
// all the known coercions.
- throw new IllegalArgumentException(ServiceMessages.noCoercionFound(sourceType, targetType,
- buildCoercionCatalog()));
+ throw new UnknownValueException(String.format("Could not find a coercion from type %s to type %s.", sourceType
+ .getName(), targetType.getName()), buildCoercionCatalog());
}
/**
@@ -287,24 +291,23 @@
* Builds a string listing all the coercions configured for the type coercer, sorted
* alphabetically.
*/
- private String buildCoercionCatalog()
+ @SuppressWarnings("unchecked")
+ private PossibleValues buildCoercionCatalog()
{
- List<String> descriptions = newList();
+ List<CoercionTuple> masterList = CollectionFactory.newList();
for (List<CoercionTuple> list : sourceTypeToTuple.values())
{
- for (CoercionTuple tuple : list)
- descriptions.add(tuple.toString());
+ masterList.addAll(list);
}
- return InternalUtils.joinSorted(descriptions);
+ return new PossibleValues("coercions", masterList);
}
/**
* Seeds the pool with the initial set of coercions for the given type.
*/
- private void seedQueue(Class sourceType, Set<CoercionTuple> consideredTuples,
- LinkedList<CoercionTuple> queue)
+ private void seedQueue(Class sourceType, Set<CoercionTuple> consideredTuples, LinkedList<CoercionTuple> queue)
{
// Work from the source type up looking for tuples
@@ -378,11 +381,9 @@
// from I1 (i.e., I2 is a superclass/superinterface of I1) and X is a new
// intermediate type, hopefully closer to our eventual target type.
- Coercion compoundCoercer = new CompoundCoercion(intermediateTuple.getCoercion(),
- tuple.getCoercion());
+ Coercion compoundCoercer = new CompoundCoercion(intermediateTuple.getCoercion(), tuple.getCoercion());
- CoercionTuple compoundTuple = new CoercionTuple(sourceType, newIntermediateType,
- compoundCoercer, false);
+ CoercionTuple compoundTuple = new CoercionTuple(sourceType, newIntermediateType, compoundCoercer, false);
// So, every tuple that is added to the queue can take as input the sourceType.
// The target type may be another intermdiate type, or may be something
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java?rev=917694&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java Mon Mar 1 20:28:48 2010
@@ -0,0 +1,82 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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 org.apache.tapestry5.ioc.internal.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Used (as part of a {@link UnknownValueException} to identify what available values
+ * are present.
+ *
+ * @since 5.2.0
+ */
+public class PossibleValues
+{
+ private final String valueType;
+
+ private final List<String> values;
+
+ /**
+ * @param valueType
+ * a word or phrase that describes what the values are such as "component types" or "service ids"
+ *@param values
+ * a set of objects defining the values; the values will be converted to strings and sorted into
+ * ascending order
+ */
+ public PossibleValues(String valueType, Collection<?> values)
+ {
+ this.valueType = valueType;
+ this.values = sortValues(values);
+ }
+
+ public PossibleValues(String valueType, Map<?, ?> map)
+ {
+ this(valueType, map.keySet());
+ }
+
+ private static List<String> sortValues(Collection<?> values)
+ {
+ List<String> result = CollectionFactory.newList();
+
+ for (Object v : values)
+ {
+ result.add(String.valueOf(v));
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
+ /** The type of value, i.e., "component types" or "service ids". */
+ public String getValueType()
+ {
+ return valueType;
+ }
+
+ /** The values, as strings, in sorted order. */
+ public List<String> getValues()
+ {
+ return values;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("PossibleValues[%s: %s]", valueType, InternalUtils.join(values));
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/PossibleValues.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java?rev=917694&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java Mon Mar 1 20:28:48 2010
@@ -0,0 +1,47 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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 org.apache.tapestry5.ioc.internal.util;
+
+/**
+ * Special exception used when a value (typically from a map) is referenced that does not exist. Uses a
+ * {@link PossibleValues} object
+ * to track what the known values are.
+ *
+ * @since 5.2.0
+ */
+public class UnknownValueException extends TapestryException
+{
+ private static final long serialVersionUID = -8131503136299055706L;
+
+ private final PossibleValues possibleValues;
+
+ public UnknownValueException(String message, PossibleValues values)
+ {
+ this(message, null, null, values);
+ }
+
+ public UnknownValueException(String message, Object location, Throwable cause, PossibleValues values)
+ {
+ super(message, location, cause);
+
+ this.possibleValues = values;
+ }
+
+ public PossibleValues getPossibleValues()
+ {
+ return possibleValues;
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/UnknownValueException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties?rev=917694&r1=917693&r2=917694&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties Mon Mar 1 20:28:48 2010
@@ -31,7 +31,6 @@
unmatched-service-method=Method %s has no match in filter interface %s.
unknown-object-proxyProvider=Object proxyProvider '%s' does not exist (in object reference '%s').
shutdown-listener-error=Error notifying %s of registry shutdown: %s
-no-coercion-found=Could not find a coercion from type %s to type %s. Available coercions: %s.
recursive-symbol=Symbol '%s' is defined in terms of itself (%s).
symbol-undefined=Symbol '%s' is not defined.
symbol-undefined-in-path=Symbol '%s' is not defined (in %s).
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java?rev=917694&r1=917693&r2=917694&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/TypeCoercerImplTest.java Mon Mar 1 20:28:48 2010
@@ -113,7 +113,7 @@
coercer.coerce("", Map.class);
unreachable();
}
- catch (IllegalArgumentException ex)
+ catch (RuntimeException ex)
{
assertTrue(ex.getMessage().contains(
"Could not find a coercion from type java.lang.String to type java.util.Map"));
@@ -279,14 +279,12 @@
{
return new Object[][]
{
- { StringBuffer.class, Integer.class,
- "Object --> String, String --> Long, Long --> Integer" },
- { void.class, Map.class, "null --> null" },
- { void.class, Boolean.class, "null --> Boolean" },
- { String[].class, List.class, "Object[] --> java.util.List" },
- { Float.class, Double.class, "Float --> Double" },
- { Double.class, BigDecimal.class,
- "Object --> String, String --> java.math.BigDecimal" }, };
+ { StringBuffer.class, Integer.class, "Object --> String, String --> Long, Long --> Integer" },
+ { void.class, Map.class, "null --> null" },
+ { void.class, Boolean.class, "null --> Boolean" },
+ { String[].class, List.class, "Object[] --> java.util.List" },
+ { Float.class, Double.class, "Float --> Double" },
+ { Double.class, BigDecimal.class, "Object --> String, String --> java.math.BigDecimal" }, };
}
@Test