You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/02/02 20:27:02 UTC

svn commit: r617866 [2/2] - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/ tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ tapestry-core/src/main/java/org/apache/tapestry/internal/ tapestry-core/src/m...

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ComponentEventImplTest.java Sat Feb  2 11:26:57 2008
@@ -15,10 +15,10 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.internal.structure.PageResources;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.ioc.services.TypeCoercer;
-import org.apache.tapestry.runtime.Component;
 import org.apache.tapestry.runtime.ComponentEvent;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -44,10 +44,13 @@
     public void matches_on_event_type()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
 
         assertTrue(event.matches("eventType", "someId", 0));
         assertFalse(event.matches("foo", "someId", 0));
@@ -59,10 +62,13 @@
     public void event_type_match_is_case_insensitive()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
 
         assertTrue(event.matches("EVENTTYPE", "someid", 0));
 
@@ -73,10 +79,13 @@
     public void matches_on_component_id()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
 
         assertTrue(event.matches("eventType", "someId", 0));
 
@@ -89,9 +98,13 @@
     public void component_id_matches_are_case_insensitive()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
 
         replay();
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", null, handler, null);
+
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
 
         assertTrue(event.matches("eventtype", "SOMEID", 0));
 
@@ -103,15 +116,19 @@
     {
         ComponentEventCallback handler = mockComponentEventHandler();
         PageResources resources = mockPageResources();
+        EventContext context = mockEventContext();
+        Integer value = new Integer(27);
 
         train_toClass(resources, "java.lang.Integer", Integer.class);
-        train_coerce(resources, "27", Integer.class, new Integer(27));
+
+        train_getCount(context, 2);
+        train_get(context, Integer.class, 0, value);
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", new String[]{"27"}, handler, resources);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
 
-        assertEquals(event.coerceContext(0, "java.lang.Integer"), new Integer(27));
+        assertSame(event.coerceContext(0, "java.lang.Integer"), value);
 
         verify();
     }
@@ -120,11 +137,13 @@
     public void coerce_when_not_enough_context()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
-        Component component = mockComponent();
+        EventContext context = mockEventContext();
+
+        train_getCount(context, 0);
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", new String[]{"27"}, handler, null);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, null);
 
         event.setMethodDescription("foo.Bar.baz()");
 
