tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject svn commit: r517073 [1/2] - in /tapestry/tapestry5: tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ tapestry-core/trunk/src/main/java/org/apache/tapestry/services/...
Date Mon, 12 Mar 2007 02:01:06 GMT
Author: hlship
Date: Sun Mar 11 19:01:04 2007
New Revision: 517073

URL: http://svn.apache.org/viewvc?view=rev&rev=517073
Log:
TAPESTRY-1342: When an exception is reported concerning a particular method, the string identifying the method should include the file name and line number (if available)

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/services/MethodLocation.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/OnEventWorkerTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProvider.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/services/ClassFactory.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/test/TestBase.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/ContributionDefImplTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/OneShotServiceCreatorTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/ValidatingConfigurationWrapperTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/ValidatingOrderedConfigurationWrapperTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImplTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/TapestryInternalUtils.java Sun Mar 11 19:01:04 2007
@@ -35,6 +35,7 @@
 import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.MethodLocation;
 import org.apache.tapestry.ioc.services.PropertyAdapter;
 
 /** Shared utility methods used by various implementation classes. */
@@ -390,10 +391,11 @@
 
             Method readMethod = pa.getReadMethod();
 
-            // Kind of assuming that line number information will be availble here.
+            MethodLocation location = classFactory.getMethodLocation(readMethod);
 
-            properties.add(new PropertyOrder(name, computeDepth(readMethod), classFactory
-                    .getMethodLineNumber(readMethod)));
+            int lineNumber = location != null ? location.getLineNumber() : 0;
+
+            properties.add(new PropertyOrder(name, computeDepth(readMethod), lineNumber));
         }
 
         Collections.sort(properties);

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorker.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -66,9 +66,10 @@
         _reverse = reverse;
         _lifecycleMethodName = lifecycleMethodSignature.getMethodName();
 
-        // If we ever add more parameters to the methods, then we can add more to the invocation builder.
+        // If we ever add more parameters to the methods, then we can add more to the invocation
+        // builder.
         // *Never* expose the Event parameter ($2), it is for internal use only.
-        
+
         _invocationBuilder.addParameter(MarkupWriter.class.getName(), "$1");
     }
 
@@ -88,8 +89,7 @@
                 // we don't
                 // include this filter, then we get endless loops.
 
-                if (signature.equals(_lifecycleMethodSignature))
-                    return false;
+                if (signature.equals(_lifecycleMethodSignature)) return false;
 
                 // A degenerate case would be a method, say beginRender(), with an conflicting
                 // annotation, say @AfterRender. In that case, this code is broken, as the method
@@ -105,8 +105,7 @@
         // Except in the root class, don't bother to add a new method unless there's something to
         // call (beside super).
 
-        if (methods.isEmpty())
-            return;
+        if (methods.isEmpty()) return;
 
         BodyBuilder builder = new BodyBuilder();
         builder.begin();
@@ -127,8 +126,7 @@
 
         // In reverse order in a a subclass, invoke the super method last.
 
-        if (_reverse && !model.isRootClass())
-            builder.addln("super.%s($$);", _lifecycleMethodName);
+        if (_reverse && !model.isRootClass()) builder.addln("super.%s($$);", _lifecycleMethodName);
 
         builder.end();
 
@@ -149,8 +147,7 @@
             // If we're not going to invoke storeResult(), then there's no reason to invoke
             // setSource().
 
-            builder.addln("$2.setSource(this, \"%s.%s\");", transformation.getClassName(), sig
-                    .getMediumDescription());
+            builder.addln("$2.setSource(this, \"%s\");", transformation.getMethodIdentifier(sig));
             builder.add("if ($2.storeResult(($w) ");
         }
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InternalClassTransformationImpl.java Sun Mar 11 19:01:04 2007
@@ -48,7 +48,6 @@
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.util.MultiKey;
 import org.apache.tapestry.ioc.internal.util.CollectionFactory;
-import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.internal.util.IdAllocator;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.model.ComponentModel;
@@ -187,8 +186,7 @@
 
         for (int i = 1; i <= count; i++)
         {
-            if (i > 1)
-                _constructor.append(", ");
+            if (i > 1) _constructor.append(", ");
 
             // $0 is implicitly self, so the 0-index ConstructorArg will be Javassisst
             // pseudeo-variable $1, and so forth.
@@ -246,15 +244,13 @@
         {
             String name = field.getName();
 
-            if (_addedFieldNames.contains(name))
-                continue;
+            if (_addedFieldNames.contains(name)) continue;
 
             int modifiers = field.getModifiers();
 
             // Fields must be either static or private.
 
-            if (Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers))
-                continue;
+            if (Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers)) continue;
 
             names.add(name);
         }
