001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.ioc.services;
016:
017: import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
018:
019: /**
020: * An immutable object that represents a mapping from one type to another. This is also the
021: * contribution type when buildign the TypeCoercer service. Wraps a {@link Coercion} object that
022: * performs the work with additional properties that describe the input and output types of the
023: * coercion, needed when searching for an appropriate coercion (or combination of coercions).
024: *
025: * @param <S>
026: * source (input) type
027: * @param <T>
028: * target (output) type
029: */
030: public final class CoercionTuple<S, T> {
031: private final Class<S> _sourceType;
032:
033: private final Class<T> _targetType;
034:
035: private final Coercion<S, T> _coercion;
036:
037: /**
038: * Wraps an arbitrary coercion with an implementation of toString() that identifies the source
039: * and target types.
040: */
041: private class CoercionWrapper<WS, WT> implements Coercion<WS, WT> {
042: private final Coercion<WS, WT> _coercion;
043:
044: public CoercionWrapper(Coercion<WS, WT> coercion) {
045: _coercion = coercion;
046: }
047:
048: public WT coerce(WS input) {
049: return _coercion.coerce(input);
050: }
051:
052: public String toString() {
053: return String.format("%s --> %s", convert(_sourceType),
054: convert(_targetType));
055: }
056: }
057:
058: private String convert(Class type) {
059: if (void.class.equals(type))
060: return "null";
061:
062: String name = ClassFabUtils.toJavaClassName(type);
063:
064: int dotx = name.lastIndexOf('.');
065:
066: // Strip off a package name of "java.lang"
067:
068: if (dotx > 0 && name.substring(0, dotx).equals("java.lang"))
069: return name.substring(dotx + 1);
070:
071: return name;
072: }
073:
074: /**
075: * Standard constructor, which defaults wrap to true.
076: */
077: public CoercionTuple(Class<S> sourceType, Class<T> targetType,
078: Coercion<S, T> coercion) {
079: this (sourceType, targetType, coercion, true);
080: }
081:
082: /**
083: * Internal-use constructor.
084: *
085: * @param sourceType
086: * the source (or input) type of the coercion
087: * @param targetType
088: * the target (or output) type of the coercion
089: * @param coercion
090: * the object that performs the coercion
091: * @param wrap
092: * if true, the coercion is wrapped to provide a useful toString()
093: */
094: public CoercionTuple(Class<S> sourceType, Class<T> targetType,
095: Coercion<S, T> coercion, boolean wrap) {
096: notNull(sourceType, "sourceType");
097: notNull(targetType, "targetType");
098: notNull(coercion, "coercion");
099:
100: _sourceType = sourceType;
101: _targetType = targetType;
102: _coercion = wrap ? new CoercionWrapper<S, T>(coercion)
103: : coercion;
104: }
105:
106: @Override
107: public String toString() {
108: return _coercion.toString();
109: }
110:
111: public Coercion<S, T> getCoercion() {
112: return _coercion;
113: }
114:
115: public Class<S> getSourceType() {
116: return _sourceType;
117: }
118:
119: public Class<T> getTargetType() {
120: return _targetType;
121: }
122:
123: }
|