@@ -145,11 +164,18 @@
     public void unable_to_coerce()
     {
         ComponentEventCallback handler = mockComponentEventHandler();
-        Component component = mockComponent();
+        EventContext context = mockEventContext();
+        PageResources resources = mockPageResources();
+
+        train_toClass(resources, Integer.class.getName(), Integer.class);
+
+        train_getCount(context, 1);
+
+        expect(context.get(Integer.class, 0)).andThrow(new NumberFormatException("Not so easy, is it?"));
 
         replay();
 
-        ComponentEvent event = new ComponentEventImpl("eventType", "someId", new String[]{"abc"}, handler, null);
+        ComponentEvent event = new ComponentEventImpl("eventType", "someId", context, handler, resources);
 
         event.setMethodDescription("foo.Bar.baz()");
 
@@ -174,11 +200,10 @@
     {
         Object result = new Object();
         String methodDescription = "foo.Bar.baz()";
-        Component component = mockComponent();
 
         ComponentEventCallback handler = mockComponentEventHandler();
 
-        train_handleResult(handler, result, component, methodDescription, true);
+        train_handleResult(handler, result, true);
 
         replay();
 
@@ -200,10 +225,9 @@
     {
         Object result = new Object();
         String methodDescription = "foo.Bar.baz()";
-        Component component = mockComponent();
         ComponentEventCallback handler = mockComponentEventHandler();
 
-        train_handleResult(handler, result, component, methodDescription, false);
+        train_handleResult(handler, result, false);
 
         replay();
 
@@ -221,7 +245,6 @@
     @Test
     public void store_null_result_does_not_abort_or_invoke_handler()
     {
-        Component component = mockComponent();
         ComponentEventCallback handler = mockComponentEventHandler();
 
         replay();
@@ -243,7 +266,6 @@
     {
         Object result = new Object();
         ComponentEventCallback handler = mockComponentEventHandler();
-        Component component = mockComponent();
 
         expect(handler.handleResult(result)).andReturn(true);
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java?rev=617866&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ContextValueEncoderImplTest.java Sat Feb  2 11:26:57 2008
@@ -0,0 +1,70 @@
+// Copyright 2008 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.services;
+
+import org.apache.tapestry.ValueEncoder;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.services.ContextValueEncoder;
+import org.apache.tapestry.services.ValueEncoderSource;
+import org.testng.annotations.Test;
+
+public class ContextValueEncoderImplTest extends InternalBaseTestCase
+{
+    @Test
+    public void to_client()
+    {
+        ValueEncoder valueEncoder = mockValueEncoder();
+        ValueEncoderSource source = mockValueEncoderSource();
+
+        Long value = 23L;
+        String encoded = "twentythree";
+
+
+        train_getEncoderForType(source, Long.class, valueEncoder);
+        train_toClient(valueEncoder, value, encoded);
+
+        replay();
+
+        ContextValueEncoder cve = new ContextValueEncoderImpl(source);
+
+        assertSame(cve.toClient(value), encoded);
+
+        verify();
+    }
+
+
+    @Test
+    public void to_value()
+    {
+        ValueEncoder valueEncoder = mockValueEncoder();
+        ValueEncoderSource source = mockValueEncoderSource();
+
+        Long value = 23L;
+        String clientValue = "twentythree";
+
+
+        train_getEncoderForType(source, Long.class, valueEncoder);
+        train_toValue(valueEncoder, clientValue, value);
+
+        replay();
+
+        ContextValueEncoder cve = new ContextValueEncoderImpl(source);
+
+        assertSame(cve.toValue(Long.class, clientValue), value);
+
+        verify();
+    }
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/LinkFactoryImplTest.java Sat Feb  2 11:26:57 2008
@@ -22,7 +22,7 @@
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.internal.util.Holder;
-import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.services.ContextValueEncoder;
 import org.apache.tapestry.services.Request;
 import org.apache.tapestry.services.Response;
 import org.easymock.EasyMock;
@@ -38,18 +38,18 @@
 
     private static final String PAGE_LOGICAL_NAME = "sub/MyPage";
 
-    private TypeCoercer _typeCoercer;
+    private ContextValueEncoder _contextValueEncoder;
 
     @BeforeClass
     public void setup()
     {
-        _typeCoercer = getObject(TypeCoercer.class, null);
+        _contextValueEncoder = getObject(ContextValueEncoder.class, null);
     }
 
     @AfterClass
     public void cleanup()
     {
-        _typeCoercer = null;
+        _contextValueEncoder = null;
     }
 
     @Test
@@ -114,7 +114,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, _typeCoercer, optimizer, null);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, _contextValueEncoder);
 
         factory.addListener(listener);
 
@@ -158,7 +158,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, _typeCoercer, optimizer, null);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createPageLink(page, false, "biff", "bazz");
@@ -201,7 +201,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, _typeCoercer, optimizer, null);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, null, optimizer, null, _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createPageLink(page, true);
@@ -247,7 +247,7 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, _typeCoercer, optimizer, null);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, null, _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createPageLink(PAGE_LOGICAL_NAME, false);
@@ -364,7 +364,8 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, _typeCoercer, optimizer, queue);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createActionLink(page, null, "myaction", false, "1.2.3", "4.5.6");
@@ -413,7 +414,8 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, _typeCoercer, optimizer, queue);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createActionLink(containingPage, null, "myaction", false);
@@ -463,7 +465,8 @@
 
         replay();
 
-        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, _typeCoercer, optimizer, queue);
+        LinkFactory factory = new LinkFactoryImpl(request, response, map, cache, optimizer, queue,
+                                                  _contextValueEncoder);
         factory.addListener(listener);
 
         Link link = factory.createActionLink(page, nestedId, eventName, false, context);

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageRenderDispatcherTest.java Sat Feb  2 11:26:57 2008
@@ -15,16 +15,29 @@
 package org.apache.tapestry.internal.services;
 
 import org.apache.tapestry.ComponentEventCallback;
+import org.apache.tapestry.EventContext;
 import org.apache.tapestry.TapestryConstants;
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
 import org.apache.tapestry.services.*;