@@ -317,8 +313,7 @@
     {
         for (Object annotation : annotations)
         {
-            if (annotationClass.isInstance(annotation))
-                return annotationClass.cast(annotation);
+            if (annotationClass.isInstance(annotation)) return annotationClass.cast(annotation);
         }
 
         return null;
@@ -425,8 +420,7 @@
         {
             CtClass ctInterface = _classPool.get(interfaceName);
 
-            if (classImplementsInterface(ctInterface))
-                return;
+            if (classImplementsInterface(ctInterface)) return;
 
             implementDefaultMethodsForInterface(ctInterface);
 
@@ -453,8 +447,7 @@
     {
         // java.lang.Object is the parent interface of interfaces
 
-        if (ctInterface.getName().equals(Object.class.getName()))
-            return;
+        if (ctInterface.getName().equals(Object.class.getName())) return;
 
         for (CtMethod method : ctInterface.getDeclaredMethods())
         {
@@ -473,8 +466,7 @@
         // up as methods of the interface. We skip those and only consider the methods
         // that are abstract.
 
-        if (!Modifier.isAbstract(method.getModifiers()))
-            return;
+        if (!Modifier.isAbstract(method.getModifiers())) return;
 
         try
         {
@@ -519,8 +511,7 @@
         {
             for (CtClass anInterface : current.getInterfaces())
             {
-                if (anInterface == ctInterface)
-                    return true;
+                if (anInterface == ctInterface) return true;
             }
         }
 
@@ -667,8 +658,7 @@
         String[] parameterTypes = methodSignature.getParameterTypes();
         for (int i = 0; i < parameterTypes.length; i++)
         {
-            if (i > 0)
-                _description.append(", ");
+            if (i > 0) _description.append(", ");
 
             _formatter.format("%s $%d", parameterTypes[i], i + 1);
         }
@@ -693,13 +683,11 @@
     {
         CtMethod method = findDeclaredMethod(methodSignature);
 
-        if (method != null)
-            return method;
+        if (method != null) return method;
 
         CtMethod result = addOverrideOfSuperclassMethod(methodSignature);
 
-        if (result != null)
-            return result;
+        if (result != null) return result;
 
         throw new IllegalArgumentException(ServicesMessages.noDeclaredMethod(
                 _ctClass,
@@ -710,8 +698,7 @@
     {
         for (CtMethod method : _ctClass.getDeclaredMethods())
         {
-            if (match(method, methodSignature))
-                return method;
+            if (match(method, methodSignature)) return method;
         }
 
         return null;
@@ -754,8 +741,7 @@
 
     private boolean match(CtMethod method, MethodSignature sig)
     {
-        if (!sig.getMethodName().equals(method.getName()))
-            return false;
+        if (!sig.getMethodName().equals(method.getName())) return false;
 
         CtClass[] paramTypes;
 
@@ -772,15 +758,13 @@
 
         int count = sigTypes.length;
 
-        if (paramTypes.length != count)
-            return false;
+        if (paramTypes.length != count) return false;
 
         for (int i = 0; i < count; i++)
         {
             String paramType = paramTypes[i].getName();
 
-            if (!paramType.equals(sigTypes[i]))
-                return false;
+            if (!paramType.equals(sigTypes[i])) return false;
         }
 
         // Ignore exceptions thrown and modifiers.
@@ -812,16 +796,13 @@
         {
             for (CtField field : _ctClass.getDeclaredFields())
             {
-                if (!isInstanceField(field))
-                    continue;
+                if (!isInstanceField(field)) continue;
 
                 String fieldName = field.getName();
 
-                if (_claimedFields.containsKey(fieldName))
-                    continue;
+                if (_claimedFields.containsKey(fieldName)) continue;
 
-                if (filter.accept(fieldName, field.getType().getName()))
-                    result.add(fieldName);
+                if (filter.accept(fieldName, field.getType().getName())) result.add(fieldName);
 
             }
         }
@@ -881,8 +862,7 @@
         {
             MethodSignature sig = getMethodSignature(method);
 
-            if (filter.accept(sig))
-                result.add(sig);
+            if (filter.accept(sig)) result.add(sig);
         }
 
         Collections.sort(result);
@@ -936,18 +916,15 @@
         skipped.addAll(_claimedFields.keySet());
         skipped.addAll(_addedFieldNames);
 
-        if (_removedFieldNames != null)
-            skipped.addAll(_removedFieldNames);
+        if (_removedFieldNames != null) skipped.addAll(_removedFieldNames);
 
         for (CtField field : _ctClass.getDeclaredFields())
         {
-            if (!isInstanceField(field))
-                continue;
+            if (!isInstanceField(field)) continue;
 
             String name = field.getName();
 
-            if (skipped.contains(name))
-                continue;
+            if (skipped.contains(name)) continue;
 
             // May need to add a filter to edit out explicitly added fields.
 
@@ -1045,8 +1022,7 @@
 
         String fieldName = searchForPreviousInjection(key);
 
-        if (fieldName != null)
-            return fieldName;
+        if (fieldName != null) return fieldName;
 
         // TODO: Probably doesn't handle arrays and primitives.
 
@@ -1091,8 +1067,7 @@
     {
         String result = _injectionCache.get(key);
 
-        if (result != null)
-            return result;
+        if (result != null) return result;
 
         if (_parentTransformation != null)
             return _parentTransformation.searchForPreviousInjection(key);
@@ -1205,8 +1180,7 @@
 
         for (int i = 0; i < count; i++)
         {
-            if (i > 0)
-                _description.append(", ");
+            if (i > 0) _description.append(", ");
 
             _formatter.format("%s $%d", types[i].getName(), i + 1);
         }
@@ -1270,8 +1244,7 @@
     {
         failIfFrozen();
 
-        if (_classAnnotations == null)
-            assembleClassAnnotations();
+        if (_classAnnotations == null) assembleClassAnnotations();
 
         return _classAnnotations;
     }
@@ -1361,8 +1334,7 @@
 
         // TODO: We could check that there's an existing field read and field write transform ...
 
-        if (_removedFieldNames == null)
-            _removedFieldNames = newSet();
+        if (_removedFieldNames == null) _removedFieldNames = newSet();
 
         _removedFieldNames.add(fieldName);
 
@@ -1372,8 +1344,7 @@
     {
         String body = String.format("$_ = %s();", methodName);
 
-        if (_fieldReadTransforms == null)
-            _fieldReadTransforms = newMap();
+        if (_fieldReadTransforms == null) _fieldReadTransforms = newMap();
 
         // TODO: Collisions?
 
@@ -1386,8 +1357,7 @@
     {
         String body = String.format("%s($1);", methodName);
 
-        if (_fieldWriteTransforms == null)
-            _fieldWriteTransforms = newMap();
+        if (_fieldWriteTransforms == null) _fieldWriteTransforms = newMap();
 
         // TODO: Collisions?
 
@@ -1401,8 +1371,7 @@
         // If no field transformations have been requested, then we can save ourselves some
         // trouble!
 
-        if (_fieldReadTransforms != null || _fieldWriteTransforms != null)
-            replaceFieldAccess();
+        if (_fieldReadTransforms != null || _fieldWriteTransforms != null) replaceFieldAccess();
 
         if (_removedFieldNames != null)
         {
@@ -1426,11 +1395,9 @@
         // Provide empty maps here, to make the code in the inner class a tad
         // easier.
 
-        if (_fieldReadTransforms == null)
-            _fieldReadTransforms = newMap();
+        if (_fieldReadTransforms == null) _fieldReadTransforms = newMap();
 
-        if (_fieldWriteTransforms == null)
-            _fieldWriteTransforms = newMap();
+        if (_fieldWriteTransforms == null) _fieldWriteTransforms = newMap();
 
         ExprEditor editor = new ExprEditor()
         {
@@ -1440,16 +1407,14 @@
                 // Ignore any methods to were added as part of the transformation.
                 // If we reference the field there, we really mean the field.
 
-                if (_addedMethods.contains(access.where()))
-                    return;
+                if (_addedMethods.contains(access.where())) return;
 
                 Map<String, String> transformMap = access.isReader() ? _fieldReadTransforms
                         : _fieldWriteTransforms;
 
                 String body = transformMap.get(access.getFieldName());
 
-                if (body != null)
-                    access.replace(body);
+                if (body != null) access.replace(body);
             }
         };
 
@@ -1493,12 +1458,26 @@
 
     public void extendConstructor(String statement)
     {
-        Defense.notNull(statement, "statement");
+        notNull(statement, "statement");
 
         failIfFrozen();
 
         _constructor.append(statement);
         _constructor.append("\n");
+    }
+
+    public String getMethodIdentifier(MethodSignature signature)
+    {
+        notNull(signature, "signature");
+
+        CtMethod method = findMethod(signature);
+
+        int lineNumber = method.getMethodInfo2().getLineNumber(0);
+        CtClass enclosingClass = method.getDeclaringClass();
+        String sourceFile = enclosingClass.getClassFile2().getSourceFile();
+
+        return format("%s.%s (at %s:%d)", enclosingClass.getName(), signature
+                .getMediumDescription(), sourceFile, lineNumber);
     }
 
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/OnEventWorker.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -53,8 +53,7 @@
 
         // No methods, no work.
 
-        if (methods.isEmpty())
-            return;
+        if (methods.isEmpty()) return;
 
         BodyBuilder builder = new BodyBuilder();
         builder.begin();
@@ -116,15 +115,13 @@
 
         // Several subsequent calls need to know the method name.
 
-        builder.addln("$1.setSource(this, \"%s.%s\");", transformation.getClassName(), method
-                .getMediumDescription());
+        builder.addln("$1.setSource(this, \"%s\");", transformation.getMethodIdentifier(method));
 
         boolean isNonVoid = !method.getReturnType().equals("void");
 
         // Store the result, converting primitives to wrappers automatically.
 
-        if (isNonVoid)
-            builder.add("if ($1.storeResult(($w) ");
+        if (isNonVoid) builder.add("if ($1.storeResult(($w) ");
 
         builder.add("%s(", method.getMethodName());
 
@@ -141,8 +138,7 @@
 
     private String[] extractComponentIds(MethodSignature method, OnEvent annotation)
     {
-        if (annotation != null)
-            return annotation.component();
+        if (annotation != null) return annotation.component();
 
         // Method name started with "on". Extract the component id, if present.
 
@@ -150,8 +146,7 @@
 
         int fromx = name.indexOf("From");
 
-        if (fromx < 0)
-            return _empty;
+        if (fromx < 0) return _empty;
 
         String componentId = name.substring(fromx + 4);
 
@@ -161,8 +156,7 @@
 
     private String[] extractEventTypes(MethodSignature method, OnEvent annotation)
     {
-        if (annotation != null)
-            return annotation.value();
+        if (annotation != null) return annotation.value();
 
         // Method name started with "on". Extract the event type.
 
@@ -174,8 +168,7 @@
 
         // This is intended for onAnyFromComponentId, but just onAny works too (and is dangerous).
 
-        if (eventName.equals("AnyEvent"))
-            return _empty;
+        if (eventName.equals("AnyEvent")) return _empty;
 
         return new String[]
         { eventName };
@@ -187,8 +180,7 @@
 
         for (int i = 0; i < method.getParameterTypes().length; i++)
         {
-            if (i > 0)
-                builder.add(", ");
+            if (i > 0) builder.add(", ");
 
             String type = method.getParameterTypes()[i];
 
@@ -205,8 +197,7 @@
 
             // Add a cast to the wrapper type up front
 
-            if (isPrimitive)
-                builder.add("(");
+            if (isPrimitive) builder.add("(");
 
             // A cast is always needed (i.e. from java.lang.Object to, say, java.lang.String, etc.).
             // The wrapper type will be the actual type unless its a primitive, in which case it
@@ -222,8 +213,7 @@
             builder.add("$1.coerceContext(%d, \"%s\")", contextIndex++, wrapperType);
 
             // and invoke a method on the cast value to get back to primitive
-            if (isPrimitive)
-                builder.add(").%s()", TransformUtils.getUnwrapperMethodName(type));
+            if (isPrimitive) builder.add(").%s()", TransformUtils.getUnwrapperMethodName(type));
         }
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/ClassTransformation.java Sun Mar 11 19:01:04 2007
@@ -327,4 +327,15 @@
 
     /** Returns the modifiers for the named field. */
     int getFieldModifiers(String fieldName);
+
+    /**
+     * Converts a signature to a string used to identify the method; this consists of the
+     * {@link MethodSignature#getMediumDescription()} appended with source file information and line
+     * number information (when available).
+     * 
+     * @param signature
+     * @return a string that identifies the class, method name, types of parameters, source file and
+     *         source line number
+     */
+    String getMethodIdentifier(MethodSignature signature);
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Sun Mar 11 19:01:04 2007
@@ -148,8 +148,7 @@
 
             long newModified = f.lastModified();
 
-            if (newModified != startModified)
-                return;
+            if (newModified != startModified) return;
 
             // Sleep 1/20 second and try again
 
@@ -512,8 +511,7 @@
 
                 for (MethodSignature sig : signatures)
                 {
-                    if (filter.accept(sig))
-                        result.add(sig);
+                    if (filter.accept(sig)) result.add(sig);
                 }
 
                 // We don't have to sort them for testing purposes. Usually there's just going to be
@@ -833,7 +831,9 @@
         expect(model.getMeta(key)).andReturn(value).atLeastOnce();
     }
 
-    protected void train_newBinding(BindingSource bindingSource, String description, ComponentResources componentResources, String defaultBindingPrefix, String expression, Binding binding)
+    protected void train_newBinding(BindingSource bindingSource, String description,
+            ComponentResources componentResources, String defaultBindingPrefix, String expression,
+            Binding binding)
     {
         expect(
                 bindingSource.newBinding(
@@ -856,7 +856,8 @@
     }
 
     @SuppressWarnings("unchecked")
-    protected final void train_renderInformalParameters(ComponentResources resources, final MarkupWriter writer, final String... informals)
+    protected final void train_renderInformalParameters(ComponentResources resources,
+            final MarkupWriter writer, final String... informals)
     {
         resources.renderInformalParameters(writer);
         IAnswer answer = new IAnswer()
@@ -864,11 +865,11 @@
             public Object answer() throws Throwable
             {
                 writer.attributes(informals);
-    
+
                 return null;
             }
         };
-    
+
         getMocksControl().andAnswer(answer);
     }
 
@@ -885,5 +886,11 @@
     protected final void train_forLocale(Resource base, Locale locale, Resource resource)
     {
         expect(base.forLocale(locale)).andReturn(resource);
+    }
+
+    protected final void train_getMethodIdentifier(ClassTransformation transformation,
+            MethodSignature signature, String id)
+    {
+        expect(transformation.getMethodIdentifier(signature)).andReturn(id);
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/Start.html Sun Mar 11 19:01:04 2007
@@ -1,131 +1,126 @@
 <html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
 
-    <h1> Tapestry 5 Integration Application 1</h1>
+  <h1> Tapestry 5 Integration Application 1</h1>
 
-    <table>
-        <tr>
-            <td>
-                <ul>
-                    <li>
-                        <a t:type="PageLink" page="MerryChristmas">Count Page</a>
-                    </li>
-                    <li>
-                        <a t:type="PageLink" page="InjectDemo">Inject Demo</a>
-                    </li>
-                    <li>
-                        <a t:type="PageLink" page="Countdown">Countdown Page</a>
-                    </li>
-                    <li>
-                        <a t:type="PageLink" page="ParameterConflict">Template Overriden by Class
-                            Page</a>
-                    </li>
-                    <li>
-                        <a t:type="PageLink" page="EnvironmentalDemo">Environmental Annotation
-                            Useage</a>
-                    </li>
-                    <li>
-                        <a t:type="PageLink" page="expansion">Expansion Page</a>
-                    </li>
-                    <li>
-                        <a href="BadTemplate">BadTemplate Page</a> -- More exception reporting </li>
-                    <li>
-                        <a t:type="PageLink" page="ActionPage">Action Page</a> -- tests fixture for
-                        ActionLink component </li>
-                    <li>
-                        <a t:type="PageLink" page="InstanceMixin">InstanceMixin</a> -- Mixin added
-                        to particular component instance </li>
-                    <li>
-                        <a t:type="PageLink" page="RenderPhaseOrder">RenderPhaseOrder</a> -- Order
-                        of operations when invoking render phase methods </li>
-                    <li><a t:type="PageLink" page="SimpleForm">SimpleForm</a> -- first pass at
-                        writing Form and TextField components </li>
-                    <li>
-                        <a t:type="PageLink" page="NumberSelect">NumberSelect</a> --
-                        passivate/activate page context demo </li>
-                    <li>
-                        <a t:type="PageLink" page="Localization">Localization</a> -- accessing
-                        localized messages from the component catalog </li>
-                    <li>
-                        <a t:type="PageLink" page="AssetDemo">AssetDemo</a> -- declaring an using
-                        Assets </li>
-                    <li>
-                        <a t:type="PageLink" page="ExpansionSubclass">ExpansionSubclass</a> --
-                        components can inherit templates from base classes </li>
-                    <li>
-                        <a href="InjectComponentMismatch">InjectComponentMismatch</a> -- check error
-                        reporting when @InjectComponent doesn't match the actual field type </li>
+  <table>
+    <tr>
+      <td>
+        <ul>
+          <li>
+            <a t:type="PageLink" page="MerryChristmas">Count Page</a>
+          </li>
+          <li>
+            <a t:type="PageLink" page="InjectDemo">Inject Demo</a>
+          </li>
+          <li>
+            <a t:type="PageLink" page="Countdown">Countdown Page</a>
+          </li>
+          <li>
+            <a t:type="PageLink" page="ParameterConflict">Template Overriden by Class Page</a>
+          </li>
+          <li>
+            <a t:type="PageLink" page="EnvironmentalDemo">Environmental Annotation Useage</a>
+          </li>
+          <li>
+            <a t:type="PageLink" page="expansion">Expansion Page</a>
+          </li>
+          <li>
+            <a href="BadTemplate">BadTemplate Page</a> -- More exception reporting </li>
+          <li>
+            <a t:type="PageLink" page="ActionPage">Action Page</a> -- tests fixture for ActionLink
+            component </li>
+          <li>
+            <a t:type="PageLink" page="InstanceMixin">InstanceMixin</a> -- Mixin added to particular
+            component instance </li>
+          <li>
+            <a t:type="PageLink" page="RenderPhaseOrder">RenderPhaseOrder</a> -- Order of operations
+            when invoking render phase methods </li>
+          <li><a t:type="PageLink" page="SimpleForm">SimpleForm</a> -- first pass at writing Form
+            and TextField components </li>
+          <li>
+            <a t:type="PageLink" page="NumberSelect">NumberSelect</a> -- passivate/activate page
+            context demo </li>
+          <li>
+            <a t:type="PageLink" page="Localization">Localization</a> -- accessing localized
+            messages from the component catalog </li>
+          <li>
+            <a t:type="PageLink" page="AssetDemo">AssetDemo</a> -- declaring an using Assets </li>
+          <li>
+            <a t:type="PageLink" page="ExpansionSubclass">ExpansionSubclass</a> -- components can
+            inherit templates from base classes </li>
+          <li>
+            <a href="InjectComponentMismatch">InjectComponentMismatch</a> -- check error reporting
+            when @InjectComponent doesn't match the actual field type </li>
 
-                    <li>
-                        <a t:type="PageLink" page="ParameterDefault">ParameterDefault</a> --
-                        defaulter methods for component parameters </li>
-                    <li>
-                        <a t:type="PageLink" page="ValidForm">ValidForm</a> -- server-side input
-                        validation</li>
-                </ul>
-            </td>
-            <td>
-                <ul>
-                    <li>
-                        <a t:type="PageLink" page="AnyDemo">AnyDemo</a> -- test out the Any
-                        component </li>
-                    <li>
-                        <a t:type="PageLink" page="PasswordFieldDemo">PasswordFieldDemo</a> -- test
-                        for the PasswordField component </li>
-                    <li>
-                        <a t:type="PageLink" page="RenderComponentDemo">RenderComponentDemo</a> --
-                        components that "nominate" other components to render </li>
-                    <li>
-                        <a t:type="PageLink" page="BlockDemo">BlockDemo</a> -- use of blocks to
-                        control rendering </li>
-                    <li>
-                        <a t:type="PageLink" page="ToDoListVolatile">ToDo List (Volatile)</a> --
-                        Loops and Submit inside Form, volatile mode </li>
-                    <li>
-                        <a t:type="PageLink" page="ToDoList">ToDo List</a> -- Loops and Submit
-                        inside Form using a primary key encoder </li>
-                    <li>
-                        <a t:type="PageLink" page="FlashDemo">FlashDemo</a> -- demonstrate "flash"
-                        persistence </li>
-                    <li>
-                        <a t:type="PageLink" page="beaneditordemo">BeanEditor Demo</a> --
-                        demonstrate the BeanEditor mega-component </li>
-                    <li>
-                        <a t:type="PageLink" page="pageloadeddemo">PageLoaded Demo</a> -- shows that
-                        page lifecycle methods are invoked </li>
-                    <li>
-                        <a t:type="PageLink" page="griddemo">Grid Demo</a> -- default Grid component </li>
-                    <li>
-                        <a t:type="PageLink" page="nullgrid">Null Grid</a> -- handling of null
-                        source for Grid </li>
-                    <li>
-                        <a t:type="PageLink" page="gridenumdemo">Grid Enum Demo</a> -- handling of
-                        enum types in the Grid </li>
-                    <li>
-                        <a t:type="ActionLink" t:id="textStreamResponse">Text Stream Response</a> --
-                        component event that directly returns a stream of character (rather than a
-                        redirect) </li>
-                    <li>
-                        <a t:type="PageLink" page="protected">Protected Page</a> -- Demonstrate
-                        result of non-void return from a page's activate method. </li>
-                    <li>
-                        <a t:type="PageLink" page="kicker">Kicker</a> -- demos complex page and
-                        component context in links </li>
-                    <li>
-                        <a t:type="PageLink" page="simpletrackgriddemo">SimpleTrack Grid Demo</a> --
-                        customizing the model for a Grid around an interface </li>
-                    <li>
-                        <a t:type="PageLink" page="pagelinkcontext">PageLink Context Demo</a> --
-                        passing explicit context in a page render link </li>
-                  <li>
-                    <a t:type="pagelink" page="ValidBeanEditorDemo">Client Validation Demo</a> --BeanEditor with validation enabled
-                  </li>
-                  
-                  <li>
-                    <a href="recursivedemo">Recursive Demo</a> -- check for handling of recursive components
-                  </li>
-                </ul>
-            </td>
-        </tr>
-    </table>
+          <li>
+            <a t:type="PageLink" page="ParameterDefault">ParameterDefault</a> -- defaulter methods
+            for component parameters </li>
+          <li>
+            <a t:type="PageLink" page="ValidForm">ValidForm</a> -- server-side input validation</li>
+        </ul>
+      </td>
+      <td>
+        <ul>
+          <li>
+            <a t:type="PageLink" page="AnyDemo">AnyDemo</a> -- test out the Any component </li>
+          <li>
+            <a t:type="PageLink" page="PasswordFieldDemo">PasswordFieldDemo</a> -- test for the
+            PasswordField component </li>
+          <li>
+            <a t:type="PageLink" page="RenderComponentDemo">RenderComponentDemo</a> -- components
+            that "nominate" other components to render </li>
+          <li>
+            <a t:type="PageLink" page="BlockDemo">BlockDemo</a> -- use of blocks to control
+            rendering </li>
+          <li>
+            <a t:type="PageLink" page="ToDoListVolatile">ToDo List (Volatile)</a> -- Loops and
+            Submit inside Form, volatile mode </li>
+          <li>
+            <a t:type="PageLink" page="ToDoList">ToDo List</a> -- Loops and Submit inside Form using
+            a primary key encoder </li>
+          <li>
+            <a t:type="PageLink" page="FlashDemo">FlashDemo</a> -- demonstrate "flash" persistence </li>
+          <li>
+            <a t:type="PageLink" page="beaneditordemo">BeanEditor Demo</a> -- demonstrate the
+            BeanEditor mega-component </li>
+          <li>
+            <a t:type="PageLink" page="pageloadeddemo">PageLoaded Demo</a> -- shows that page
+            lifecycle methods are invoked </li>
+          <li>
+            <a t:type="PageLink" page="griddemo">Grid Demo</a> -- default Grid component </li>
+          <li>
+            <a t:type="PageLink" page="nullgrid">Null Grid</a> -- handling of null source for Grid </li>
+          <li>
+            <a t:type="PageLink" page="gridenumdemo">Grid Enum Demo</a> -- handling of enum types in
+            the Grid </li>
+          <li>
+            <a t:type="ActionLink" t:id="textStreamResponse">Text Stream Response</a> -- component
+            event that directly returns a stream of character (rather than a redirect) </li>
+          <li>
+            <a t:type="PageLink" page="protected">Protected Page</a> -- Demonstrate result of
+            non-void return from a page's activate method. </li>
+          <li>
+            <a t:type="PageLink" page="kicker">Kicker</a> -- demos complex page and component
+            context in links </li>
+          <li>
+            <a t:type="PageLink" page="simpletrackgriddemo">SimpleTrack Grid Demo</a> -- customizing
+            the model for a Grid around an interface </li>
+          <li>
+            <a t:type="PageLink" page="pagelinkcontext">PageLink Context Demo</a> -- passing
+            explicit context in a page render link </li>
+          <li>
+            <a t:type="pagelink" page="ValidBeanEditorDemo">Client Validation Demo</a> --BeanEditor
+            with validation enabled </li>
+
+          <li>
+            <a href="recursivedemo">Recursive Demo</a> -- check for handling of recursive components </li>
+
+          <li>
+            <t:actionlink t:id="badreturntype">BadReturnType Demo</t:actionlink> -- Error report due
+            to event handler method returning unacceptible return value (an Integer) </li>
+        </ul>
+      </td>
+    </tr>
+  </table>
 
 </html>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sun Mar 11 19:01:04 2007
@@ -842,6 +842,7 @@
         assertTextPresent("First Name: [Howard]");
     }
 
+    @Test
     public void recursive_components_are_identified_as_errors()
     {
         open(BASE_URL);
@@ -851,5 +852,17 @@
                 "An unexpected application exception has occurred.",
                 "The template for component org.apache.tapestry.integration.app1.components.Recursive is recursive (contains another direct or indirect reference to component org.apache.tapestry.integration.app1.components.Recursive). This is not supported (components may not contain themselves).",
                 "This component is <t:recursive>recursive</t:recursive>, so we\'ll see a failure.");
+    }
+
+    @Test
+    public void check_handling_of_unexpected_type_from_component_event_handler_method()
+    {
+        open(BASE_URL);
+        clickAndWait("link=BadReturnType Demo");
+
+        assertTextPresent(
+                "An unexpected application exception has occurred.",
+                "An event handler for component org.apache.tapestry.integration.app1.pages.Start returned the value 20 (from method org.apache.tapestry.integration.app1.pages.Start.onActionFromBadReturnType() (at Start.java:34)). Return type java.lang.Integer can not be handled.");
+
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java Sun Mar 11 19:01:04 2007
@@ -27,4 +27,10 @@
 
         return new TextStreamResponse("text/html", text);
     }
+
+    Object onActionFromBadReturnType()
+    {
+        // What is Tapestry supposed to do with this? Let's see than Exception Report page.
+        return 20;
+    }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentLifecycleMethodWorkerTest.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -270,8 +270,7 @@
         train_findMethods(tf, sig);
 
         train_getMethodAnnotation(tf, sig, SetupRender.class, annotation);
-
-        train_getClassName(tf, "biff.Baz");
+        train_getMethodIdentifier(tf, sig, "biff.Baz.aMethod()");
 
         train_isRootClass(model, false);
 
@@ -307,21 +306,23 @@
         MethodSignature sigb = new MethodSignature(Modifier.PUBLIC, "void", "bMethod", new String[]
         { MarkupWriter.class.getName() }, null);
 
+        String ida = "aMethod()";
+
         train_findMethods(tf, siga, sigb);
 
         train_getMethodAnnotation(tf, siga, SetupRender.class, annotation);
+        train_getMethodIdentifier(tf, siga, ida);
+
         train_getMethodAnnotation(tf, sigb, SetupRender.class, annotation);
 
         train_isRootClass(model, false);
 
-        train_getClassName(tf, "foo.Bar");
-
         train_addMethod(
                 tf,
                 TransformConstants.SETUP_RENDER_SIGNATURE,
                 "{ super.setupRender($$);",
                 "if ($2.isAborted()) return;",
-                "$2.setSource(this, \"foo.Bar.aMethod()\");",
+                "$2.setSource(this, \"aMethod()\");",
                 "if ($2.storeResult(($w) aMethod())) return;",
                 "bMethod($1); }");
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InternalClassTransformationImplTest.java Sun Mar 11 19:01:04 2007
@@ -47,6 +47,7 @@
 import org.apache.tapestry.internal.transform.pages.ClaimedFields;
 import org.apache.tapestry.internal.transform.pages.EventHandlerTarget;
 import org.apache.tapestry.internal.transform.pages.FindFieldClass;
+import org.apache.tapestry.internal.transform.pages.MethodIdentifier;
 import org.apache.tapestry.internal.transform.pages.ParentClass;
 import org.apache.tapestry.internal.transform.pages.TargetObject;
 import org.apache.tapestry.internal.transform.pages.TargetObjectSubclass;
@@ -1088,6 +1089,28 @@
             if (f.getName().equals("_fieldToRemove"))
                 throw new AssertionError("_fieldToRemove still in transformed class.");
         }
+
+        verify();
+    }
+
+    @Test
+    public void get_method_identifier() throws Exception
+    {
+        Log log = newLog();
+
+        replay();
+
+        ClassTransformation ct = createClassTransformation(MethodIdentifier.class, log);
+
+        List<MethodSignature> sigs = ct.findMethodsWithAnnotation(OnEvent.class);
+
+        assertEquals(sigs.size(), 1);
+
+        MethodSignature sig = sigs.get(0);
+
+        assertEquals(
+                ct.getMethodIdentifier(sig),
+                "org.apache.tapestry.internal.transform.pages.MethodIdentifier.makeWaves(java.lang.String, int[]) (at MethodIdentifier.java:24)");
 
         verify();
     }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/OnEventWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/OnEventWorkerTest.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/OnEventWorkerTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/OnEventWorkerTest.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -72,7 +72,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         train_extendMethod(
                 ct,
@@ -113,7 +113,7 @@
 
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         train_extendMethod(
                 ct,
@@ -156,8 +156,8 @@
 
         train_addInjectedField(ct, "eventTypes", "_v", "Submit");
 
-        train_getClassName(ct, "foo.Bar");
-
+        train_getMethodIdentifier(ct, signature, "foo.Bar.onSubmit()");
+        
         train_extendMethod(
                 ct,
                 TransformConstants.HANDLE_COMPONENT_EVENT,
@@ -201,7 +201,7 @@
 
         train_getResourcesFieldName(ct, "_res");
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         train_extendMethod(
                 ct,
@@ -239,7 +239,7 @@
 
         train_getResourcesFieldName(ct, "_res");
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.onAnyEventFromZork()");
 
         train_extendMethod(
                 ct,
@@ -289,7 +289,7 @@
 
         train_getResourcesFieldName(ct, "_res");
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         train_extendMethod(
                 ct,
@@ -332,7 +332,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         train_extendMethod(
                 ct,
@@ -369,7 +369,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo(java.lang.String)");
 
         train_extendMethod(
                 ct,
@@ -406,7 +406,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo(boolean)");
 
         train_extendMethod(
                 ct,
@@ -444,7 +444,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo(java.lang.String, java.lang.Integer)");
 
         train_extendMethod(
                 ct,
@@ -482,7 +482,7 @@
         train_value(annotation, new String[0]);
         train_component(annotation, new String[0]);
 
-        train_getClassName(ct, "foo.Bar");
+        train_getMethodIdentifier(ct, signature, "foo.Bar.foo()");
 
         // Notice that the context doesn't affect the indexing of the other parameters. Though it is
         // unlikely that a method would use both a context array and explicit context parameters.
@@ -493,8 +493,7 @@
                 "{",
                 BOILERPLATE_1,
                 BOILERPLATE_2,
-                String.format("$1.setSource(this, \"foo.Bar.%s\");", signature
-                        .getMediumDescription()),
+                "$1.setSource(this, \"foo.Bar.foo()\");",
                 "foo((java.lang.String)$1.coerceContext(0, \"java.lang.String\"), ",
                 "$1.getContext(), ",
                 "(java.lang.Integer)$1.coerceContext(1, \"java.lang.Integer\"));",

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java?view=auto&rev=517073
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/transform/pages/MethodIdentifier.java Sun Mar 11 19:01:04 2007
@@ -0,0 +1,26 @@
+// Copyright 2007 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.tapestry.internal.transform.pages;
+
+import org.apache.tapestry.annotations.OnEvent;
+
+public class MethodIdentifier
+{
+    @OnEvent
+    String makeWaves(String argument1, int[] argument2)
+    {
+        return null;
+    }
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/RegistryBuilder.java Sun Mar 11 19:01:04 2007
@@ -29,7 +29,9 @@
 import org.apache.tapestry.ioc.internal.LogSourceImpl;
 import org.apache.tapestry.ioc.internal.RegistryImpl;
 import org.apache.tapestry.ioc.internal.RegistryWrapper;
+import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
 import org.apache.tapestry.ioc.internal.util.OneShotLock;
+import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.TapestryIOCModule;
 
 /**
@@ -57,6 +59,8 @@
 
     private final LogSource _logSource;
 
+    private final ClassFactory _classFactory;
+
     public RegistryBuilder()
     {
         this(Thread.currentThread().getContextClassLoader());
@@ -73,6 +77,13 @@
         _logSource = logSource;
         _log = logSource.getLog(RegistryBuilder.class);
 
+        // Make the ClassFactory appear to be a service inside TapestryIOCModule, even before that
+        // module exists.
+
+        Log classFactoryLog = logSource.getLog(TapestryIOCModule.class.getName() + ".ClassFactory");
+
+        _classFactory = new ClassFactoryImpl(_classLoader, classFactoryLog);
+
         add(TapestryIOCModule.class);
     }
 
@@ -95,7 +106,7 @@
         {
             Class c = queue.remove(0);
 
-            ModuleDef def = new DefaultModuleDefImpl(c, _log);
+            ModuleDef def = new DefaultModuleDefImpl(c, _log, _classFactory);
             add(def);
 
             SubModule annotation = ((AnnotatedElement) c).getAnnotation(SubModule.class);
@@ -127,7 +138,7 @@
     {
         _lock.lock();
 
-        RegistryImpl registry = new RegistryImpl(_modules, _classLoader, _logSource,
+        RegistryImpl registry = new RegistryImpl(_modules, _classFactory, _logSource,
                 _serviceOverrides);
 
         registry.eagerLoadServices();

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ContributionDefImpl.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -12,103 +12,104 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.ioc.internal;
-
+package org.apache.tapestry.ioc.internal;
+
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.apache.tapestry.ioc.Configuration;
-import org.apache.tapestry.ioc.MappedConfiguration;
-import org.apache.tapestry.ioc.ModuleBuilderSource;
-import org.apache.tapestry.ioc.OrderedConfiguration;
-import org.apache.tapestry.ioc.ServiceLocator;
-import org.apache.tapestry.ioc.def.ContributionDef;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.tapestry.ioc.Configuration;
+import org.apache.tapestry.ioc.MappedConfiguration;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.OrderedConfiguration;
+import org.apache.tapestry.ioc.ServiceLocator;
+import org.apache.tapestry.ioc.def.ContributionDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
-
-/**
- * 
- */
-public class ContributionDefImpl implements ContributionDef
-{
-    private final String _serviceId;
-
-    private final Method _contributorMethod;
-
-    public ContributionDefImpl(String serviceId, Method contributorMethod)
-    {
-        _serviceId = serviceId;
-        _contributorMethod = contributorMethod;
-    }
-
-    @Override
-    public String toString()
-    {
-        return InternalUtils.asString(_contributorMethod);
-    }
-
-    public String getServiceId()
-    {
-        return _serviceId;
-    }
-
-    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
-            Configuration configuration)
-    {
-        invokeMethod(moduleBuilderSource, locator, Configuration.class, configuration);
-    }
-
-    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
-            OrderedConfiguration configuration)
-    {
-        invokeMethod(moduleBuilderSource, locator, OrderedConfiguration.class, configuration);
-    }
-
-    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
-            MappedConfiguration configuration)
-    {
-        invokeMethod(moduleBuilderSource, locator, MappedConfiguration.class, configuration);
-    }
-
-    private <T> void invokeMethod(ModuleBuilderSource source, ServiceLocator locator,
-            Class<T> parameterType, T parameterValue)
-    {
-        Map<Class, Object> parameterDefaults = newMap();
-
-        // The way it works is: the method will take Configuration, OrderedConfiguration or
-        // MappedConfiguration. So, if the method is for one type and the service is for a different
-        // type, then we'll see an error putting together the parameter.
-
-        parameterDefaults.put(parameterType, parameterValue);
-        parameterDefaults.put(ServiceLocator.class, locator);
-
-        Throwable fail = null;
-
-        Object moduleBuilder = InternalUtils.isStatic(_contributorMethod) ? null : source
-                .getModuleBuilder();
-
-        try
-        {
-            Object[] parameters = InternalUtils.calculateParametersForMethod(
-                    _contributorMethod,
-                    locator,
-                    parameterDefaults);
-
-            _contributorMethod.invoke(moduleBuilder, parameters);
-        }
-        catch (InvocationTargetException ex)
-        {
-            fail = ex.getTargetException();
-        }
-        catch (Exception ex)
-        {
-            fail = ex;
-        }
-
-        if (fail != null)
-            throw new RuntimeException(IOCMessages
-                    .contributionMethodError(_contributorMethod, fail), fail);
-    }
-}
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+public class ContributionDefImpl implements ContributionDef
+{
+    private final String _serviceId;
+
+    private final Method _contributorMethod;
+
+    private final ClassFactory _classFactory;
+
+    public ContributionDefImpl(String serviceId, Method contributorMethod, ClassFactory classFactory)
+    {
+        _serviceId = serviceId;
+        _contributorMethod = contributorMethod;
+        _classFactory = classFactory;
+    }
+
+    @Override
+    public String toString()
+    {
+        return InternalUtils.asString(_contributorMethod, _classFactory);
+    }
+
+    public String getServiceId()
+    {
+        return _serviceId;
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            Configuration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, Configuration.class, configuration);
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            OrderedConfiguration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, OrderedConfiguration.class, configuration);
+    }
+
+    public void contribute(ModuleBuilderSource moduleBuilderSource, ServiceLocator locator,
+            MappedConfiguration configuration)
+    {
+        invokeMethod(moduleBuilderSource, locator, MappedConfiguration.class, configuration);
+    }
+
+    private <T> void invokeMethod(ModuleBuilderSource source, ServiceLocator locator,
+            Class<T> parameterType, T parameterValue)
+    {
+        Map<Class, Object> parameterDefaults = newMap();
+
+        // The way it works is: the method will take Configuration, OrderedConfiguration or
+        // MappedConfiguration. So, if the method is for one type and the service is for a different
+        // type, then we'll see an error putting together the parameter.
+
+        parameterDefaults.put(parameterType, parameterValue);
+        parameterDefaults.put(ServiceLocator.class, locator);
+
+        Throwable fail = null;
+
+        Object moduleBuilder = InternalUtils.isStatic(_contributorMethod) ? null : source
+                .getModuleBuilder();
+
+        try
+        {
+            Object[] parameters = InternalUtils.calculateParametersForMethod(
+                    _contributorMethod,
+                    locator,
+                    parameterDefaults);
+
+            _contributorMethod.invoke(moduleBuilder, parameters);
+        }
+        catch (InvocationTargetException ex)
+        {
+            fail = ex.getTargetException();
+        }
+        catch (Exception ex)
+        {
+            fail = ex;
+        }
+
+        if (fail != null)
+            throw new RuntimeException(IOCMessages
+                    .contributionMethodError(_contributorMethod, fail), fail);
+    }
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DecoratorDefImpl.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -12,85 +12,87 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.ioc.internal;
-
+package org.apache.tapestry.ioc.internal;
+
 import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
-
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.apache.tapestry.ioc.IdMatcher;
-import org.apache.tapestry.ioc.ModuleBuilderSource;
-import org.apache.tapestry.ioc.ServiceDecorator;
-import org.apache.tapestry.ioc.ServiceResources;
-import org.apache.tapestry.ioc.def.DecoratorDef;
-import org.apache.tapestry.ioc.def.ServiceDef;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.tapestry.ioc.IdMatcher;
+import org.apache.tapestry.ioc.ModuleBuilderSource;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceResources;
+import org.apache.tapestry.ioc.def.DecoratorDef;
+import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
-
-/**
- * 
- */
-public class DecoratorDefImpl implements DecoratorDef
-{
-    private final String _decoratorId;
-
-    private final Method _decoratorMethod;
-
-    private final IdMatcher _idMatcher;
-
-    private final String[] _constraints;
-
-    public DecoratorDefImpl(String decoratorId, Method decoratorMethod, String[] patterns,
-            String[] constraints)
-    {
-        _decoratorId = notBlank(decoratorId, "decoratorId");
-        _decoratorMethod = notNull(decoratorMethod, "decoratorMethod");
-
-        List<IdMatcher> matchers = CollectionFactory.newList();
-
-        for (String pattern : notNull(patterns, "patterns"))
-        {
-            IdMatcher matcher = new IdMatcherImpl(pattern);
-            matchers.add(matcher);
-        }
-
-        _idMatcher = new OrIdMatcher(matchers);
-
-        _constraints = constraints != null ? constraints : new String[0];
-    }
-
-    @Override
-    public String toString()
-    {
-        return InternalUtils.asString(_decoratorMethod);
-    }
-
-    public String[] getConstraints()
-    {
-        return _constraints;
-    }
-
-    public String getDecoratorId()
-    {
-        return _decoratorId;
-    }
-
-    public ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource,
-            ServiceResources resources)
-    {
-        return new ServiceDecoratorImpl(_decoratorMethod, moduleBuilderSource, resources);
-    }
-
-    /**
-     * Returns true if <em>any</em> provided pattern matches the id of the service.
-     */
-    public boolean matches(ServiceDef serviceDef)
-    {
-        String serviceId = serviceDef.getServiceId();
-
-        return _idMatcher.matches(serviceId);
-    }
-
-}
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+public class DecoratorDefImpl implements DecoratorDef
+{
+    private final String _decoratorId;
+
+    private final Method _decoratorMethod;
+
+    private final IdMatcher _idMatcher;
+
+    private final String[] _constraints;
+
+    private final ClassFactory _classFactory;
+
+    public DecoratorDefImpl(String decoratorId, Method decoratorMethod, String[] patterns,
+            String[] constraints, ClassFactory classFactory)
+    {
+        _decoratorId = notBlank(decoratorId, "decoratorId");
+        _decoratorMethod = notNull(decoratorMethod, "decoratorMethod");
+
+        List<IdMatcher> matchers = CollectionFactory.newList();
+
+        for (String pattern : notNull(patterns, "patterns"))
+        {
+            IdMatcher matcher = new IdMatcherImpl(pattern);
+            matchers.add(matcher);
+        }
+
+        _idMatcher = new OrIdMatcher(matchers);
+
+        _constraints = constraints != null ? constraints : new String[0];
+
+        _classFactory = classFactory;
+    }
+
+    @Override
+    public String toString()
+    {
+        return InternalUtils.asString(_decoratorMethod, _classFactory);
+    }
+
+    public String[] getConstraints()
+    {
+        return _constraints;
+    }
+
+    public String getDecoratorId()
+    {
+        return _decoratorId;
+    }
+
+    public ServiceDecorator createDecorator(ModuleBuilderSource moduleBuilderSource,
+            ServiceResources resources)
+    {
+        return new ServiceDecoratorImpl(_decoratorMethod, moduleBuilderSource, resources);
+    }
+
+    /**
+     * Returns true if <em>any</em> provided pattern matches the id of the service.
+     */
+    public boolean matches(ServiceDef serviceDef)
+    {
+        String serviceId = serviceDef.getServiceId();
+
+        return _idMatcher.matches(serviceId);
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImpl.java Sun Mar 11 19:01:04 2007
@@ -44,6 +44,7 @@
 import org.apache.tapestry.ioc.def.ModuleDef;
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
 
 /**
  * Starting from the Class for a module builder, identifies all the services (service builder
@@ -65,6 +66,8 @@
 
     private final Log _log;
 
+    private final ClassFactory _classFactory;
+
     /** Keyed on service id. */
     private final Map<String, ServiceDef> _serviceDefs = newCaseInsensitiveMap();
 
@@ -86,11 +89,14 @@
      * @param builderClass
      *            the class that is responsible for building services, etc.
      * @param log
+     * @param classFactory
+     *            TODO
      */
-    public DefaultModuleDefImpl(Class builderClass, Log log)
+    public DefaultModuleDefImpl(Class builderClass, Log log, ClassFactory classFactory)
     {
         _builderClass = builderClass;
         _log = log;
+        _classFactory = classFactory;
 
         grind();
     }
@@ -198,7 +204,7 @@
             return;
         }
 
-        ContributionDef def = new ContributionDefImpl(serviceId, method);
+        ContributionDef def = new ContributionDefImpl(serviceId, method, _classFactory);
 
         _contributionDefs.add(def);
     }
@@ -238,7 +244,8 @@
         String[] patterns = match == null ? new String[]
         { decoratorId } : match.value();
 
-        DecoratorDef def = new DecoratorDefImpl(decoratorId, method, patterns, constraints);
+        DecoratorDef def = new DecoratorDefImpl(decoratorId, method, patterns, constraints,
+                _classFactory);
 
         _decoratorDefs.put(decoratorId, def);
     }
@@ -295,7 +302,8 @@
         String lifecycle = extractLifecycle(method);
         boolean eagerLoad = method.isAnnotationPresent(EagerLoad.class);
 
-        _serviceDefs.put(serviceId, new ServiceDefImpl(serviceId, lifecycle, method, eagerLoad));
+        _serviceDefs.put(serviceId, new ServiceDefImpl(serviceId, lifecycle, method, eagerLoad,
+                _classFactory));
     }
 
     private String extractLifecycle(Method method)

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java Sun Mar 11 19:01:04 2007
@@ -24,6 +24,7 @@
 import org.apache.tapestry.ioc.ServiceDecorator;
 import org.apache.tapestry.ioc.ServiceLifecycle;
 import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.test.IOCTestCase;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.AfterSuite;
@@ -33,12 +34,16 @@
 {
     private static Registry _registry;
 
+    private static ClassFactory _classFactory;
+
     @BeforeSuite
     public final void setup_registry()
     {
         RegistryBuilder builder = new RegistryBuilder();
 
         _registry = builder.build();
+
+        _classFactory = _registry.getService(ClassFactory.class);
     }
 
     @AfterSuite
@@ -47,12 +52,18 @@
         _registry.shutdown();
 
         _registry = null;
+        _classFactory = null;
     }
 
     @AfterMethod
     public final void cleanupThread()
     {
         _registry.cleanupThread();
+    }
+
+    public final ClassFactory getClassFactory()
+    {
+        return _classFactory;
     }
 
     public final <T> T getObject(String reference, Class<T> objectType)

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Sun Mar 11 19:01:04 2007
@@ -41,10 +41,8 @@
 import org.apache.tapestry.ioc.def.DecoratorDef;
 import org.apache.tapestry.ioc.def.ModuleDef;
 import org.apache.tapestry.ioc.def.ServiceDef;
-import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
 import org.apache.tapestry.ioc.internal.services.RegistryShutdownHubImpl;
 import org.apache.tapestry.ioc.internal.services.ThreadCleanupHubImpl;
-import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
 import org.apache.tapestry.ioc.internal.util.OneShotLock;
 import org.apache.tapestry.ioc.internal.util.Orderer;
@@ -89,6 +87,12 @@
     private final Map<String, ServiceLifecycle> _lifecycles = newCaseInsensitiveMap();
 
     /**
+     * Map from service interface class to list of service ids that implement the interface
+     * (including builtin services).
+     */
+    private final Map<Class, List<String>> _serviceInterfaceToServiceIdList = newMap();
+
+    /**
      * Service implementation overrides, keyed on service id. Service implementations are most
      * useful when perfroming integration tests on services. As one service can bring in another, we
      * have to stop at a certain "bounary" services by provide stub/ mock objects as their
@@ -125,15 +129,15 @@
      * 
      * @param moduleDefs
      *            defines the modules (and builders, decorators, etc., within)
-     * @param contextClassLoader
-     *            the class loader used to load classes
+     * @param classFactory
+     *            TODO
      * @param logSource
      *            used to obtain Log instances
      * @param serviceOverrides
      *            overrides for service implementation (used in testing, see
      *            {@link RegistryBuilder#addServiceOverride(String, Object)})
      */
-    public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassLoader contextClassLoader,
+    public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassFactory classFactory,
             LogSource logSource, Map<String, Object> serviceOverrides)
     {
         _logSource = logSource;
@@ -157,18 +161,20 @@
                             .getServiceDef(serviceId), module.getServiceDef(serviceId)));
 
                 _serviceIdToModule.put(serviceId, module);
+
+                ServiceDef serviceDef = module.getServiceDef(serviceId);
+
+                addServiceImplementer(serviceDef.getServiceInterface(), serviceId);
             }
         }
 
         addBuiltin(LOG_SOURCE_SERVICE_ID, LogSource.class, _logSource);
 
-        Log log = logForBuiltinService(CLASS_FACTORY_SERVICE_ID);
-
-        _classFactory = new ClassFactoryImpl(contextClassLoader, log);
+        _classFactory = classFactory;
 
         addBuiltin(CLASS_FACTORY_SERVICE_ID, ClassFactory.class, _classFactory);
 
-        log = logForBuiltinService(THREAD_CLEANUP_HUB_SERVICE_ID);
+        Log log = logForBuiltinService(THREAD_CLEANUP_HUB_SERVICE_ID);
 
         _cleanupHub = new ThreadCleanupHubImpl(log);
 
@@ -216,6 +222,21 @@
     {
         _builtinTypes.put(serviceId, serviceInterface);
         _builtinServices.put(serviceId, service);
+
+        addServiceImplementer(serviceInterface, serviceId);
+    }
+
+    private void addServiceImplementer(Class serviceInterface, String serviceId)
+    {
+        List<String> serviceIds = _serviceInterfaceToServiceIdList.get(serviceInterface);
+
+        if (serviceIds == null)
+        {
+            serviceIds = newList();
+            _serviceInterfaceToServiceIdList.put(serviceInterface, serviceIds);
+        }
+
+        serviceIds.add(serviceId);
     }
 
     public synchronized void shutdown()
@@ -462,15 +483,11 @@
     {
         _lock.check();
 
-        List<String> ids = CollectionFactory.newList();
+        List<String> serviceIds = _serviceInterfaceToServiceIdList.get(serviceInterface);
 
-        for (Module m : _modules)
-        {
-            Collection<String> matchingIds = m.findServiceIdsForInterface(serviceInterface);
-            ids.addAll(matchingIds);
-        }
+        if (serviceIds == null) serviceIds = Collections.emptyList();
 
-        switch (ids.size())
+        switch (serviceIds.size())
         {
             case 0:
 
@@ -478,15 +495,17 @@
 
             case 1:
 
-                String serviceId = ids.get(0);
+                String serviceId = serviceIds.get(0);
 
                 return getService(serviceId, serviceInterface);
 
             default:
 
-                Collections.sort(ids);
+                Collections.sort(serviceIds);
 
-                throw new RuntimeException(IOCMessages.manyServiceMatches(serviceInterface, ids));
+                throw new RuntimeException(IOCMessages.manyServiceMatches(
+                        serviceInterface,
+                        serviceIds));
         }
     }
 

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/ServiceDefImpl.java Sun Mar 11 19:01:04 2007
@@ -20,6 +20,7 @@
 import org.apache.tapestry.ioc.ServiceBuilderResources;
 import org.apache.tapestry.ioc.def.ServiceDef;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.ClassFactory;
 
 public class ServiceDefImpl implements ServiceDef
 {
@@ -31,18 +32,22 @@
 
     private final boolean _eagerLoad;
 
-    ServiceDefImpl(String serviceId, String lifecycle, Method builderMethod, boolean eagerLoad)
+    private final ClassFactory _classFactory;
+
+    ServiceDefImpl(String serviceId, String lifecycle, Method builderMethod, boolean eagerLoad,
+            ClassFactory classFactory)
     {
         _serviceId = serviceId;
         _lifecycle = lifecycle;
         _builderMethod = builderMethod;
         _eagerLoad = eagerLoad;
+        _classFactory = classFactory;
     }
 
     @Override
     public String toString()
     {
-        return InternalUtils.asString(_builderMethod);
+        return InternalUtils.asString(_builderMethod, _classFactory);
     }
 
     Method getBuilderMethod()

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassFactoryImpl.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2004, 2005, 2006 The Apache Software Foundation
+// Copyright 2006, 2007 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.
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry.ioc.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
+
 import java.lang.reflect.Method;
 
 import javassist.CtClass;
@@ -24,11 +26,10 @@
 import org.apache.tapestry.ioc.services.ClassFab;
 import org.apache.tapestry.ioc.services.ClassFabUtils;
 import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodLocation;
 
 /**
  * Implementation of {@link org.apache.tapestry.ioc.services.ClassFactory}.
- * 
- * @author Howard Lewis Ship
  */
 public class ClassFactoryImpl implements ClassFactory
 {
@@ -111,8 +112,13 @@
         return _loader;
     }
 
-    public int getMethodLineNumber(Method method)
+    public MethodLocation getMethodLocation(Method method)
     {
+        notNull(method, "method");
+
+        // TODO: Is it worth caching this? Probably not as it usually is only
+        // invoked perhaps at startup and in the event of errors.
+
         CtClass ctClass = _classSource.getCtClass(method.getDeclaringClass());
 
         StringBuilder builder = new StringBuilder("(");
@@ -129,11 +135,15 @@
         {
             CtMethod ctMethod = ctClass.getMethod(method.getName(), builder.toString());
 
-            return ctMethod.getMethodInfo().getLineNumber(0);
+            int lineNumber = ctMethod.getMethodInfo().getLineNumber(0);
+
+            String sourceFile = ctMethod.getDeclaringClass().getClassFile2().getSourceFile();
+
+            return new MethodLocation(method, sourceFile, lineNumber);
         }
         catch (Exception ex)
         {
-            return -1;
+            return null;
         }
     }
 

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProvider.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProvider.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/MasterObjectProvider.java Sun Mar 11 19:01:04 2007
@@ -1,4 +1,4 @@
-// Copyright 2006 2007 The Apache Software Foundation
+// Copyright 2006 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.

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java?view=diff&rev=517073&r1=517072&r2=517073
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InternalUtils.java Sun Mar 11 19:01:04 2007
@@ -32,6 +32,8 @@
 import org.apache.tapestry.ioc.ServiceLocator;
 import org.apache.tapestry.ioc.annotations.Inject;
 import org.apache.tapestry.ioc.annotations.InjectService;
+import org.apache.tapestry.ioc.services.ClassFactory;
+import org.apache.tapestry.ioc.services.MethodLocation;
 
 /**
  * Utilities used within various internal implemenations of Tapestry IOC and the rest of the
@@ -45,6 +47,24 @@
      * member name.
      */
     public static final String NAME_PREFIX = "_$";
+
+    /**
+     * Converts a method to a user presentable string using a {@link ClassFactory} to obtain a
+     * {@link MethodLocation} (where possible). {@link #asString(Method)} is used under the covers,
+     * to present a detailed, but not excessive, description of the class, method and parameters.
+     * 
+     * @param method
+     *            method to convert to a string
+     * @param classFactory
+     *            used to obtain the {@link MethodLocation}
+     * @return the method formatted for presentation to the user
+     */
+    public static String asString(Method method, ClassFactory classFactory)
+    {
+        MethodLocation location = classFactory.getMethodLocation(method);
+
+        return location != null ? location.toString() : asString(method);
+    }
 
     /**
      * Converts a method to a user presentable string consisting of the containing class name, the



Mime
View raw message