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));
}