Author: hlship
Date: Tue Mar  6 14:30:09 2007
New Revision: 515327

URL: http://svn.apache.org/viewvc?view=rev&rev=515327
Log:
TAPESTRY-1319: tapestry.InfrastructureOverrides is not yet implemented

Modified:
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InfrastructureImpl.java
    
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt
    
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InfrastructureImplTest.java

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InfrastructureImpl.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InfrastructureImpl.java?view=diff&rev=515327&r1=515326&r2=515327
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InfrastructureImpl.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InfrastructureImpl.java
 Tue Mar  6 14:30:09 2007
@@ -14,12 +14,14 @@
 
 package org.apache.tapestry.internal.services;
 
+import static 
org.apache.tapestry.ioc.internal.util.CollectionFactory.newCaseInsensitiveMap;
 import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
 
 import java.util.Map;
 
 import org.apache.tapestry.ioc.ObjectProvider;
 import org.apache.tapestry.ioc.ServiceLocator;
+import org.apache.tapestry.ioc.internal.util.OneShotLock;
 import org.apache.tapestry.services.Infrastructure;
 import org.apache.tapestry.services.InfrastructureManager;
 
@@ -28,17 +30,23 @@
  */
 public class InfrastructureImpl implements Infrastructure, ObjectProvider
 {
-    private final InfrastructureManager _manager;
+    // Derived from the managers when first needed
 
-    // Derived from the manager when first needed
+    private final Map<String, Object> _properties = newCaseInsensitiveMap();
 
-    private Map<String, Object> _properties;
+    private InfrastructureManager _masterManager;
+
+    private InfrastructureManager _overridesManager;
 
     private String _mode;
 
-    public InfrastructureImpl(InfrastructureManager manager)
+    private final OneShotLock _lock = new OneShotLock();
+
+    public InfrastructureImpl(InfrastructureManager masterManager,
+            InfrastructureManager overridesManager)
     {
-        _manager = manager;
+        _masterManager = masterManager;
+        _overridesManager = overridesManager;
     }
 
     public ObjectProvider getObjectProvider()
@@ -53,12 +61,20 @@
     {
         _mode = notNull(mode, "mode");
 
-        _properties = _manager.getContributionsForMode(_mode);
+        // This method may only be invoked once.
+
+        _lock.lock();
+
+        _properties.putAll(_masterManager.getContributionsForMode(_mode));
+        _properties.putAll(_overridesManager.getContributionsForMode(_mode));
+
+        _masterManager = null;
+        _overridesManager = null;
     }
 
     public <T> T provide(String expression, Class<T> objectType, 
ServiceLocator locator)
     {
-        if (_properties == null)
+        if (_properties.isEmpty())
             throw new 
RuntimeException(ServicesMessages.infrastructureModeNotSet());
 
         Object object = _properties.get(expression);

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=515327&r1=515326&r2=515327
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
 Tue Mar  6 14:30:09 2007
@@ -418,11 +418,25 @@
     }
 
     public static Infrastructure buildInfrastructure(Log log,
-            Collection<InfrastructureContribution> configuration)
+
+    @InjectService("InfrastructureOverrides")
+    InfrastructureManager overridesManager,
+
+    Collection<InfrastructureContribution> configuration)
     {
         InfrastructureManager manager = new InfrastructureManagerImpl(log, 
configuration);
 
-        return new InfrastructureImpl(manager);
+        return new InfrastructureImpl(manager, overridesManager);
+    }
+
+    /**
+     * A companion service to [EMAIL PROTECTED] #buildInfrastructure(Log, 
Collection)} whose configuration
+     * contribution define spot overrides to specific services.
+     */
+    public static InfrastructureManager buildInfrastructureOverrides(Log log,
+            Collection<InfrastructureContribution> configuration)
+    {
+        return new InfrastructureManagerImpl(log, configuration);
     }
 
     public static MarkupWriterFactory buildMarkupWriterFactory(

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt?view=diff&rev=515327&r1=515326&r2=515327
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt 
(original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/guide/infrastructure.apt 
Tue Mar  6 14:30:09 2007
@@ -9,13 +9,16 @@
   into  your components or services, any of the services, using a shorter 
name, i.e.,
   "infrastructure:Request" vs. "service:tapestry.Request".
 
-  This functionaliy serves a separate, and ultimately more important, purpose.
+  As elsewhere in Tapestry, the name provided (i.e., "Request") is matched 
case insensitively
+  to the available names, contributed into the service.
+
+  This functionality serves a separate, and ultimately more important, purpose.
   
   In the vast majority of applications developed using Tapestry, the built in 
set of 
   services does exactly what you need them to do. However, there are always 
outliers,
   very special cases that aren't addressed. The infrastructure mechanism 
includes the ability
   to <<override>> these services.  If infrastructure:AssetSource doesn't do 
quite what you need,
-  you will be able to provide your own service and make that 
infrastructure:AssetSource. It will be
+  you will be able to provide your own service and make that known as 
infrastructure:AssetSource. It will be
   your implementation that is injected into both your own services and 
components and the
   services built into Tapestry (both public and internal).
 
@@ -118,8 +121,37 @@
     
{{{../apidocs/org/apache/tapestry/services/ValidationMessagesSource.html}ValidationMessagesSource}}
 (tapestry.ValidationMessagesSource)
     
     Provides access to localized messages related to input validation.
+    
+  []
+  
+  <Several additional services have been contributed as well, the above 
documentation is somewhat out of date.>
 
 Contributing to Infrastructure
 
-  To Be Documented
+  To contribute a new service to Infrastructure, you must first determine its 
logical name.
+  
+  You can then contribute into the tapestry.Infrastructure service's 
configuration:
+  
++---+
+  @Contribute("tapestry.Infrastructure")
+  public static void contributeMyService(@InjectService("MyService") MyService 
myService,
+     Configuration<InfrastructureContribution> configuration)
+  {
+     configuration.add(new InfrastructureContribution("MyName", myService));
+  }
++---+
+
+  The above example follows a typical pattern; the service to be vended is 
injected into the contributor method.
+  A contribution is made providing the name. 
+  
+Contributing to Infrastructure Overrides
+
+  To override a service, you need to know its logical name.
+  
+  You can then make a contribution to the tapestry.InfrastructureOverrides 
service configuration, as described in the previous section.
+  
+  The object contributed as an override will mask the default contribution.
+ 
+  
+  
   

Modified: 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InfrastructureImplTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InfrastructureImplTest.java?view=diff&rev=515327&r1=515326&r2=515327
==============================================================================
--- 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InfrastructureImplTest.java
 (original)
+++ 
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InfrastructureImplTest.java
 Tue Mar  6 14:30:09 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.
@@ -16,6 +16,7 @@
 
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
 
+import java.util.Collections;
 import java.util.Map;
 
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
@@ -25,20 +26,20 @@
 import org.apache.tapestry.services.InfrastructureManager;
 import org.testng.annotations.Test;
 
-/**
- * 
- */
 public class InfrastructureImplTest extends InternalBaseTestCase
 {
+    private Map<String, Object> _emptyMap = Collections.emptyMap();
+
     @Test
     public void mode_not_set_when_resolution_requested()
     {
         InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
         ServiceLocator locator = newServiceLocator();
 
         replay();
 
-        Infrastructure infra = new InfrastructureImpl(manager);
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
 
         // Do not assume that infra and provider are the same;
         // that's an implementation choice.
@@ -66,59 +67,107 @@
     @Test
     public void resolve_object_within_mode()
     {
+        String infrastructureProperty = "myrunnable";
+        String mode = "papyrus";
+
         InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
+
         ServiceLocator locator = newServiceLocator();
         Runnable r = newRunnable();
 
         Map<String, Object> configuration = newMap();
-        configuration.put("myrunnable", r);
+        configuration.put(infrastructureProperty, r);
 
-        train_getContributionsForMode(manager, "papyrus", configuration);
+        train_getContributionsForMode(manager, mode, configuration);
+        train_getContributionsForMode(overridesManager, mode, _emptyMap);
 
         replay();
 
-        Infrastructure infra = new InfrastructureImpl(manager);
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
 
-        infra.setMode("papyrus");
+        infra.setMode(mode);
 
         // Do not assume that infra and provider are the same;
         // that's an implementation choice.
 
         ObjectProvider provider = infra.getObjectProvider();
 
-        Runnable actual = provider.provide("myrunnable", Runnable.class, 
locator);
+        Runnable actual = provider.provide(infrastructureProperty, 
Runnable.class, locator);
 
         assertSame(actual, r);
 
         verify();
     }
 
+    @Test
+    public void overrides_manager_has_precendence()
+    {
+        String infrastructureProperty = "myrunnable";
+        String mode = "papyrus";
+
+        InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
+
+        ServiceLocator locator = newServiceLocator();
+        Runnable masterRunnable = newRunnable();
+        Runnable overrideRunnable = newRunnable();
+
+        Map<String, Object> masterConfiguration = newMap();
+        masterConfiguration.put(infrastructureProperty, masterRunnable);
+
+        Map<String, Object> overrideConfiguration = newMap();
+        overrideConfiguration.put(infrastructureProperty, overrideRunnable);
+
+        train_getContributionsForMode(manager, mode, masterConfiguration);
+        train_getContributionsForMode(overridesManager, mode, 
overrideConfiguration);
+
+        replay();
+
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
+
+        infra.setMode(mode);
+
+        ObjectProvider provider = infra.getObjectProvider();
+
+        Runnable actual = provider.provide(infrastructureProperty, 
Runnable.class, locator);
+
+        assertSame(actual, overrideRunnable);
+
+        verify();
+    }
+
     /** Check that the manager is only consulted once. */
     @Test
     public void configuration_is_cached()
     {
+        String property = "myrunnable";
+        String mode = "clay";
+
         InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
         ServiceLocator locator = newServiceLocator();
         Runnable r = newRunnable();
 
         Map<String, Object> configuration = newMap();
-        configuration.put("myrunnable", r);
+        configuration.put(property, r);
 
-        train_getContributionsForMode(manager, "clay", configuration);
+        train_getContributionsForMode(manager, mode, configuration);
+        train_getContributionsForMode(overridesManager, mode, _emptyMap);
 
         replay();
 
-        Infrastructure infra = new InfrastructureImpl(manager);
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
 
-        infra.setMode("clay");
+        infra.setMode(mode);
 
         // Do not assume that infra and provider are the same;
         // that's an implementation choice.
 
         ObjectProvider provider = infra.getObjectProvider();
 
-        Runnable actual1 = provider.provide("myrunnable", Runnable.class, 
locator);
-        Runnable actual2 = provider.provide("myrunnable", Runnable.class, 
locator);
+        Runnable actual1 = provider.provide(property, Runnable.class, locator);
+        Runnable actual2 = provider.provide(property, Runnable.class, locator);
 
         assertSame(actual1, r);
         assertSame(actual2, r);
@@ -129,7 +178,10 @@
     @Test
     public void expression_not_found_in_configuration()
     {
+        String mode = "clay";
+
         InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
         ServiceLocator locator = newServiceLocator();
 
         Map<String, Object> configuration = newMap();
@@ -138,13 +190,14 @@
         configuration.put("barney", this);
         configuration.put("wilma", this);
 
-        train_getContributionsForMode(manager, "clay", configuration);
+        train_getContributionsForMode(manager, mode, configuration);
+        train_getContributionsForMode(overridesManager, mode, _emptyMap);
 
         replay();
 
-        Infrastructure infra = new InfrastructureImpl(manager);
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
 
-        infra.setMode("clay");
+        infra.setMode(mode);
 
         ObjectProvider provider = infra.getObjectProvider();
 
@@ -167,20 +220,25 @@
     @Test
     public void requested_type_not_compatible_with_object()
     {
+        String property = "myrunnable";
+        String mode = "papyrus";
+
         InfrastructureManager manager = newInfrastructureManager();
+        InfrastructureManager overridesManager = newInfrastructureManager();
         ServiceLocator locator = newServiceLocator();
         Runnable r = newRunnable();
 
         Map<String, Object> configuration = newMap();
-        configuration.put("myrunnable", r);
+        configuration.put(property, r);
 
-        train_getContributionsForMode(manager, "papyrus", configuration);
+        train_getContributionsForMode(manager, mode, configuration);
+        train_getContributionsForMode(overridesManager, mode, _emptyMap);
 
         replay();
 
-        Infrastructure infra = new InfrastructureImpl(manager);
+        Infrastructure infra = new InfrastructureImpl(manager, 
overridesManager);
 
-        infra.setMode("papyrus");
+        infra.setMode(mode);
 
         // Do not assume that infra and provider are the same;
         // that's an implementation choice.
@@ -189,13 +247,13 @@
 
         try
         {
-            provider.provide("myrunnable", UpdateListenerHub.class, locator);
+            provider.provide(property, UpdateListenerHub.class, locator);
             unreachable();
         }
         catch (RuntimeException ex)
         {
             assertEquals(ex.getMessage(), 
ServicesMessages.infrastructurePropertyWrongType(
-                    "myrunnable",
+                    property,
                     r,
                     UpdateListenerHub.class));
         }


Reply via email to