-import static org.easymock.EasyMock.*;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+import org.easymock.IAnswer;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 public class PageRenderDispatcherTest extends InternalBaseTestCase
 {
+    private ContextValueEncoder _contextValueEncoder;
+
+    @BeforeClass
+    public void setup()
+    {
+        _contextValueEncoder = getService(ContextValueEncoder.class);
+    }
+
     @Test
     public void not_a_page_request() throws Exception
     {
@@ -40,7 +53,7 @@
 
         replay();
 
-        Dispatcher d = new PageRenderDispatcher(resolver, handler);
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
 
         assertFalse(d.dispatch(request, response));
 
@@ -60,7 +73,7 @@
 
         replay();
 
-        Dispatcher d = new PageRenderDispatcher(resolver, handler);
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
 
         assertFalse(d.dispatch(request, response));
 
@@ -99,7 +112,7 @@
         train_get(cache, "foo/Bar", page);
         train_getRootElement(page, rootElement);
 
-        train_triggerEvent(rootElement, TapestryConstants.ACTIVATE_EVENT, new Object[0], null, false);
+        train_triggerContextEvent(rootElement, TapestryConstants.ACTIVATE_EVENT, new Object[0], false);
 
         renderer.renderPageResponse(page);
 
@@ -107,7 +120,7 @@
 
         PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, processor, renderer);
 
-        Dispatcher d = new PageRenderDispatcher(resolver, handler);
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, null);
 
         assertTrue(d.dispatch(request, response));
 
@@ -146,7 +159,7 @@
         train_get(cache, "foo/Bar", page);
         train_getRootElement(page, rootElement);
 
-        train_triggerEvent(rootElement, TapestryConstants.ACTIVATE_EVENT, new Object[]{"zip", "zoom"}, null, false);
+        train_triggerContextEvent(rootElement, TapestryConstants.ACTIVATE_EVENT, new Object[]{"zip", "zoom"}, false);
 
         renderer.renderPageResponse(page);
 
@@ -154,7 +167,7 @@
 
         PageRenderRequestHandler handler = new PageRenderRequestHandlerImpl(cache, processor, renderer);
 
-        Dispatcher d = new PageRenderDispatcher(resolver, handler);
+        Dispatcher d = new PageRenderDispatcher(resolver, handler, _contextValueEncoder);
 
         assertTrue(d.dispatch(request, response));
 
@@ -166,10 +179,30 @@
         return newMock(ComponentEventResultProcessor.class);
     }
 
-    private void train_triggerEvent(ComponentPageElement element, String eventType, Object[] context,
-                                    ComponentEventCallback handler, boolean handled)
+    private void train_triggerContextEvent(ComponentPageElement element, String eventType, final Object[] context,
+                                           final boolean handled)
     {
-        expect(element.triggerEvent(eq(eventType), aryEq(context), isA(ComponentEventCallback.class))).andReturn(
-                handled);
+        IAnswer<Boolean> answer = new IAnswer<Boolean>()
+        {
+            public Boolean answer() throws Throwable
+            {
+                Object[] arguments = EasyMock.getCurrentArguments();
+
+                EventContext ec = (EventContext) arguments[1];
+
+                assertEquals(ec.getCount(), context.length);
+
+                for (int i = 0; i < context.length; i++)
+                {
+                    assertEquals(ec.get(Object.class, i), context[i]);
+                }
+
+
+                return handled;
+            }
+        };
+
+        expect(element.triggerContextEvent(eq(eventType), isA(EventContext.class),
+                                           isA(ComponentEventCallback.class))).andAnswer(answer);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Sat Feb  2 11:26:57 2008
@@ -14,10 +14,7 @@
 
 package org.apache.tapestry.internal.test;
 
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.ComponentResourcesCommon;
-import org.apache.tapestry.ContentType;
-import org.apache.tapestry.Link;
+import org.apache.tapestry.*;
 import org.apache.tapestry.internal.*;
 import org.apache.tapestry.internal.events.InvalidationListener;
 import org.apache.tapestry.internal.parser.ComponentTemplate;
@@ -594,5 +591,20 @@
                                              T coercedValue)
     {
         expect(pageResources.coerce(input, expectedType)).andReturn(coercedValue);
+    }
+
+    protected final EventContext mockEventContext()
+    {
+        return newMock(EventContext.class);
+    }
+
+    protected final <T> void train_get(EventContext context, Class<T> type, int index, T value)
+    {
+        expect(context.get(type, index)).andReturn(value);
+    }
+
+    protected final void train_getCount(EventContext context, int count)
+    {
+        expect(context.getCount()).andReturn(count).atLeastOnce();
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/util/StrategyRegistry.java Sat Feb  2 11:26:57 2008
@@ -24,38 +24,63 @@
  * A key component in implementing the "Gang of Four" Strategy pattern. A StrategyRegistry will
  * match up a given input type with a registered strategy for that type.
  *
- * @param <A>
- * the type of the strategy adapter
+ * @param <A> the type of the strategy adapter
  */
 public final class StrategyRegistry<A>
 {
     private final Class<A> _adapterType;
 
+    private final boolean _allowNonMatch;
+
     private final Map<Class, A> _registrations = newMap();
 
     private final Map<Class, A> _cache = newConcurrentMap();
 
     /**
-     * Creates a strategy registry for the given adapter type.
-     *
-     * @param adapterType   the type of adapter retrieved from the registry
-     * @param registrations map of registrations (the contents of the map are copied)
+     * Used to identify types for which there is no matching adapter; we're using it as if it were
+     * a ConcurrentSet.
      */
-    public StrategyRegistry(final Class<A> adapterType, Map<Class, A> registrations)
+    private final Map<Class, Boolean> _unmatched = newConcurrentMap();
+
+    private StrategyRegistry(Class<A> adapterType, Map<Class, A> registrations, boolean allowNonMatch)
     {
         _adapterType = adapterType;
+        _allowNonMatch = allowNonMatch;
+
         _registrations.putAll(registrations);
     }
 
+    /**
+     * Creates a strategy registry for the given adapter type. The registry will be configured
+     * to require matches.
+     *
+     * @param adapterType   the type of adapter retrieved from the registry
+     * @param registrations map of registrations (the contents of the map are copied)
+     */
     public static <A> StrategyRegistry<A> newInstance(Class<A> adapterType,
                                                       Map<Class, A> registrations)
     {
-        return new StrategyRegistry<A>(adapterType, registrations);
+        return newInstance(adapterType, registrations, false);
+    }
+
+    /**
+     * Creates a strategy registry for the given adapter type.
+     *
+     * @param adapterType   the type of adapter retrieved from the registry
+     * @param registrations map of registrations (the contents of the map are copied)
+     * @param allowNonMatch if true, then the registry supports non-matches when retrieving an adapter
+     */
+    public static <A> StrategyRegistry<A> newInstance(
+            Class<A> adapterType,
+            Map<Class, A> registrations, boolean allowNonMatch)
+    {
+        return new StrategyRegistry<A>(adapterType, registrations, allowNonMatch);
     }
 
     public void clearCache()
     {
         _cache.clear();
+        _unmatched.clear();
     }
 
     public Class<A> getAdapterType()
@@ -68,8 +93,8 @@
      * in which case, a search on class void is used.
      *
      * @param value for which an adapter is needed
-     * @return the adaptoer for the value
-     * @throws IllegalArgumentException if no matching adapter may be found
+     * @return the adapter for the value or null if not found (and allowNonMatch is true)
+     * @throws IllegalArgumentException if no matching adapter may be found and allowNonMatch is false
      */
 
     public A getByInstance(Object value)
@@ -81,18 +106,32 @@
      * Searches for an adapter corresponding to the given input type.
      *
      * @param type the type to search
-     * @return the corresponding adapter
-     * @throws IllegalArgumentException if no matching adapter may be found
+     * @return the adapter for the type or null if not found (and allowNonMatch is true)
+     * @throws IllegalArgumentException if no matching adapter may be found   and allowNonMatch is false
      */
     public A get(Class type)
     {
+
         A result = _cache.get(type);
 
-        if (result == null)
+        if (result != null) return result;
+
+        if (_unmatched.containsKey(type)) return null;
+
+
+        result = findMatch(type);
+
+        // This may be null in the case that there is no match and we're allowing that to not
+        // be an error.  That's why we check via containsKey.
+
+        if (result != null)
         {
-            result = findMatch(type);
             _cache.put(type, result);
         }
+        else
+        {
+            _unmatched.put(type, true);
+        }
 
         return result;
     }
@@ -112,6 +151,8 @@
         List<String> names = newList();
         for (Class t : _registrations.keySet())
             names.add(t.getName());
+
+        if (_allowNonMatch) return null;
 
         throw new IllegalArgumentException(UtilMessages
                 .noStrategyAdapter(type, _adapterType, names));

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java?rev=617866&r1=617865&r2=617866&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/util/StrategyRegistryTest.java Sat Feb  2 11:26:57 2008
@@ -56,7 +56,7 @@
     }
 
     @Test
-    public void adapter_found()
+    public void adapter_not_found_when_non_error()
     {
         Runnable r1 = mockRunnable();
         Runnable r2 = mockRunnable();